Javascript Aiuto calcolo preventivo

NoName00

Utente Electrum
27 Agosto 2010
162
24
4
113
Ultima modifica da un moderatore:
Buongiorno,
Sto creando un plugin per wordpress che deve calcolare un preventivo, non riesco a prendere il secondo valore dell'elemento dell'array, che corrisponde al prezzo del servizio per poterlo sommare agli altri servizi e moltiplicarlo per il numero di persone sulle quali bisogna eseguire il servizio.
JavaScript:
<!-- CODICE JS -->

var servizi = [
    ["Stalking", 50],
    ["Infedeltà coniugale", 100],
    ["Affidamento minori", 150],
    ["Sicurezza aziendale", 50],
    ["Sicurezza infromatica", 50],
    ["Infedeltà soci / Dipendenti", 150],
];

//vado a stampare su html le card in base ai servizi scelti
var elementoContenitore = document.querySelector(".servizi");

for (var i = 0; i < servizi.length; i++) {
    elementoContenitore.insertAdjacentHTML("beforeend",
        `<option value="${servizi[i][1]}">
            ${servizi[i][0]}
        </option>`);
}

//controllo quando il pulsante viene schiacciato avvio il calcolo del prezzo in base ai servizi selezionati

function calcolaPrezzo() {

    //vado a prendere tutti gli elementio che sono input con type checkbox
    var selectDaVerificare = document.getElementById("servizi");
    var indiceSelezionato = selectDaVerificare.selectedIndex;
    var valoreSelezionato = selectDaVerificare.options[indiceSelezionato];
    var valoreDentroLopzione = valoreSelezionato.value;
    console.log(valoreDentroLopzione);
    //inizzializzo i prezzi dei servizi
    var prezzoBase = 0;
    var sommaServizi = 0;

    //vado a vedere quali elementi sono selezionati cosa da aggiungerli al preventivo
    for (var i = 0; i < servizi.length; i++) {
        var elemento = selectDaVerificare[i];
        var elemento2 = elemento[1];
     
        if (elemento2) {
            sommaServizi += elemento2;
        }
    }

    //Prendo il valore del form
    var persone = document.getElementById('persone').value;
 
    var totale = prezzoBase + elemento2;
    var total2 = totale * persone
    console.log(totale);
    document.getElementById("prezzo_finale").innerHTML = total2.toFixed(2) + " €";

}
 

Dany©

Utente Gold
8 Ottobre 2010
1,050
13
265
344
Ciao!
Onestamente non ho capito la domanda, ma rifacendomi al "problema" che segnali dipende dal fatto che stai selezionando l'indice dell'array esterno e non quello relativo agli array interni. L'approccio che stai seguendo è, a parer mio sbagliato, utilizzerei piuttosto un array di oggetti.

Se vuoi tenere la tua logica iniziale, per traversare il tuo array dovresti fare così:

JavaScript:
for(let servizio of servizi) {
    // ogni iterazione corrisponde ad uno degli array interni
    // a questo punto puoi accedere ai due elementi di ogni array interno
    elementoContenitore.insertAdjacentHTML("beforeend", `<option value="${servizio[1]}">${servizio[0]}</option>`);
}

Io utilizzerei piuttosto un approccio del genere:

JavaScript:
const services = [
  {
    name: "Stalking",
    price: 50
  },
  {
      name: "Infedeltà coniugale",
    price: 100
  },
  {
      name: "Affidamento minori",
    price: 150
  },
  {
      name: "Sicurezza aziendale",
    price: 50
  },
  {
      name: "Sicurezza informatica",
    price: 50
  },
  {
      name: "Infedeltà soci / dipendenti",
    price: 150
  }
]

for(let service of services) {
    // ogni iterazione corrisponde ad uno degli oggetti servizio
    let option = document.createElement("option");
    option.text = service.name;
    option.value = service.price;
    select.insertAdjacentHTML("beforeend", option);
}

Comunque il contesto del problema non mi è chiaro così come il problema, tu hai una select a selezione multipla dalla quale puoi selezionare da una a tutte le options e devi calcolare l'ammontare totale dei vari servizi selezionati?
 
  • Mi piace
Reazioni: MRPants

NoName00

Utente Electrum
27 Agosto 2010
162
24
4
113
Ultima modifica:
Ciao!
Onestamente non ho capito la domanda, ma rifacendomi al "problema" che segnali dipende dal fatto che stai selezionando l'indice dell'array esterno e non quello relativo agli array interni. L'approccio che stai seguendo è, a parer mio sbagliato, utilizzerei piuttosto un array di oggetti.

Se vuoi tenere la tua logica iniziale, per traversare il tuo array dovresti fare così:

JavaScript:
for(let servizio of servizi) {
    // ogni iterazione corrisponde ad uno degli array interni
    // a questo punto puoi accedere ai due elementi di ogni array interno
    elementoContenitore.insertAdjacentHTML("beforeend", `<option value="${servizio[1]}">${servizio[0]}</option>`);
}

Io utilizzerei piuttosto un approccio del genere:

JavaScript:
const services = [
  {
    name: "Stalking",
    price: 50
  },
  {
      name: "Infedeltà coniugale",
    price: 100
  },
  {
      name: "Affidamento minori",
    price: 150
  },
  {
      name: "Sicurezza aziendale",
    price: 50
  },
  {
      name: "Sicurezza informatica",
    price: 50
  },
  {
      name: "Infedeltà soci / dipendenti",
    price: 150
  }
]

for(let service of services) {
    // ogni iterazione corrisponde ad uno degli oggetti servizio
    let option = document.createElement("option");
    option.text = service.name;
    option.value = service.price;
    select.insertAdjacentHTML("beforeend", option);
}

Comunque il contesto del problema non mi è chiaro così come il problema, tu hai una select a selezione multipla dalla quale puoi selezionare da una a tutte le options e devi calcolare l'ammontare totale dei vari servizi selezionati?
Ciao, prima avevo delle checkbox per i servizi e funzionava tutto perfettamente, mi è stato richiesto di togliere le checkbox e mettere tutto dentro una multiple select. Il problema sta proprio qua, non riesco a prendere il secondo valore dell'elemento ovvero il prezzo, sia in singolo che multiplo perché quando premo calcola mi esce fuori NaN come risultato. Premetto che sono nuovo al mondo della programmazione quindi ci sta che abbia seguito dei ragionamenti un po accrocchiati. il tuo approccio mi sembra nettamente migliore. Faccio un tentativo e ti dico se funziona. Comunque si, devo calcolare l'ammontare totale dei servizi selezionati e moltiplicarli per il numero di persone da seguire.
 

Dany©

Utente Gold
8 Ottobre 2010
1,050
13
265
344
Figurati! C'è sempre uno starting point e una curva di apprendimento!

Fai pure sapere se hai altri problemi, eventualmente posso condividerti un jfiddle con la soluzione anche se, visto che ti stai approcciando a questo mondo, è meglio se ci sbatti un po' la testa :p

Buona fortuna!
 

NoName00

Utente Electrum
27 Agosto 2010
162
24
4
113
Figurati! C'è sempre uno starting point e una curva di apprendimento!

Fai pure sapere se hai altri problemi, eventualmente posso condividerti un jfiddle con la soluzione anche se, visto che ti stai approcciando a questo mondo, è meglio se ci sbatti un po' la testa :p

Buona fortuna!
Dopo 3 ore e mezzo di tentativi sono arrivato a pushare gli elementi selezionati in un nuovo array ma mi pusha solo il nome e non tutto l'oggetto.
Considerata la tua struttura dati:

JavaScript:
var elementoContenitore = document.querySelector(".servizi");
 
  for(let servizio of servizi) {

      elementoContenitore.insertAdjacentHTML("beforeend",
        `<option value="${servizio.price}">
            ${servizio.name}
        </option>`);
  }
//controllo quando il pulsante viene schiacciato avvio il calcolo del prezzo in base ai servizi selezionati



function calcolaPrezzo() {
    var checked = document.getElementById("servizi");
    var value = checked.options[checked.selectedIndex].value;
    var text = checked.options[checked.selectedIndex].text
    console.log(value);

   //array vuoto che conterrrà i servizi selezionati
   let arrServizi = [];
   var selected = document.querySelectorAll('#servizi option:checked');
 
   for(let i=0; i<selected.length; i++){
     if(selected){
      arrServizi.push(selected);

     }
     console.log(arrServizi);
   }
    
    //inizzializzo i prezzi dei servizi
    var prezzoBase = 0;
    var sommaServizi = 0;

    //vado a vedere quali elementi sono selezionati cosa da aggiungerli al preventivo
    
        if (value) {
            sommaServizi += value;
        }

    //Prendo il valore del form
    var persone = document.getElementById('persone').value;
  
    var totale = prezzoBase + value;
    var total2 = totale * persone;
    console.log(total2);
    document.getElementById("prezzo_finale").innerHTML = total2 + " €";

}

Di conseguenza non riesco a fare il calcolo
 

Dany©

Utente Gold
8 Ottobre 2010
1,050
13
265
344
Ciao,
ti posto qui l'approccio che seguirei io, cercando di spiegarti perché in modo che tu possa anche capire e adattarlo alla tua situazione.

JavaScript:
// creo delle variabili in modo da poter referenziare gli elementi HTML;
let people = document.getElementById('peopleInput');
let selectedPeople = document.getElementById('people');
let select = document.getElementById('select');
let selectedServices = document.getElementById('services');
let totalPrice = document.getElementById('total');
let servicesTotal = 0;

// inizializzo gli elementi HTML relativi a numero di persone / prezzo totale;
selectedPeople.innerHTML = people.value;
totalPrice.innerHTML = servicesTotal;

// imposto l'array di servizi:
// ogni servizio corrisponde ad un oggetto composto da nome e prezzo del servizio.
const services = [
    {
        name: "Stalking",
        price: 50
    },
    {
        name: "Infedeltà coniugale",
        price: 100
    },
    {
        name: "Affidamento minori",
        price: 150
    },
    {
        name: "Sicurezza aziendale",
        price: 50
    },
    {
        name: "Sicurezza informatica",
        price: 50
    },
    {
        name: "Infedeltà soci / dipendenti",
        price: 150
    }
]

// traverso l'array di servizi per generare le opzioni della select
for(let service of services) {
    let option = document.createElement("option");
    option.text = service.name;
    option.value = service.price;
    select.appendChild(option);
}

// getSelectedValues: funzione che viene richiamata quando viene cambiata la selezione
// dei servizi;
// ritorna un array di oggetti servizio, con solo i servizi selezionati (stessa forma dell'array iniziale);
const getSelectedValues = () => {
    let selectedValues = [];
    let options = select.options;
    for(let option of options) {
        option.selected && selectedValues.push({ name: option.text, price: option.value });
    }
    return selectedValues;
}

// event listener per la selezione del numero di persone:
// quando cambia la selezione ricalcola anche il prezzo totale.
people.addEventListener('change', (e) => {
    selectedPeople.innerHTML = e.currentTarget.value;
    calculateTotal();
});

// event listener per la selezione dei servizi:
// quando cambia la selezione viene chiamata la funzione getSelectedValues()
// e viene anche ricalcolato il totale.
select.addEventListener('change', () => {
    selectedServices.innerHTML = "";
    let currentSelectedServices = getSelectedValues();
    // map dell'array di servizi selezionati per generare dinamicamente
    // la lista di servizi correntemente selezionati
    currentSelectedServices.map(service => {
        selectedServices.insertAdjacentHTML("beforeend", `<li>${service.name}</li>`);
    });
    // map dell'array di servizi selezionati per calcolare l'ammontare totale
    servicesTotal = currentSelectedServices.map(service => parseInt(service.price)).reduce((a, b) => a + b);
    calculateTotal();
});

// funzione che calcola il totale (prezzo servizi * numero di persone)
// e lo inserisce nell'elemento HTML apposito
const calculateTotal = () => {
    total.innerHTML = people.value * servicesTotal;
}

Qui il JSFiddle per vedere il funzionamento in una sandbox, non so esattamente il layout del tuo plugin ma puoi prendere spunto da questa logica per sistemare la tua :)
Spero di essere stato d'aiuto!
 

NoName00

Utente Electrum
27 Agosto 2010
162
24
4
113
Grazie mille!! ora mi studio bene la logica che hai usato perché ci sono alcune cose che non mi sono molto chiare però davvero molto utile. Grazie ancora.