2

I finally found a select menu plugin smart enough to work in IE comparability mode and also allows me to fire an event before the menu options are displaced. This awesome plugin is called jQuery Selectric.

I need to fire an event before the options are displayed and I want to make an ajax request which tells me which option I should enable/disable.

I was able to make the ajax request before the menu opens. but I am having hard time trying to disable the options. The options are always enabled even after I disable them.

I tried to use the $('select').selectric('refresh'); on ajax sucess but his cause a problem that the menu will never get a chance to open because just before it open the ajax request will close it again.

How can I disable options on the fly?

Here is what I have done

    $('#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);
            }

        });
    }
Junior
  • 11,602
  • 27
  • 106
  • 212

2 Answers2

1

Since you cannot know how long the ajax is going to take to complete, I can think of two possible solutions:

The first is to display a hidden <div> over the input and, on click, show a loading image inside it. Then wait until the ajax is over to finally hide the div and trigger a click event on the updated <input>, or ....

You can launch the update function as soon as the page loads and keep the <select> disable until the ajax is complete.

I recommend the second one, but there might be other solutions. If you need any help implementing any of these you should open a new question.


Update

Since you want to do it after the click, the best I could come up with was this solution. It has the drawback that if the ajax takes too long and the user leaves the select input, it will reopen anyway. But I think this could be fixed with some focus/class verification. I'll leave that in your hands.

I must remind you that this kind of UI might leave some users (the one with bad connection) confused about what is available or not.

$('#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>
rafaelcastrocouto
  • 11,781
  • 3
  • 38
  • 63
  • I don't think this is the problem here. Alternatively I can set `Async:False` to prevent the next action until ajax request finish. The problem here is how do I get the option to show as disabled after it has been opened. It seems that I have to use the `refresh` function which cause an infinite loop! – Junior Mar 02 '16 at 17:13
1

I reported this as a bug in github https://github.com/lcdsantos/jQuery-Selectric/issues/109. The author of the plugin Leonardo Santos at came up with a smart hacky way to solve the problem.

He gave me this code

$('#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;
}

The code can also be found in this fiddle https://jsfiddle.net/lcdsantos/rgaeqbp6/

I hope this code help someone :)

Junior
  • 11,602
  • 27
  • 106
  • 212