J'ai un problème sur la façon de remplir des données dans ma troisième liste déroulante.
J'ai trois listes déroulantes, premièrement, lorsque je clique sur ma première liste déroulante, la deuxième liste déroulante remplit la liste en fonction de la valeur de ma première liste déroulante et en dessous de mon code, cela fonctionne bien.
Le problème est que je veux remplir la liste dans ma troisième liste déroulante lorsque je clique sur la deuxième liste déroulante, mais elle n'affiche rien.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <select onChange="changemeal(this.value);"> <option value="" disabled selected>Select Province</option> <option value="A">Usa</option> <option value="B">Japan</option> <option value="C">China</option> </select> <select name="category" id="category" onChange="changecat(this.value);" disabled> <option disabled selected>Select</option> <option value="A">Usa</option> <option value="B">Japan</option> <option value="C">China</option> </select> <select name="provinces" id="provinces" disabled> <option value="" disabled selected>Select</option> </select>
var mealsByCategory =
{ A: [ 'San Francisco', 'Manila', 'Kirishima' ]
, B: [ 'b', 'bb', 'bbb', 'bbbb' ]
, C: [ 'c', 'ccc', 'cccc', 'ccccc', 'cccccc' ]
}
var Mprovinces =
{ A: [ 'San Francisco', 'Manila', 'Kirishima' ]
, B: [ 'b', 'bb', 'bbb', 'bbbb' ]
, C: [ 'c', 'ccc', 'cccc', 'ccccc', 'cccccc' ]
}
function changemeal(value) {
$('#category').prop('disabled', false);
if (value.length == 0) document.getElementById("category").innerHTML = "<option></option>";
else {
var catOptions = "";
for (categoryId in mealsByCategory[value]) {
catOptions += "<option>" + mealsByCategory[value][categoryId] + "</option>";
}
document.getElementById("category").innerHTML = catOptions;
}
}
function changecat(value) {
$('#provinces').prop('disabled', false);
if (value.length == 0) document.getElementById("provinces").innerHTML = "<option></option>";
else {
var catOptions1 = "";
for (categoryId in Mprovinces[value]) {
catOptions1 += "<option>" + Mprovinces[value][categoryId] + "</option>";
}
document.getElementById("provinces").innerHTML = catOptions1;
}
}3 Réponses :
OK - c'est un exemple très approximatif que je viens de rassembler pour vous donner une idée de la structure des données et du javascript:
<select id="parent" onchange="getChildren()";></select><select id="child"></select>
let data = [{"id":1, "displaytext":"England", "parentid": 0},
{"id":2, "displaytext":"Scotland", "parentid": 0},
{"id":3, "displaytext":"Wales", "parentid": 0},
{"id":4, "displaytext":"Northern Ireland", "parentid": 0},
{"id":5, "displaytext":"London", "parentid": 1},
{"id":6, "displaytext":"Birmingham", "parentid": 1},
{"id":7, "displaytext":"Manchester", "parentid": 1},
{"id":8, "displaytext":"Edinburgh", "parentid": 2},
{"id":9, "displaytext":"Glasgow", "parentid": 2},
{"id":10, "displaytext":"Dundee", "parentid": 2},
{"id":11, "displaytext":"Cardiff", "parentid": 3},
{"id":12, "displaytext":"Swansea", "parentid": 3},
{"id":13, "displaytext":"Belfast", "parentid": 4},
{"id":14, "displaytext":"Lisburn", "parentid": 4}]
function loadParents() {
let oList = document.getElementById("parent");
let parents = data.filter(item => item.parentid == 0);
let topItem = document.createElement("option");
topItem.value = 0;
topItem.text = "--Select--";
oList.appendChild(topItem);
parents.forEach(function(parent) {
let newItem = document.createElement("option");
newItem.value = parent.id;
newItem.text = parent.displaytext;
oList.appendChild(newItem);
})
}
function getChildren() {
let oList = document.getElementById("parent");
let cList = document.getElementById("child");
cList.innerHTML = "";
let oFilter = oList.value;
if (oList.value != 0) {
let children = data.filter(item => item.parentid == oFilter);
let topItem = document.createElement("option");
topItem.value = 0;
topItem.text = "--Select--";
cList.appendChild(topItem);
children.forEach(function(child) {
let newItem = document.createElement("option");
newItem.value = child.id;
newItem.text = child.displaytext;
cList.appendChild(newItem);
})
}
}
window.onload = loadParents;Ceci est juste une simple liste de pays du Royaume-Uni et de certaines de leurs villes. Sélectionnez un pays dans la première liste et la deuxième liste est remplacée par les «enfants» de ce «parent».
mon chemin...
<form action="" id="geographia-form"> <select name="region"></select> <select name="land"></select> <select name="city"></select> </form>
const f_Geo = document.getElementById('geographia-form')
, selOrder = [ 'region', 'land', 'city' ] // hierarchical order of selects
, treeData =
[ { id: 1, name: 'USA', parentID: 0 }
, { id: 2, name: 'Japan', parentID: 0 }
, { id: 3, name: 'Europe', parentID: 0 }
, { id: 4, name: 'California', parentID: 1 }
, { id: 5, name: 'Oklahoma', parentID: 1 }
, { id: 6, name: 'Arizona', parentID: 1 }
, { id: 7, name: 'Kantô', parentID: 2 }
, { id: 8, name: 'Kansai', parentID: 2 }
, { id: 9, name: 'Chügoku', parentID: 2 }
, { id: 10, name: 'France', parentID: 3 }
, { id: 11, name: 'Deutschland', parentID: 3 }
, { id: 12, name: 'Espana', parentID: 3 }
, { id: 13, name: 'Sacramento', parentID: 4 }
, { id: 14, name: 'Los Angeles', parentID: 4 }
, { id: 15, name: 'San Diego', parentID: 4 }
, { id: 16, name: 'Tulsa', parentID: 5 }
, { id: 17, name: 'Oklahoma City', parentID: 5 }
, { id: 18, name: 'Lawton', parentID: 5 }
, { id: 19, name: 'Phoenix', parentID: 6 }
, { id: 20, name: 'Flagstaff', parentID: 6 }
, { id: 21, name: 'Tucson', parentID: 6 }
, { id: 21, name: 'Tokyo', parentID: 7 }
, { id: 22, name: 'Chiba', parentID: 7 }
, { id: 23, name: 'Tochigi', parentID: 7 }
, { id: 24, name: 'Kyoto', parentID: 8 }
, { id: 25, name: 'Osaka', parentID: 8 }
, { id: 26, name: 'Nara', parentID: 8 }
, { id: 27, name: 'Tottori', parentID: 9 }
, { id: 28, name: 'Hirochima', parentID: 9 }
, { id: 29, name: 'Okayama', parentID: 9 }
, { id: 30, name: 'Quimper', parentID: 10 }
, { id: 31, name: 'Toulouse', parentID: 10 }
, { id: 32, name: 'Nancy', parentID: 10 }
, { id: 33, name: 'Dusseldorf', parentID: 11 }
, { id: 34, name: 'Leipzig', parentID: 11 }
, { id: 35, name: 'Munchen', parentID: 11 }
, { id: 36, name: 'Barcelona', parentID: 12 }
, { id: 37, name: 'Sevilla', parentID: 12 }
, { id: 38, name: 'Guernica', parentID: 12 }
]
;
f_Geo.onsubmit=e=>e.preventDefault() // disable submit
;
f_Geo.onchange=e=>
{
//if (!e.target.matches('select')) return
setSubSelects(e.target.name)
}
function setSelect(name,id)
{
f_Geo[name].innerHTML = '' // clear select
treeData.filter(el=>el.parentID===id)
.forEach(el=>{ f_Geo[name].add( new Option(el.name, el.id)) })
}
function setSubSelects(selectName)
{
let idx = selOrder.findIndex(x=>x===selectName) +1
if (idx < selOrder.length)
{
let sName = selOrder[idx]
setSelect ( sName, +f_Geo[selectName].value )
setSubSelects(sName)
}
}
setSelect('region',0)
setSubSelects('region')De manière totalement personnalisable:
<button onclick="getText();">Click</button> <select id="list1"> <option value="1">Text 1</option> <option value="2">Text 2</option> <option value="3">Text 3</option> </select>
function getText() {
let thisList = document.getElementById("list1");
console.log(thisList.value);
console.log(thisList[thisList.selectedIndex].text);
}Region: <select id="list1" onchange="updateList('list2', this);"></select>
Sub-region:<select id="list2" onchange="updateList('list3', this);"></select>>
Location:<select id="list3"></select> Tant que la structure des données est la même - c'est-à-dire {"id":n, "name":"xxx", "parentid":n} alors le seul changement est le texte à côté de chacune des listes - sinon, la fonction a juste besoin d'être mis à jour pour utiliser les noms de clé fournis. Et, comme tout ce que nous faisons est de populateList listes basées sur le même tableau, elles peuvent toutes utiliser la même fonction de base - populateList . Le chargement initial et la sélection dans une liste commencent différemment, mais finissent par faire la même chose - remplir une liste en fonction du tableau filtré.
select {width:150px;}let data = [{"id":1,"name":"USA","parentid":0},
{"id":2,"name":"Japan","parentid":0},
{"id":3,"name":"Europe","parentid":0},
{"id":4,"name":"California","parentid":1},
{"id":5,"name":"Oklahoma","parentid":1},
{"id":6,"name":"Arizona","parentid":1},
{"id":7,"name":"Kantô","parentid":2},
{"id":8,"name":"Kansai","parentid":2},
{"id":9,"name":"Chügoku","parentid":2},
{"id":10,"name":"France","parentid":3},
{"id":11,"name":"Deutschland","parentid":3},
{"id":12,"name":"Espana","parentid":3},
{"id":13,"name":"Sacramento","parentid":4},
{"id":14,"name":"Los Angeles","parentid":4},
{"id":15,"name":"San Diego","parentid":4},
{"id":16,"name":"Tulsa","parentid":5},
{"id":17,"name":"Oklahoma City","parentid":5},
{"id":18,"name":"Lawton","parentid":5},
{"id":19,"name":"Phoenix","parentid":6},
{"id":20,"name":"Flagstaff","parentid":6},
{"id":21,"name":"Tucson","parentid":6},
{"id":21,"name":"Tokyo","parentid":7},
{"id":22,"name":"Chiba","parentid":7},
{"id":23,"name":"Tochigi","parentid":7},
{"id":24,"name":"Kyoto","parentid":8},
{"id":25,"name":"Osaka","parentid":8},
{"id":26,"name":"Nara","parentid":8},
{"id":27,"name":"Tottori","parentid":9},
{"id":28,"name":"Hirochima","parentid":9},
{"id":29,"name":"Okayama","parentid":9},
{"id":30,"name":"Quimper","parentid":10},
{"id":31,"name":"Toulouse","parentid":10},
{"id":32,"name":"Nancy","parentid":10},
{"id":33,"name":"Dusseldorf","parentid":11},
{"id":34,"name":"Leipzig","parentid":11},
{"id":35,"name":"Munchen","parentid":11},
{"id":36,"name":"Barcelona","parentid":12},
{"id":37,"name":"Sevilla","parentid":12},
{"id":38,"name":"Guernica","parentid":12}]
function populateList(list, pid) {
let l = document.getElementById(list);
l.innerHTML = "";
let topItem = document.createElement("option");
topItem.value = 0;
topItem.text = "--Select--";
l.appendChild(topItem);
let items = data.filter(item => item.parentid == pid);
items.forEach(function(item){
let newItem = document.createElement("option");
newItem.value = item.id;
newItem.text = item.name;
l.appendChild(newItem);
})
}
function updateList(selList, thisList) {
if (thisList.value != 0) {
populateList(selList, Number(thisList.value));
} else {
let s = document.getElementById(selList);
s.value = 0;
triggerEvent(s, "onchange");
let sCopy = s.cloneNode(false);
let p = s.parentNode;
p.replaceChild(sCopy, s);
}
}
function triggerEvent(e, trigger)
{
if ((e[trigger] || false) && typeof e[trigger] == 'function')
{
e[trigger](e);
}
}
function loadList1() {
populateList("list1", 0);
}
window.onload = loadList1;Salut monsieur, je sais que c'est un peu tard mais avez-vous une idée? comment puis-je obtenir la valeur textuelle de cette option de sélection, actuellement, lorsque j'ai utilisé votre code au-dessus de la valeur que j'obtiens est l'ID au lieu de la valeur, j'utilise python django, en espérant
Je n'utilise ni python ni django, donc je ne sais pas comment obtenir des valeurs / du texte à partir d'un élément HTML. J'ai mis à jour le code ci-dessus pour montrer comment cela se fait en javascript, ce qui peut fonctionner pour vous, ou vous donner un point de départ pour votre propre code.
c'est parce que votre modèle de données est mauvais. tu dois en faire un arbre
@MisterJojo Il faut que ce soit un arbre. J'ai fait différentes versions de ceci en utilisant rien de plus qu'un seul tableau. Chaque élément du tableau est structuré comme quelque chose comme
{"id":n, "displaytext":x, "parentid":n2}Tous les éléments de niveau supérieur ont"parentid":0et tous les éléments enfants ont la valeuriddu parent comme valeurparentid. Ensuite, un simple filtrage obtiendra facilement les éléments de niveau supérieur - ils auront tous 0 comme parentid, et les éléments enfants peuvent être trouvés en filtrant sur parentid = id du parent.@ATD pouvez-vous fournir une solution? S'il vous plaît. Il faut presque 4 heures pour trouver une solution jusqu'à maintenant
J'ai ajouté une réponse qui vous montre le genre de chose que je fais. Ce n'est pas une version de travail complète - mais cela devrait suffire à vous donner une idée de ce que vous pouvez faire et comment
@ATD oui, la structure de votre table est correcte. Il manque juste un moyen d'indiquer l'ordre hiérarchique des sélections. J'ai ajouté ma réponse pour le montrer.
Et pourquoi est-ce important à quoi ça ressemble? Si vous le souhaitez, vous pouvez avoir des tableaux séparés pour le parent, l'enfant et le petit-enfant (pour utiliser vos 3 niveaux comme exemple) et simplement filtrer la liste appropriée. Sinon, vous créez des objets personnalisés pour contenir des tableaux dans des tableaux juste pour le faire ressembler à un arbre. Que gagne-t-on en faisant cela?
@ATD non, je parle de mon tableau
selOrder(pour indiquer l'ordre hiérarchique des sélections) qui peut être étendu à "l'infini" (n'existe pas dans votre code), sans rien changer d'autre dans mon code.