Search code examples
jqueryjquery-uijquery-ui-selectmenu

Hide option in jQuery-UI selectmenu


It is an easy task to hide the option in a select.

jQuery("#bbb").hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<select id="mySelect">
    <option id="aaa">A</option>
    <option id="bbb">B</option>
    <option id="ccc">C</option>
</select>

But how does it work in Selectmenu UI ? I can only remove options, but hiding them seems to be impossible.

For example I try to hide the option 'RAL Sonderfarbe' on the select Farbe:

Attempt (in dev console):

var $el = jQuery('option:contains("RAL Sonderfarbe")');
$el.hide();
$hausfux_laenge_dropdown.find('select').selectmenu('refresh');

But it does not work.

enter image description here

I found a workaround, but if selectmenu('refresh'); is called, then the option appears again...

$('#mySelect').selectmenu();
var mySelectOpened = false;

$('#mySelect').selectmenu({
    open: function(event, ui) {
        if (mySelectOpened == false) {
            mySelectOpened = true;
            var $el1 = $('#mySelect option:contains("B")');
            var $el2 = $('li:contains("B")');
            
            $el1.hide();
            $el2.hide();
        } 
    }
});

$("#refresh").click(function() {
    $('#mySelect').selectmenu('refresh');
});
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

<select id="mySelect">
    <option id="aaa">A</option>
    <option id="bbb">B</option>
    <option id="ccc">C</option>
</select>

<button id="refresh">Refresh Selectmenu UI</button>


Solution

  • I solved it by extending the core jQuery UI javascript and css.

    Example:

    var $el = jQuery('option:contains("B")');
    $('#mySelect').selectmenu();
    
    jQuery('#hide_option_b').click(function() {
      $el.attr('hidden',true);
      $('#mySelect').selectmenu('refresh');
    });
    jQuery('#show_option_b').click(function() {
      $el.attr('hidden',false);
      $('#mySelect').selectmenu('refresh');
    });
    <link href="https://cdn.jsdelivr.net/gh/Eddcapone/custom_jquery-ui-1.12.1@master/jquery-ui.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/Eddcapone/custom_jquery-ui-1.12.1@master/jquery-ui.js"></script>
    
    <select id="mySelect">
        <option id="aaa">A</option>
        <option id="bbb">B</option>
        <option id="ccc">C</option>
    </select>
    
    <button id="hide_option_b">Hide option B</button>
    <button id="show_option_b">Show option B</button>

    I added this to jquery-ui.css (https://raw.githubusercontent.com/Eddcapone/custom_jquery-ui-1.12.1/master/jquery-ui.css)

    /* Hidden */
    .ui-state-hidden { display: none; }
    

    And I changed/added some lines in jquery-ui.min.js (https://raw.githubusercontent.com/Eddcapone/custom_jquery-ui-1.12.1/master/jquery-ui.js):

    Changed _renderItem from:

    _renderItem: function( ul, item ) {
        var li = $( "<li>" ),
            wrapper = $( "<div>", {
                title: item.element.attr( "title" )
            } );
    
        if ( item.disabled ) {
            this._addClass( li, null, "ui-state-disabled" );
        }
    
        this._setText( wrapper, item.label );
    
        return li.append( wrapper ).appendTo( ul );
    },
    

    to

    _renderItem: function( ul, item ) {
        var li = $( "<li>" ),
            wrapper = $( "<div>", {
                title: item.element.attr( "title" )
            } );
    
        if ( item.disabled ) {
            this._addClass( li, null, "ui-state-disabled" );
        }
        if ( item.hidden ) {
            this._addClass( li, null, "ui-state-hidden" );
        }
    
        this._setText( wrapper, item.label );
    
        return li.append( wrapper ).appendTo( ul );
    },
    

    And _parseOption from:

    _parseOption: function( option, index ) {
        var optgroup = option.parent( "optgroup" );
    
        return {
            element: option,
            index: index,
            value: option.val(),
            label: option.text(),
            optgroup: optgroup.attr( "label" ) || "",
            disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ),
        };
    },
    

    to

    _parseOption: function( option, index ) {
        var optgroup = option.parent( "optgroup" );
    
        return {
            element: option,
            index: index,
            value: option.val(),
            label: option.text(),
            optgroup: optgroup.attr( "label" ) || "",
            disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ),
            hidden: optgroup.prop( "hidden" ) || optgroup.css( "display" ) == "none" || optgroup.css( "visibility" ) == "hidden"
                    || option.prop( "hidden" ) || option.css( "display" ) == "none" || option.css( "visibility" ) == "hidden"
        };
    },
    

    Now hidden options are automatically detected and hidden.