【问题标题】:jEditable select dropdowns change the order of the optionsjEditable 选择下拉菜单更改选项的顺序
【发布时间】:2013-08-22 19:30:51
【问题描述】:

这是我使用 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.
        }); 

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

{"0":"Select driver...", "48":"Ashley Solis", "43":"Casey Segal", // etc. 

但在最终网页中,选择下拉菜单中的选项按数字排序。

似乎 jEditable 在我不希望它重新排序 JSON 数据时。我该如何解决这个问题?

【问题讨论】:

  • 只是说明,不是解决方案,您可能对X-editable 感兴趣。它功能丰富且灵活。
  • @lightswitch05 值得一看,谢谢。在这种情况下,我选择了 jEditable,因为它拥有 integration with dataTables,我也在使用它。

标签: jquery select jeditable


【解决方案1】:

原因

问题的根源不在于 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

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


修复

有很多方法可以解决这个问题,但最简单的方法是通过 Google 搜索通过an anonymously-authored jEditable plug-in I found on Pastebin。将此粘贴到一个新的 JavaScript 文件中,然后将其加载到您的 HTML 文件中之后 jEditable:

<script src="/js/jquery.jeditable.min.js"></script>
<script src="/js/jquery.jeditable.plugins.js"></script>

此外,必须更改json.php 文件。而不是像这样返回 JSON 作为对象:

{"0":"Select driver...", "48":"Ashley Solis", "43":"Casey Segal", // etc. 

它应该将 JSON 作为线性数组返回,如下所示:

[" Select driver...||0","Ashley Solis||48","Casey Segal||43", // etc.

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


插件

这里是the complete jEditable plugin I found on Pastebin

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

【讨论】:

  • 引用:通常,for (var key in json) 应该按照 JSON 属性的创建顺序循环它们——但是将数据复制到 json 的行为会重新排序这些属性按数字顺序排列。 这是错误的。该对象没有被复制; datajson 是指向同一个对象的引用。
【解决方案2】:

更简单的解决方法:将值设为非数字。开头加个“_”什么的,然后在选择后使用值的时候去掉:

{"_0":"Select driver...", "_48":"Ashley Solis", "_43":"Casey Segal", // etc. 

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

【讨论】:

  • 有史以来最有效、最简单的解决方案。谢谢!
【解决方案3】:

我遇到了同样的问题,最终创建了一个名为“server_ordered_select”的自定义输入类型。要使用它,您需要做一些事情:

  1. 更改您的服务器响应以返回一个对象数组。每个对象只有一个 id 和 label 的键值对。例如

    "[{'197':'Sterling'}, {'199':'US Dollar'}, {'185':'Canadian Dollar'}, {'200':'Yen'}]"
    
  2. 在 jEditable 初始化代码之前的某处添加以下内容:

    $.editable.addInputType('server_ordered_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 isArray = Object.prototype.toString.call(json) === '[object Array]',
                selected = "";
            for (var key in json) {
                var k, v;
                if (isArray) {
                    k = Object.keys(json[key])[0];
                    v = json[key][k];
                    if ('selected' == k) {
                        selected = v;
                        continue;
                    }
                } else {
                    if (!json.hasOwnProperty(key)) {
                        continue;
                    }
                    if ('selected' == key) {
                        selected = json['selected'];
                        continue;
                    }
                    k = key;
                    v = json[key];
                }
                var option = $('<option />').val(k).append(v);
                $('select', this).append(option);
            }
            /* Loop option again to set selected. IE needed this... */
            $('select', this).children().each(function() {
                if ($(this).val() == selected ||
                    $(this).text() == $.trim(original.revert)) {
                    $(this).attr('selected', 'selected');
                }
            });
        }
    });
    
  3. 现在在可编辑的初始化选项中将可编辑的类型更改为“server_ordered_select”。

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

输入类型也应该与“选择”类型的常规 json 响应兼容,但它不会保留来自服务器的订单。

【讨论】:

  • 虽然我认为plugin solution 实现起来更简单,但对于那些无法控制 JSON 数据的人来说,这可能是一种更好的方法。
【解决方案4】:

正要实现上述解决方案之一,当我注意到如果您可以调整生成的 JSON,X-Editable 现在支持以下:

列表的源数据。 如果是数组 - 它应该是格式:

[{value: 1, text: "text1"}, {value: 2, text: "text2"}, ...]

---8

自 1.4.1 起支持渲染 OPTGROUP 的关键子项(仅用于选择输入)。

[{text: "group1", children: [{value: 1, text: "text1"}, {value: 2, text: "text2"}]}, ...]

来源:https://vitalets.github.io/x-editable/docs.html

【讨论】:

    【解决方案5】:

    我找到了一种通过值而不是键对 JSON 数据进行排序的方法。您可以在名为“sortselectoptions”的声明中设置一个带有 jeditable 的设置。将此属性设置为“启用”,这应该按其显示值对您的 select-dropwdown 进行排序。

       $(".edit-select").editable('@Url.Action("OptionInline", "BudOption")', {
            type : "select",
            style: "inherit",
            sortselectoptions: "enable",
            loadurl : '@Url.Action("GetOptionDrpJSON", "BudOption")',
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-28
      • 2023-03-31
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      • 2018-02-17
      • 2015-03-28
      相关资源
      最近更新 更多