Dynamic select doesn't work correctly - javascript

I got a problem with dynamic selects that not update their content when I change the selection.
I have 2 select inputs:
the first one is to select the category, for example cars, motorbike, etc
and the second should show the various models - for example city car, sport car, etc... if you select cars in the first
But, in my code the second select doesn't update the content when I change the first one and I have to reload the page to see the changes.
I think the problem is in onchange, but I'm not sure, someone know how to resolve?
/*metodo con cui creo la prima select "categoria"*/
this.creaSelectCategoria =
function () {
var categorie = {};
for (var i = 0; i<this.lista.length; i++) {
categorie[this.lista[i].categoria] = true;
}
var s = "";
s+='<option value="null" >Seleziona una Categoria </option>';
for (var i in categorie) {
s += '<option value="' + categorie[i] + '">' + categorie[i] + '</option>';
}
return s;
}
/*metodo con cui creo la seconda select "gruppo"*/
this.creaSelectGruppo =
function () {
var c= document.getElementById("selectCategoria").value;
var gruppi = {};
for (var i = 0; i<this.lista.length; i++) {
if(this.lista[i].categoria==c){
gruppi[this.lista[i].gruppo] = this.lista[i].gruppo;
}
}
var s = "";
s+='<option value="null" >Seleziona un gruppo</option>';
for (var i in gruppi) {
s += '<option value="' + gruppi[i] + '">' + gruppi[i] + '</option>';
}
return s;
}
function inizializza(){
var nodo = caricaXML("elenco.xml");
contenitore.inizializza(nodo);
var nodoSelectCategoria = document.getElementById("selectCategoria");
nodoSelectCategoria.onchange= contenitore.creaSelectCategoria();
var nodoSelectGruppo = document.getElementById("selectGruppo");
nodoSelectGruppo.innerHTML = contenitore.creaSelectGruppo();
var c1 = document.getElementById("cerca1");
var c2 = document.getElementById("cerca2");
c1.onclick = cercaNome;
c2.onclick = cercaGruppo;
}
function crea_gruppo(categoria) {
var gruppi = {};
for (var i = 0; i < lista.length; i++) {
if(lista[i].categoria==categoria)
{
gruppi[lista[i].gruppo] = true;
}
}
var s = '<option value="null" >Seleziona gruppo</option>';
for (var i in gruppi) {
s += '<option value="' + i + '">' + i + '</option>';
}
document.getElementById("selectGruppo").innerHTML= s;
}
<select id="selectCategoria" onchange='crea_gruppo(document.getElementById("selectCategoria").options[document.getElementById("selectCategoria").selectedIndex].value);'>
<option selected="selected" value="null">Seleziona tipo di ricerca</option>
<option value="Personaggio">Personaggi</option>
<option value="Arma">Armi</option>
<option value="Veicolo">Veicoli</option>
</select>
<select id="selectGruppo">
<option selected="selected" value="">-seleziona-</option>
</select>
update- now select works, but i ad duplicate entries in the second one
function creaSelectGruppo(categoria){
var v1=[];var v2=[];
for(var i=0;i<contenitore.lista.length;i++){
if(contenitore.lista[i].categoria==categoria){v1.push(contenitore.lista[i]);v2.push(contenitore.lista[i].categoria);}
}
v2.sort();
for(var i=0;i<v2.length;i++){
if(v2[i]==v2[i+1]) not in v2;
}
//fino a qui toglie tutti i duplicati ma lascia un buco nell'array
var s = '<option value="null" >Seleziona gruppo</option>';
for(var i=0;i<v2.length;i++){
try{
if(v2[i]!=undefined){
s += '<option value="' + v1[i].gruppo + '">' + v1[i].gruppo + '</option>';
}
}
catch(Errore){}
}
document.getElementById("selectGruppo").innerHTML=s;
}

Try adding new Option instead of text
function crea_gruppo(categoria) {
var gruppi = {};
for (var i = 0; i < lista.length; i++) {
if(lista[i].categoria==categoria)
{
gruppi[lista[i].gruppo] = true;
}
}
// clear existing entries
while (document.getElementById('selectGruppo').options.length > 0) {
document.getElementById('selectGruppo').removeChild(document.getElementById('selectGruppo').options[0]);
}
document.getElementById("selectGruppo").add(new Option('Seleziona gruppo', ''));
for (var i in gruppi) {
document.getElementById("selectGruppo").add(new Option(i, gruppi[i]));
}
}

Related

how to replace a single choice with a select my cart

For now I have a cart in javascript that works
But when I click the add to cart button
there is only one product added
I would like to replace this with a select so that the user can choose the number of articles to add
I tried to modify the code but when I select a quantity and I click on add to cart
It's always two that adds up
var MonPanier = (function() {
panier = [];
function Item(nom, prix, quantite) {
this.nom = nom;
this.prix = prix;
this.quantite = quantite;
}
function savepanier() {
console.log("saving",panier)
// sessionStorage.setItem('MonPanier', JSON.stringify(panier));
}
function loadpanier() {
// panier = JSON.parse(sessionStorage.getItem('MonPanier'));
panier = []
}
// if (sessionStorage.getItem("MonPanier") != null) {
// loadpanier();
// }
//variable objet
var obj = {};
obj.ajouter_produit_dans_panier = function(nom, prix, quantite) {
for (var item in panier) {
if (panier[item].nom === nom) {
//panier[item].quantite ++ ; ancien code
panier[item].quantite;
savepanier();
return;
}
}
var item = new Item(nom, prix, quantite);
panier.push(item);
savepanier();
}
obj.setquantiteForItem = function(nom, quantite) {
for (var i in panier) {
if (panier[i].nom === nom) {
panier[i].quantite = quantite;
break;
}
}
};
obj.enlever_produit_de_panier = function(nom) {
for (var item in panier) {
if (panier[item].nom === nom) {
panier[item].quantite--;
if (panier[item].quantite === 0) {
panier.splice(item, 1);
}
break;
}
}
savepanier();
}
obj.enlever_produit_de_panier_tous = function(nom) {
for (var item in panier) {
if (panier[item].nom === nom) {
panier.splice(item, 1);
break;
}
}
savepanier();
}
obj.clearpanier = function() {
panier = [];
savepanier();
}
obj.totalquantite = function() {
var totalquantite = 0;
for (var item in panier) {
totalquantite += panier[item].quantite;
}
return totalquantite;
}
obj.totalpanier = function() {
var totalpanier = 0;
for (var item in panier) {
totalpanier += panier[item].prix * panier[item].quantite;
}
return Number(totalpanier.toFixed(2));
}
obj.listpanier = function() {
var panierCopy = [];
for (i in panier) {
item = panier[i];
itemCopy = {};
for (p in item) {
itemCopy[p] = item[p];
}
itemCopy.total = Number(item.prix * item.quantite).toFixed(2);
panierCopy.push(itemCopy)
}
return panierCopy;
}
return obj;
})();
$('.ajouter-panier').click(function(event) {
event.preventDefault();
var nom_option = "";
var prix_option = 0;
var nom = $(this).data('nom');
var prix = Number($(this).data('prix')) + prix_option;
var quantite = $(this).data('select');
MonPanier.ajouter_produit_dans_panier(nom, prix, quantite);
//MonPanier.ajouter_produit_dans_panier(nom, prix,1); ancien code
afficherpanier();
});
$('.clear-panier').click(function() {
MonPanier.clearpanier();
afficherpanier();
});
$('.choix_livraison').click(function() {
const cases = document.querySelectorAll('input[name="choix_livraison"]');
for (const x of cases) {
if (x.checked) {
afficherpanier();
}}
});
function afficherpanier() {
var panierArray = MonPanier.listpanier();
var output = "";
var countart=0;
var countart2=0;
var count=0;
for(var i in panierArray) {
output += "<div class='row' style='border-style: ridge; border-width: 1px; border-color: #8ebf42; background-color: #d9d9d9;margin-bottom:5px;'>"
+ "<div class='col' style='text-align: center;border-left: solid;padding-left: 5px;padding-right: 5px;'><button class='btn btn-danger effacer-item' data-nom='" + panierArray[i].nom + "'>X</button></div>"
+ "<div class='col' style='text-align: center;border-left: solid;padding-left: 5px;padding-right: 5px;'>" + panierArray[i].nom + "</div>"
+ "<div class='col' style='text-align: center;border-left: solid;padding-left: 5px;padding-right: 5px;'>" + panierArray[i].prix.toFixed(0) + " euro</div>"
+ "<div class='form-inline col' style='text-align: center;border-left: solid;padding-left: 5px;padding-right: 5px;'><div class='input-group'><button class='btn btn-primary moins-item' data-nom='" + panierArray[i].nom + "'>-</button>"
+ "<input type='number' min='1' class='form-control item-quantite' style='width:55px !important' data-nom='" + panierArray[i].nom + "' value='" + panierArray[i].quantite + "'>"
+ "<button class='btn btn-primary plus-item' data-nom='" + panierArray[i].nom + "'>+</button></div></div>"
//+ ' = '
+ "<div class='col' style='text-align: center;border-left: solid;padding-left: 5px;padding-right: 5px;'>" + panierArray[i].total + " euros</div>"
+ "</div>";
count++;
countart += panierArray[i].quantite; // somme des unités d'articles
countart2 = countart
}
$('.show-panier').html(output);
if (Livraison == 3)
{
// % du prix total total correspondant au prix de la livraison
const cases = document.querySelectorAll('input[name="choix_livraison"]');
//const cases = document.querySelectorAll('input[name="ajout");
for (const x of cases) {
if (x.checked) {
let nom_choix_livraison = x.dataset.nom;
let prix_choix_livraison = x.value;
//console.log(panierArray[i] );
let prix_et_livraison = (( (MonPanier.totalpanier()*Poucentage_Livraison))) + Number(prix_choix_livraison) + Number(Forfait_Livraison ) ;
document.getElementById('amount').value = prix_et_livraison ;
$('.total-panier').html(prix_et_livraison.toFixed(2));
document.getElementById('livraison-detail').innerHTML ="<div class='col' style='text-align:right;background-color: #78b8df;visibility:hidden;'> (" + nom_choix_livraison + ")" + prix_choix_livraison + " euro(s)</div>";
document.getElementById('remise').innerHTML =MonPanier.totalpanier()*Poucentage_Livraison_opposse ;
document.getElementById('nouveau_prix').innerHTML =(MonPanier.totalpanier()- (MonPanier.totalpanier()*Poucentage_Livraison_opposse));
document.getElementById('frais-fixe').innerHTML =Forfait_Livraison ;
document.getElementById("prix_depart").innerHTML = MonPanier.totalpanier();
document.getElementById("countart_bas").innerHTML = countart;
document.getElementById("countart_haut").innerHTML = countart;
break;
}
}
}
$('.total-panier-modal').html(MonPanier.totalpanier());
$('.total-quantite').html(MonPanier.totalquantite());
if ((Qte_Minimum == 1) && (Number.isInteger(MonPanier.totalquantite() / Qte_Minimum_Valeur) == false) && (MonPanier.totalquantite() != 0))
{
document.getElementById('qte_minimum_report').innerHTML = txt_qte_minimum_bad;
}
else if ((Qte_Minimum == 1) && (Number.isInteger(MonPanier.totalquantite() / Qte_Minimum_Valeur) == true) && (MonPanier.totalquantite() != 0))
{
document.getElementById('qte_minimum_report').innerHTML = txt_qte_minimum_ok;
}
else if (Qte_Minimum == 1)
{
document.getElementById('qte_minimum_report').innerHTML = txt_qte_minimum_defaut;
}
else if (Qte_Minimum == 0)
{
document.getElementById('qte_minimum_report').innerHTML = "";
}
}
$('.show-panier').on("click", ".effacer-item", function(event) {
var nom = $(this).data('nom')
MonPanier.enlever_produit_de_panier_tous(nom);
afficherpanier();
})
$('.show-panier').on("click", ".moins-item", function(event) {
var nom = $(this).data('nom')
MonPanier.enlever_produit_de_panier(nom);
afficherpanier();
})
$('.show-panier').on("click", ".plus-item", function(event) {
var nom = $(this).data('nom')
MonPanier.ajouter_produit_dans_panier(nom);
afficherpanier();
})
$('.show-panier').on("change", ".item-quantite", function(event) {
var nom = $(this).data('nom');
var quantite = Number($(this).val());
MonPanier.setquantiteForItem(nom, quantite);
afficherpanier();
});
afficherpanier();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row mt-3">
<div class="col-md-4">
<p>Produit 02 (15.00 €)</p>
</div>
<div class="col-md-2">
<select class="form-control" id="02">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
<div class="col-md-6 text-end">
<a style="cursor:pointer;" data-nom="Produit 02" data-prix="15.00" data-select="02" class="btn btn-primary ajouter-panier">Add to Cart</a>
</div>
</div>

Fetch data from a nested array which has no key, just values to populate multiple selects

I have a JSON file, and I made a first variable that takes the countries out of it. These countries have cities inside them, this is the variable with that data:
var sucursalPais = [
"colombia": [
"bogotá",
"cali"
],
"peru" : [
"lima",
"cusco"
]
]
now, I am populating two select tags; one with country names, using this:
for (var k in sucursalPais) {
pais.innerHTML += '<option value ="' + k + '">' + k +'</option>';
}
So, when a pick a country, the next select is suposed to be populated by that country cities; but I don't know how to call the cities into the next select, because I don't have a city [] subarray with all of them on it, I have directly the cities into each country.
I have tried all, but I have not found a solution.
This is all of my code:
var pais = document.getElementById("pais");
var sucursalPais = [];
for (z = 0; z < sucursalData.length; z++) {
if(sucursalData[z].content.country && sucursalData[z].content.city) {
if(sucursalPais[sucursalData[z].content.country] != undefined) {
sucursalPais[sucursalData[z].content.country].push(sucursalData[z].content.city);
} else {
sucursalPais[sucursalData[z].content.country] = [sucursalData[z].content.city];
}
}
}
for (var k in sucursalPais){
pais.innerHTML += '<option value ="' + k + '">' + k +'</option>';
}
pais.addEventListener("change", function () {
for (m = 0; m < pais[this.value].length; m++) {
console.log(sucursalPais[m]);
ciudad.innerHTML += '<option value ="' + sucursalPais[m][value] + '">' + sucursalPais[m][value] +'</option>';
}
});
I've no idea what a pais is, but you'll get the point:
sucursalPais = {
"colombia": [
"bogotá",
"cali"
],
"peru" : [
"lima",
"cusco"
]
}
var pais = "";
var pius = "";
for (var k in sucursalPais) {
pais += '<option value ="' + k + '">' + k +'</option>';
for (var z=0; z < sucursalPais[k].length; z++) {
var city = sucursalPais[k][z];
pius += '<option value ="' + city + '">' + city +'</option>';
}
}
console.log(pais); // Countries
console.log(pius); // Cities
... you can create pius with innerHTML like in your example, I use strings to make the demo simple.

Pure Js onclick element doesn't work

I'm having trouble when i run this code under greasemonkey the last position working and run function.
var arry = [];
arry = GM_listValues();
for ( var i = 0; i < arry.length; i++) {
document.getElementById('moje_menu').innerHTML = document.getElementById('moje_menu').innerHTML + '<p id="' + arry[i] + '">' + arry[i] + '</p>';
document.getElementById(arry[i]).onclick = delete;
}
On 10 position the last working ... WHY ????
When you replace the innerHTML you remove all previous event handlers.
In plain JS you can detect the click in the div but you need to check the event:
function removeP(p) {
console.log(p.id);
}
var arry = ["a","b","c"];
window.onload=function() {
for ( var i = 0; i < arry.length; i++) {
document.getElementById('moje_menu').innerHTML += '<p id="' + arry[i] + '">' + arry[i] + '</p>';
}
document.getElementById('moje_menu').onclick=function(e) {
var event = e?e:window.event,tgt = event.target || event.srcElement;
if (tgt.tagName.toLowerCase()=="p") {
console.log(tgt.id);
}
}
}
<div id="moje_menu"></div>
Alternative is inline since you generate the P anyway
var arry = [];
arry = GM_listValues();
for ( var i = 0; i < arry.length; i++) {
document.getElementById('moje_menu').innerHTML += '<p id="' + arry[i] + '" onclick="delete(this)">' + arry[i] + '</p>';
}
You can the modify delete (poor name for a function since delete is a built-in method) to handle the passed paragraph
Example:
function removeP(p) {
console.log(p.id);
}
var arry = ["a","b","c"];
for ( var i = 0; i < arry.length; i++) {
document.getElementById('moje_menu').innerHTML += '<p id="' + arry[i] + '" onclick="removeP(this)">' + arry[i] + '</p>';
}
<div id="moje_menu"></div>
In jQuery you can easily delegate:
function removeP() {
console.log(this.id);
}
$(function() {
var arry = ["a","b","c"];
var $menu = $('#moje_menu');
for (var i=0; i<arry.length; i++) {
$menu.append($('<p/>',{"id":arry[i], "text":arry[i]}))
}
$menu.on("click","p",removeP);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="moje_menu"></div>
This is my solution i dont like them but works.
var arry = [];
arry = GM_listValues();
for ( var i = 0; i<arry.length; i++) {
// if(arry[i].search('player')==''){
document.getElementById('moje_menu').innerHTML += '<p class="lista_farm" id="'+arry[i]+'">'+arry[i]+'</p>';
//document.getElementById(arry[i]).onclick = usun_farme;
//}
}
var lista_farm = document.getElementsByClassName('lista_farm');
for(var i = 0; i<lista_farm.length; i++){
lista_farm[i].onclick = usun_farme;
}

Javascript: Javascript ignores the elements generated by itself

I have this javascript function that generates new selects with IDs:
function generateChild(root, categories){
++counter;
var appendid = "id='selectCategory_".concat(counter);
var coma = "'";
var mayorque = "'>";
var appendcoma = appendid.concat(coma);
var select ="<div class='selectContainer'".concat(appendcoma);
var close = "><select ";
var cerrar = select.concat(close);
var appendidselect = cerrar.concat(appendid);
var html = appendidselect.concat(mayorque);
for (var i = 0; i < categories.length; i++) {
html += "<option value='" + categories[i] + "'>" + categories[i] + "</option>";
}
html += '</select></div>';
// ---------------------------
// ---------------------------
// create an element from the html string
// ---------------------------
var tplt = root.createElement('template');
tplt.innerHTML = html;
var el = tplt.content.firstChild;
// ---------------------------
// ---------------------------
// attach the change handler
// ---------------------------
el.firstChild.addEventListener("change", handle_onChange);
// ---------------------------
return el;
}
}
And then this function to search for the last dropdown that didn't have a blank space on it, and save it in a hidden input for later use:
if(this.value == ' '){
for (var i = counter - 1 ; i >= 0 ; --i){
var string = i.toString();
var selectid = "selectCategory_".concat(string);
if(document.getElementById(selectid)){
document.getElementById("category").value = document.getElementById(selectid).value;
break;
}
}
}
else{
var lastselectedvalue = this.value;
document.getElementById("category").value = this.value;
}
This works well with the first dropdown, which is already in the code:
<input type ="hidden" name="category" id = "category" value="">
<div id="category0" class="selectContainer">
<select id="selectCategory_0">
<option>something</option>
<option>something else</option>
</select>
</div>
But never works with the other dropdowns, it always returns undefined.

Create a new dropdown with javascript

I am trying to create a dropdown after I choose an option in an original dropdown.
This is the HTML code:
<br>
<select id ="select-container" onchange="addSelect('select-container');">
<option>test1</option>
<option>test2</option>
<option>test3</option>
</select>
<br>
This is the javascript.
function categorygenerate() {
//for testing purposes
var categoryarray = new Array(),
i;
for (i = 0; i < 3; i++) {
categoryarray[i] = Math.random();
}
return categoryarray;
}
function addSelect(divname) {
var newDiv = document.createElement('div');
var html = '<select>',
dates = categorygenerate(),
i;
for (i = 0; i < dates.length; i++) {
html += "<option value='" + dates[i] + "'>" + dates[i] + "</option>";
}
html += '</select>';
newDiv.innerHTML = html;
document.getElementById(divname).appendChild(newDiv);
console.log($("#" + divname).html());
console.log(newDiv);
}
The debugger mode shows me no error.
It is because you are trying to append your code in the "original select": look at the id of your select.
You have to add a div tag with the id="select-container" and remove it from the "original select"
Here is a working snippet:
function categorygenerate() {
//for testing purposes
var categoryarray = new Array(),
i;
for (i = 0; i < 3; i++) {
categoryarray[i] = Math.random();
}
return categoryarray;
}
function addSelect(divname) {
var newDiv = document.createElement('div');
var html = '<select>',
dates = categorygenerate(),
i;
for (i = 0; i < dates.length; i++) {
html += "<option value='" + dates[i] + "'>" + dates[i] + "</option>";
}
html += '</select>';
newDiv.innerHTML = html;
document.getElementById(divname).appendChild(newDiv);
console.log($("#" + divname).html());
console.log(newDiv);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br>
<select onchange="addSelect('select-container');">
<option>test1</option>
<option>test2</option>
<option>test3</option>
</select>
<br>
<div id="select-container"></div>
Put your select in a div with the id select-container. Ofcourse, give your select an other ID. Then your code should work. It's because you try to append a new select to the original one in your HTML.
https://jsfiddle.net/b248a4k1/

Categories