使用javascript将json对象转换为已排序的html选择的最佳方法

时间:2014-08-21 16:55:33

标签: javascript html json sorting

将json对象转换为有序HTML选择的最佳方法是什么(仅限直接javascript)?

如果需要,json的格式可以更改。我一直在搜索,大多数文档说对象键不能排序只有数组可以排序,但我无法弄清楚如何修改json的结构使其成为一个数组,因此很容易排序。

var json = {
                "group3": [
                  {"value33": "label33"},
                  {"value13": "label13"},
                  {"value23": "label23"}
                ],
                "group1": [
                  {"value21": "label21"},
                  {"value31": "label31"},
                  {"value11": "label11"}
                ],
                "group2": [
                  {"value22": "label22"},
                  {"value12": "label12"},
                  {"value32": "label32"}
                ]
              };

将成为这个:

    <select multiple="multiple">
      <optgroup label="Group 1">
        <option value="value11">Label 11</option>
        <option value="value21">Label 21</option>
        <option value="value31">Label 31</option>
      </optgroup>
      <optgroup label="Group 2">
        <option value="value12">Label 12</option>
        <option value="value22">Label 22</option>
        <option value="value32">Label 32</option>
      </optgroup>
      <optgroup label="Group 3">
        <option value="value13">Label 13</option>
        <option value="value23">Label 23</option>
        <option value="value33">Label 33</option>
      </optgroup>
    </select>

3 个答案:

答案 0 :(得分:1)

我能够通过略微修改JSON的结构来解决这个问题(因为你说这没问题)并且编写了一个自定义排序函数。

在这里小提琴:http://jsfiddle.net/9urusm5p/2/

<html>
    <head>
        <script>

            //take an object and loop through all the properties
            //each property goes into an array and is sorted
            //loop through the sorted array and build an output array of objects
            //objects in output have 2 properties
            //key = original property name, value = original property value
            function createSortedArray(obj) {
                var returnArray = [];
                var sortingArray = [];
                for(var property in obj) {
                    sortingArray.push(property);
                }
                sortingArray.sort();
                for(var index = 0; index < sortingArray.length; index++) {
                    var property = sortingArray[index];
                    var newObject = {};
                    newObject.key = property;
                    newObject.value = obj[property];
                    returnArray.push(newObject);
                }
                return returnArray;
            }

            window.onload = function() {
                var json = {
                                "group3": {
                                  "value33": "label33",
                                  "value13": "label13",
                                  "value23": "label23"
                                },
                                "group1": {
                                  "value21": "label21",
                                  "value31": "label31",
                                  "value11": "label11"
                                },
                                "group2": {
                                  "value22": "label22",
                                  "value12": "label12",
                                  "value32": "label32"
                                }
                              };

                //sort source object with function above and loop through results
                var sortedGroups = createSortedArray(json);
                for(var index = 0; index < sortedGroups.length; index++) {
                    var group = sortedGroups[index];

                    //create optgroup tag and assign label property
                    var optGroup = document.createElement("optgroup");
                    optGroup.label = group.key;

                    //sort the properties of the current group using our function again
                    var optionArray = createSortedArray(group.value);
                    for(var optionIndex = 0; optionIndex <  optionArray.length; optionIndex++ ) {
                        //options are now sorted, just add to the optgroup
                        var option = optionArray[optionIndex];
                        var opt = document.createElement("option");
                        opt.value = option.key;
                        opt.textContent  = option.value;
                        optGroup.appendChild(opt);
                    }

                    //add optgroup to select tag
                    document.getElementById("select").appendChild(optGroup);
                }
            }
        </script>
    </head>
    <body>
        <select id="select" multiple="multiple" style="height:300px;width:100px;"></select>
    </body>
</html>

答案 1 :(得分:0)

使用document.createElement和一些for循环,我们可以做到这一点:http://jsfiddle.net/kruduuzo/

首先,我们使用for in循环来获取要用作optgroup的键的名称。然后我们使用刚刚发现的组名循环遍历该optgroup中的数组。进入后,再进行另一个for in循环以获取值名称,然后使用它来设置textContent。然后你只需将孩子们附加到他们各自的父母身边,最后选择身体。

var body = document.getElementsByTagName("body")[0];

var select = document.createElement("select");
select.multiple = true;

for (group in json) {
    var optgroup = document.createElement("optgroup");
    optgroup.label = group;
    var i = 0, count = json[group].length;
    for (i; i < count; i++) {
        var opt = document.createElement("option");
        for (value in json[group][i]) {
            opt.value = value;
            opt.textContent = json[group][i][value];
        }
        optgroup.appendChild(opt);
    }
    select.appendChild(optgroup);
}

body.appendChild(select);

我没有注意到你说json的格式可能会改变。在这种情况下,我会做一些类似于GravityScore对你的json所做的事情。但是,如果您发现将json保持为相同的格式会更容易,那么我的解决方案肯定能让您找到所需的位置。

答案 2 :(得分:0)

JavaScript中的字典无法排序,因为它们根本没有订单概念。我通常解决这个问题的方式是:

var json = [
  {
    "name": "group1",
    "content": [
      {"value": "value13", "label": "label13"},
      {"value": "value11", "label": "label33"},
      ...
    ],
  },
  {
    "name": "group2",
    "content": [
      ...
    ]
  },
  ...
}

要对这样的对象进行排序,您可以使用自定义排序功能。要按顺序对每个组进行排序:

json.sort(function(a, b) {
  if (a.name < b.name) {
    return -1;
  } else if (a.name > b.name) {
    return 1;
  } else {
    return 0;
  }
}

要对组内的每个内容数组进行排序,您只需循环遍历json数组中的每个值,并使用上面的另一个自定义排序函数在其内容上调用sort。有关这些的更多信息:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort