Javascript iterate through JSON file levels to populate dropdown list

橙三吉。 提交于 2021-01-07 02:49:41

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!