【问题标题】:Javascript iterate through JSON file levels to populate dropdown listJavascript 遍历 JSON 文件级别以填充下拉列表
【发布时间】:2021-04-09 08:36:22
【问题描述】:

我是 JS 新手,我尝试从 JSON 文件传递​​值以填充下拉列表。我有一个如下所示的 JSON 文件:

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"]
    }
}

我希望第一个下拉列表显示列出的年份,第二个下拉列表显示月份,最后一个下拉列表显示几周。

我想出了以下方法来填充 id 为“selectedyear”多年的下拉列表,并且效果很好:

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);
}

现在我如何遍历 JSON 的第二级,以便 id 为“selectedmonth”的下拉菜单选项仅显示所选年份的月份,然后为 id 为“selectedweek”的下拉菜单显示星期对应选定的年月??

非常感谢您的帮助!

【问题讨论】:

  • 您想一次显示 3 个下拉元素还是一个动态下拉列表?
  • 一次三个下拉元素

标签: javascript json drop-down-menu


【解决方案1】:

基本思想是使用新值选择中的 onchange 事件来填充其他下拉列表的值。下面是一个例子。

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>

【讨论】:

  • 非常感谢。当我使用您的代码 sn-p 时它工作正常,但我的 html 上没有出现任何内容。唯一的区别是我从 Django 中的静态文件调用 json 文件的方式......问题来自以下几行,因为这里的 mydates 根据您的代码不是一个常量? var mydates; .fetch("{% static 'dates.json' %}") .then(response => response.json()) .then(json => mydates = json) .then(() => console.log(mydates ));
  • 我可以在 console.log 中看到正确解析的 json ...但在 html 上按钮是空的
  • 是的,听起来解析很好。对于范围, mydates 应该在全球范围内可用,所以这不是问题。你在js和html中转换了select的id吗?我使用了#year、#month 和#date,而我相信您使用的是#selectedyear、#selectedmonth 和#selecteddate。
  • 是的,我更改了 ID 以匹配您的 ID。我现在收到以下错误: Uncaught ReferenceError: yearChanged is not defined at HTMLSelectElement.onchange
【解决方案2】:

以下代码初始化并侦听除周选择之外的任何选择的事件change

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);
    }
});

【讨论】:

    【解决方案3】:

    您可以执行以下操作,

    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);
        });
      })
    })
    

    【讨论】:

      猜你喜欢
      • 2023-04-04
      • 2021-02-21
      • 2013-04-16
      • 2021-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      相关资源
      最近更新 更多