jEditable select下拉菜单更改选项的顺序

Bla*_*ger 5 jquery select jeditable

这是我用来使用jEditable向表行添加选择下拉列表的代码:

$('tr',this).find('td:eq(8)').css('cursor','pointer')
    .editable( 'update.php', {
        'type': "select",
        'loadurl': 'json.php',
        'onblur': 'submit',
        'callback': function( value, settings ) {
         // etc.
        }); 
Run Code Online (Sandbox Code Playgroud)

问题是下拉列表中的选项未按所需顺序排序.来自的原始JSON json.php按名字排序(根据客户的要求):

{"0":"Select driver...", "48":"Ashley Solis", "43":"Casey Segal", // etc. 
Run Code Online (Sandbox Code Playgroud)

但在最终的网页中,选择下拉列表中的选项按编号排序.

似乎jEditable在我不想要的时候重新排序JSON数据.我该如何解决?

小智 9

更简单的解决方法:使值非数字.在开头或其他位置添加"_",然后在选择后使用该值时将其删除:

{"_0":"Select driver...", "_48":"Ashley Solis", "_43":"Casey Segal", // etc. 
Run Code Online (Sandbox Code Playgroud)

这应该保留顺序(至少在我测试过的浏览器中).


Bla*_*ger 4

原因

问题的根源不在于 jEditable,而在于它用于创建选择下拉列表的 JSON 是单个对象。JavaScript 将对象属性视为未排序。这是 jEditable 1.7.1 中的关键代码(从第 492 行开始):

 /* If it is string assume it is json. */
 if (String == data.constructor) {      
     eval ('var json = ' + data);
 } else {
 /* Otherwise assume it is a hash already. */
     var json = data;
 }
 for (var key in json) {
 // starts looping through the object properties
Run Code Online (Sandbox Code Playgroud)

通常,for (var key in json)应该按照 JSON 属性的创建顺序循环遍历它们。相反,它们按数字(“字母”)顺序循环。


修复方法

有很多方法可以解决这个问题,但最简单的方法是通过我通过 Google 搜索在 Pastebin 上找到的一个匿名编写的 jEditable 插件将其粘贴到新的 JavaScript 文件中,然后在 jEditable之后将其加载到 HTML 文件中:

<script src="/js/jquery.jeditable.min.js"></script>
<script src="/js/jquery.jeditable.plugins.js"></script>
Run Code Online (Sandbox Code Playgroud)

此外,json.php必须更改该文件。而不是将 JSON 作为对象返回,如下所示:

{"0":"Select driver...", "48":"Ashley Solis", "43":"Casey Segal", // etc. 
Run Code Online (Sandbox Code Playgroud)

它应该以线性数组形式返回 JSON,如下所示:

[" Select driver...||0","Ashley Solis||48","Casey Segal||43", // etc.
Run Code Online (Sandbox Code Playgroud)

请注意在字符串“Select driver...”开头使用空格,这确保它将被排序到第一个位置。不需要更改任何其他 JavaScript,前提是json.php不在其他地方使用它。


插件

这是我在 Pastebin 上找到的完整 jEditable 插件

// type: select (based on 1.7.1, added feature: sorted options)
$.editable.addInputType("select", {
    element: function (settings, original) {
        var select = $('<select />');
        $(this).append(select);
        return (select);
    },
    content: function (data, settings, original) {
        /* If it is string assume it is json. */
        if (String == data.constructor) {
            eval('var json = ' + data);
        } else {
            /* Otherwise assume it is a hash already. */
            var json = data;
        }

        var aData = [];
        for (var key in json) {
            if (!json.hasOwnProperty(key)) {
                continue;
            }
            if ('selected' == key) {
                continue;
            }

            aData.push(json[key] + "||" + key);
        }

        // Sort
        aData.sort();

        // Create
        for (var key in aData) {
            var aDataSplit = aData[key].split("||");

            var option = $('<option />').val(aDataSplit[1]).append(aDataSplit[0]);
            $('select', this).append(option);
        }

        /* Loop option again to set selected. IE needed this... */
        $('select', this).children().each(function () {
            if ($(this).val() == json['selected'] || $(this).text() == $.trim(original.revert)) {
                $(this).attr('selected', 'selected');
            }
        });
    }
});
Run Code Online (Sandbox Code Playgroud)