问题
I'mn new to JS and trying to pass values from a JSON file to populate dropdown lists. I've got a JSON file that looks like this:
var mydates = {
"2018": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8","week9","week11"]
},
"2019": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8","week10","week11"]
},
"2020": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8"]
}
}
I want a first dropdown list to show the years listed, a second dropdown for the months and a last dropdown for the weeks.
I came up with the following to populate the dropdown for years with id "selectedyear", and it works just fine:
years = []
for(var prop in mydates){
console.log(prop)
years.push(prop)}
var myyear = document.getElementById('selectedyear');
for(var i = 0; i < years.length; i++) {
var opt = document.createElement('option');
opt.innerHTML = years[i];
myyear.appendChild(opt);
}
Now how can I iterate through the second level of the JSON so that the options for the dropdown with id "selectedmonth" only shows the months for the year selected, and then for the dropdown with id "selectedweek" to show the weeks corresponding to the selected year and month ??
Many thanks for your help!
回答1:
The following code both initiallizes and listens for event change of any selection excluding the week selection.
const mydates = {
"2018": {
"January": ["week1", "week2", "week3", "week4"],
"February": ["week5", "week6", "week7"],
"March": ["week8", "week9", "week11"]
},
"2019": {
"January": ["week1", "week2", "week3", "week4"],
"February": ["week5", "week6", "week7"],
"March": ["week8", "week10", "week11"]
},
"2020": {
"January": ["week1", "week2", "week3", "week4"],
"February": ["week5", "week6", "week7"],
"March": ["week8"]
}
}
const years = Object.keys(mydates); // years = ['2018', '2019', '2020']
const initalMonths = Object.keys(Object.values(mydates)[0]);
const initialWeeks = mydates[Object.keys(mydates)[0]][initalMonths[0]];
const $yearSelectionOBJ = document.getElementById('selecetedyear');
const $monthSelectionOBJ = document.getElementById('selecetedmonth');
const $weekSelectionOBJ = document.getElementById('selecetedweek');
for (year of years) {
const $optOBJ = document.createElement('option');
$optOBJ.innerHTML = year;
$yearSelectionOBJ.appendChild($optOBJ);
}
for (month of initalMonths) {
const $optOBJ = document.createElement('option');
$optOBJ.innerHTML = month;
$monthSelectionOBJ.appendChild($optOBJ);
}
for (week of initialWeeks) {
const $optOBJ = document.createElement('option');
$optOBJ.innerHTML = week;
$weekSelectionOBJ.appendChild($optOBJ);
}
$yearSelectionOBJ.addEventListener('change', (event) => {
$monthSelectionOBJ.innerHTML = '';
$weekSelectionOBJ.innerHTML = '';
for (month in mydates[event.target.value]) {
const $optOBJ = document.createElement('option');
$optOBJ.innerHTML = month;
$monthSelectionOBJ.appendChild($optOBJ);
}
for (week of mydates[event.target.value][Object.keys(mydates[event.target.value])[0]]) {
const $optOBJ = document.createElement('option');
$optOBJ.innerHTML = week;
$weekSelectionOBJ.appendChild($optOBJ);
}
});
$monthSelectionOBJ.addEventListener('change', (event) => {
$weekSelectionOBJ.innerHTML = '';
for (week of mydates[$yearSelectionOBJ.value][$monthSelectionOBJ.value]) {
const $optOBJ = document.createElement('option');
$optOBJ.innerHTML = week;
$weekSelectionOBJ.appendChild($optOBJ);
}
});
回答2:
The basic idea is to use an onchange event from the selection of a new value to populate the values of the other dropdowns. Below is an example.
const mydates = {
"2018": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8","week9","week11"]
},
"2019": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8","week10","week11"]
},
"2020": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8"]
}
};
const yearSelect = document.getElementById("year");
for (let year in mydates) {
let opt = document.createElement('option');
opt.innerHTML = year;
yearSelect.appendChild(opt);
}
const monthSelect = document.getElementById("month");
const weekSelect = document.getElementById("week");
// delete all options besides the placholder
function clearSelect(select) {
select.querySelectorAll("option:not(.placeholder)").forEach(elem => {
select.removeChild(elem);
});
}
function yearChanged(year) {
monthSelect.querySelector("option.placeholder").innerHTML = "Select a month";
clearSelect(monthSelect);
// add options for the given year
for (let month in mydates[year]) {
let opt = document.createElement('option');
opt.innerHTML = month;
monthSelect.appendChild(opt);
}
monthSelect.value = ''; // select the placeholder
clearSelect(weekSelect);
weekSelect.querySelector("option.placeholder").innerHTML = "Select a month first";
weekSelect.value = ''; // select the placeholder
}
function monthChanged(month) {
weekSelect.querySelector("option.placeholder").innerHTML = "Select a week";
clearSelect(weekSelect)
for (const week of mydates[yearSelect.value][month]) {
let opt = document.createElement('option');
opt.innerHTML = week;
weekSelect.appendChild(opt);
}
weekSelect.value = ''; // select the placeholder
}
<html>
<head></head>
<body>
<select id="year" onchange="yearChanged(this.value)">
<option class="placeholder" value="" disabled selected>Select a year</option>
</select>
<select id="month" onchange="monthChanged(this.value)">
<option class="placeholder" value="" disabled selected>Select a year first</option>
</select>
<select id="week">
<option class="placeholder" value="" disabled selected>Select a month first</option>
</select>
</body>
</html>
回答3:
You can do the following,
var mydates = {
"2018": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8","week9","week11"]
},
"2019": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8","week10","week11"]
},
"2020": {
"January": ["week1","week2","week3","week4"],
"February": ["week5","week6","week7"],
"March": ["week8"]
}
}
var myyear = document.getElementById('selectedyear');
Object.keys(mydates).forEach(year => {
var yearOpt = document.createElement('option');
yearOpt.innerHTML = year;
myyear.appendChild(yearOpt);
let months = Object.keys(mydates[year]);
var myMonth = document.getElementById('selectedmonth');
months.forEach(month => {
var monthOpt = document.createElement('option');
monthOpt.innerHTML = month;
myMonth.appendChild(monthOpt);
var myWeek = document.getElementById('selectedweek');
mydates[year][month].forEach(week => {
let opt = document.createElement('option');
opt.innerHTML = week;
myweek.appendChild(opt);
});
})
})
来源:https://stackoverflow.com/questions/65547642/javascript-iterate-through-json-file-levels-to-populate-dropdown-list