如何在使用 jQuery Selectric 打开之前禁用菜单选项?

How to disable menu options before open using jQuery Selectric?

我终于找到了一个 select 菜单插件,它足够智能,可以在 IE 比较模式下工作,并且还允许我在菜单选项被替换之前触发一个事件。这个很棒的插件叫做 jQuery Selectric.

我需要在显示选项之前触发一个事件,我想发出一个 ajax 请求,告诉我应该选择哪个选项 enable/disable。

我能够在菜单打开前发出 ajax 请求。但我很难尝试禁用这些选项。即使在我禁用它们之后,这些选项也始终处于启用状态。

我尝试在 ajax 上使用 $('select').selectric('refresh'); 成功,但他导致了一个问题,菜单将永远没有机会打开,因为就在它打开之前 ajax 请求将再次关闭它。

如何即时禁用选项?

这是我所做的

    $('#MasterWrapUps').selectric();

    $('#MasterWrapUps').on('selectric-before-open', function (e) {

        var status = "noattempt";

        $.ajax({
            type: "GET",
            url: "/getStatus",
            dataType: "json",
            cache: false,
            success: function (data) {

                if ( data && ! $.isEmptyObject(data) ) {
                    status = data.status;
                }

                attrWrapUpMenu(status);

            }
        });

    });

    function attrWrapUpMenu(status)
    {
        $('.dispositionMenuOption').each(function (index, element) {

            var option = $(element);

            if ( customIsAllowed(status, option) ) {

                option.attr("disabled", false);

            } else {

                if( option.attr('selected') ) {
                    //At this point we know the option that is select can't be used, select the default value
                    $('#MasterWrapUps').val('0')
                }

                option.attr("disabled", true);
            }

        });
    }

由于您无法知道 ajax 需要多长时间才能完成,所以我可以想到两种可能的解决方案:

第一个是在输入上显示一个隐藏的 <div>,并在单击时在其中显示一个加载图像。然后等到 ajax 结束,最终隐藏 div 和 trigger 更新后的 <input> 上的点击事件,或者....

您可以在页面加载后立即启动更新功能并保持 <select> 禁用直到 ajax 完成。

我推荐第二种,但可能还有其他解决方案。如果您需要任何帮助来实施其中任何一个,您应该提出一个新问题。


更新

既然你想在点击之后做,我能想到的最好的就是这个解决方案。它的缺点是如果 ajax 花费的时间太长并且用户离开了 select 输入,它无论如何都会重新打开。但我认为这可以通过一些 focus/class 验证来解决。我会把它交给你。

我必须提醒您,这种 UI 可能会让一些用户(连接不好的用户)对可用或不可用感到困惑。

$('#MasterWrapUps').selectric().on('selectric-init', function () {
  $('#MasterWrapUps').selectric('open');
});
$('.selectric').on('click', function () {
  setTimeout(function () { /* fake ajax */
    $('option:first-child').attr('disabled', true);
    $('#MasterWrapUps').selectric('refresh');    
  }, 600 );
});
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-1.11.3.js"></script>
  <script src="http://lcdsantos.github.io/jQuery-Selectric/jquery.selectric.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <link rel="stylesheet" href="http://lcdsantos.github.io/jQuery-Selectric/selectric.css">
  <style>.selectric-above .selectric-items {top: 100%; bottom: auto}</style>
</head>
<body>
    <select id="MasterWrapUps">
      <option value="ant">Ant</option>
      <option value="bird">Bird</option>
      <option value="cat">Cat</option>
    </select>
</body>
</html>

我将此报告为 github https://github.com/lcdsantos/jQuery-Selectric/issues/109 中的错误。插件 Leonardo Santos 的作者想出了一个聪明的 hacky 方法来解决这个问题。

他给了我这个代码

$('#MasterWrapUps').selectric();

var isOpen = false;
var selectricData = $('#MasterWrapUps').data('selectric');

$('#MasterWrapUps').on('selectric-open', function (e) {
    var status = "noattempt";

    if (!isOpen) {
    selectricData.close();

    $.ajax({
      type: "POST",
      url: "/echo/json/",
      dataType: "json",
      cache: false,
      data: {
        // emulate ajax delay on jsfiddle
        delay: 1
      },
      success: function (data) {
        if ( data && ! $.isEmptyObject(data) ) {
          status = data.status;
        }

        attrWrapUpMenu(status);
      }
    });

  }

});

function customIsAllowed() {
    return !!(Math.random()+.5|0);
}

function attrWrapUpMenu(status) {
  $('.dispositionMenuOption').each(function (index, element) {

    var option = $(element);

    if ( customIsAllowed(status, option) ) {

      option.prop('disabled', false);

    } else {

      if( option.prop('selected') ) {
        $('#MasterWrapUps').val('0');
      }

      option.prop('disabled', true);
    }

  });

  isOpen = true;
  selectricData.refresh();
  selectricData.open();
  isOpen = false;
}

代码也可以在这个fiddlehttps://jsfiddle.net/lcdsantos/rgaeqbp6/

中找到

我希望这段代码对某人有所帮助:)