jQuery和JSON:从具有多个值的数组中链接选择

时间:2016-01-01 21:25:37

标签: javascript jquery html json chained-select

我有一个JSON文件(json/cities.json),它以下列形式将我所在国家/地区的状态与其城市相关联:

{
    "State #1": [
        "City #1 from State #1",
        "City #2 from State #1",
        "City #3 from State #1"
    ],
    "State #2": [
        "City #1 from State #2",
        "City #2 from State #2",
        "City #3 from State #2"
    ]
}

我还有一个带状态的HTML选择,如下所示:

<select id="state" name="state">
    <option value="State #1"> State #1 </option>
    <option value="State #2"> State #2 </option>
</select>

以及城市的空HTML选择:

<select id="city" name="city"></select>

我要做的是使用按键(状态)过滤的JSON值填充城市的HTML选择。

我正在使用以下jQuery脚本:

$('#state').on('change', function () {
    var state = $(this).val(), city = $('#city');
    $.getJSON('json/cities.json', function (result) {
        $.each(result, function (i, value) {
            if (i === state) {
                 var obj = city.append($("<option></option>").attr("value", value).text(value));
                 console.log(obj);
            }
        });
    });
});

问题是,当console.log返回以下标记时,应该填充城市的选项甚至不会更改:

<select name="city" id="city">
    <option value="City #1 form State #1, City #2 from State #1, City #3 from State #1">
        City #1 from State #1, City #2 from State #1, City #3 from State #1
    </option>
</select>

也就是说,这些值作为一个值返回,它应该是多个值(每个值用逗号分隔)。

3 个答案:

答案 0 :(得分:2)

你在州而不是城市上进行迭代。 result[state]为您提供了迭代的数组。

P.S。代码中的url部分只是为了让它在代码片段中运行

&#13;
&#13;
$('#state').on('change', function () {
    var state = $(this).val(), city = $('#city');
    city.empty();
    var url = URL.createObjectURL(new Blob(['{"State #1":["City #1 from State #1","City #2 from State #1","City #3 from State #1"],"State #2":["City #1 from State #2","City #2 from State #2","City #3 from State #2"]}'], {type:'application/json'}));
    $.getJSON(url, function (result) {
        if (result[state]){
            $.each(result[state], function (i, value) {
               city.append($("<option></option>").attr("value", value).text(value));
            });
        }
    });
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="state" name="state">
    <option value="State #1"> State #1 </option>
    <option value="State #2"> State #2 </option>
</select>
<select id="city" name="city"></select>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我的建议:

&#13;
&#13;
$('#state').on('change', function () {
  var state = $(this).val(), city = $('#city');
  $.getJSON('json/cities.json', function (result) {
    var values = result[state];
    if (values != undefined && values.length > 0) {
      city.find('option').remove();
      $(values).each(function(index, element) {
        city.append($("<option></option>").attr("value", element).text(element));
      });
    }
  });
});
&#13;
&#13;
&#13;

答案 2 :(得分:0)

这是一个有效的例子。我改变了一些东西让它起作用;代码中的注释。

首先,我在文档中嵌入了JSON,使其在代码片段中工作。改变这个变量的来源非常简单。您也可以继续在此版本中更改JSON,并且您将看到更改更新。

我没有遍历状态并查看它是否与所选状态匹配,而是利用JSON中的结构按名称索引城市。如果有很多州,这种效率会更高,而且无论如何都更容易编程。

我还在状态标识符下的列表中的 cities 上添加了缺少的迭代。

我添加了清单列表中的城市清单,以便在更改列表时,或者城市列表中包含所有来自所有的城市有史以来的州。

虽然不是绝对必要,但我认为将选定的禁用选项添加到状态<select>是一个不错的选择 - 它会强制用户选择状态并强制更新城市列表(否则状态1由默认情况下,需要做更多的工作来填充初始选择的列表,因为在首次定义元素时,onchange不会被设置)。

&#13;
&#13;
/*
I'm embedding the JSON right in the page, but you'd 
use AJAX, of course.  You might want to pull this data just 
once or - if, it changes frequently and 
interaction with the form is prolonged, pull it
periodically, behind the scenes with a setInterval so the 
user doesn't have to wait for a web request.
*/
function get_state_data(){
   return JSON.parse($('#json').val())
};

// set the event handler after the doc is ready - 
// make sure it's set _after_ the elements it changes 
// are in the DOM
$(document).ready(function() {
  $('#state').on('change', function() {
    var state = $(this).val(),
      city = $('#city'),
      data = get_state_data();
    city.html(""); // clear out old cities
    // make use of the key->value structure of json,
    // rather than iterating over all cities
    if (data[state] === undefined)
      alert("No such state in data! :( ");
    else {
      //we have to iterate over each city
      for (c in data[state]) {
        city.append(
           $("<option></option>").attr("value", data[state][c]).text(data[state][c])
        );
      }
    }
  });
});
&#13;
textarea {
  width: 95%;
  margin: auto;
  height: 10em;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <textarea id='json'>
    { "State #1": [ "City #1 from State #1", "City #2 from State #1", "City #3 from State #1" ], "State #2": [ "City #1 from State #2", "City #2 from State #2", "City #3 from State #2" ] }
  </textarea>
</div>
<select id="state" name="state">
  <option disabled selected value=''>Select a state</option>
  <option value="State #1">State #1</option>
  <option value="State #2">State #2</option>
</select>
<select id="city" name="city"></select>
&#13;
&#13;
&#13;