2

I have a select list with options that each contain a custom attribute of "active" which is either equal to "T" or "F". I'm trying to set up a javascript or jQuery function that will allow me to filter the options to only show those whose active attribute is equal to "T" or whose active attribute is equal to "F" based on which button they click. Essentially having "Show Active" / "Show Inactive" buttons that will hide/show the appropriate select options.

Does anyone have any samples they could provide to get me started? Thank you very much in advance!

function toggleUnitsSelector(active)
{
    $('#unitsSelector option').each(function() {
        if($(this).attr("active")==active){
            $(this).show();
        } else {
            $(this).hide();
        }
    });
}

Using the example provided by David Xu I came up with the function above. It does indeed limit the options to only the ones marked as active="T" when I click my "show active" button, however it shows an empty select box when trying for inactive. I can see in Google Chromes dev tools that the markup is being changed and when I select "show inactive" the ones that were marked with style="display:none;" switch to style="display:inline;" but they do not show up. Any ideas? Also, I'm calling this function toggleUnitsSelector('T') or toggleUnitsSelector('F')

Phil
  • 4,029
  • 9
  • 62
  • 107

5 Answers5

1

A fairly easy option is to combine an updated version of this plugin: https://stackoverflow.com/a/9234883/2287470 with a simple event handler:

$.fn.toggleOption = function( show ) {
    return this.each(function(){
        $(this).toggle(show);
        if(show) {
            if($(this).parent('span.toggleOption').length) $(this).unwrap();
        } else {
            $(this).wrap('<span class="toggleOption" style="display: none;" />');
        }
    });
};

var list = $('select option'), buttons = $('button');

list.toggleOption(false);

buttons.on('click', function () {
    var filter = $(this).hasClass('active') ? "[data-active=F]" : "[data-active=T]";
    list.toggleOption(true).filter(filter).toggleOption(false);
});

This hides the options in a cross browser compatible way and still remains quite small in size. Here it is working: http://jsfiddle.net/jTngY/2/

Community
  • 1
  • 1
Joe
  • 15,205
  • 8
  • 49
  • 56
0

With jQuery loop over each "option" item within the "select" tag:

$("#select_list option").each(function(i,o) {
   if (o.attr("active") == "T") {
      console.log(o + " is T");
   }
});

Hope this helps

David Xu
  • 5,555
  • 3
  • 28
  • 50
  • 1
    hmm.. wouldn't `o` be the index? the arguments passed in are (index,Element) – wirey00 Aug 06 '13 at 20:33
  • 1
    Using your code as example, I've come up with the following function toggleUnitsSelector(active) { $('#unitsSelector option').each(function() { if($(this).attr("active")==active){ $(this).show(); } else { $(this).hide(); } }); } – Phil Aug 06 '13 at 20:40
  • @DavidXu - yeah, that's my answer/fiddle. There are a lot of cross browser inconsistencies when it comes to hiding ` – Joe Aug 07 '13 at 11:04
0

I do sometimes like this:

someSelectInit($("select"));

$("a.someLink").click(function(){
    someSelectFilter($("select"), 'someAttrName','someAttrValue');
    return false;
});

function someSelectInit(objects)
{
    $(objects).each(function(i,e){
        that = $(e);
        options = [];
        that.find('option').each(function(optionIndex, optionElement){
            option = $(optionElement);
            options.push({
                value: option.attr('value'),
                text: option.text(),
                someAttrName: option.attr(someAttrName)
            });
        });
        that.data('options', options);
        that.find("option:not(:disabled)").remove();
    });
}

function someSelectFilter(selectElement, attrName, attrValue)
{
    selectElement = $(selectElement);
    selectElement.find('option:not(:disabled)').remove();
    options = $(selectElement).data('options');
    for(var i in options)
    {
        if(options[i].someAttrName != attrValue)
            continue;

        option = $('<option />').attr('value', options[i].value).text(options[i].text);
        selectElement.append(option);
    }
}
lysenkobv
  • 566
  • 2
  • 5
  • 20
0

Without using jQuery, and assuming each list item has a class attribute of 'select_list_option'

function showItemsForType(type) {
    var elementList = document.getElementsByClassName('.select_list_option'),
        elementArray = Array.prototype.slice.call(elementArray);

    elementArray.forEach(function(el) {
        if (el.getAttribute('active') === type) {
            // display el
        }
    });
}

showItemsForType('T');
nicksweet
  • 3,929
  • 1
  • 20
  • 22
0

Sadly, there is no happy answer for this because IE is the spawn of the Devil . . .

This should be as easy as:

function toggleUnitsSelector(active) {
    $("#unitsSelector option").hide();
    $("#unitsSelector option[active='" + active + "']").show();
}

And that works great in all of the reasonable browsers, however, IE (in at least most, if not all of their versions) is not a reasonable browser and, therefore, will not allow you to hide select options.

So, in order to get them to not display in IE, you have to "get creative", and by "get creative", I mean do things that you should never have to do to support this kind of functionality.

One such solution that you could use would be to have two hidden <select> elements that each contained the active="T" and active="F" options separated out and use those to populate the primary selector (which I defaulted to the "active" options), as needed:

<style>
     .hidden {display: none;}
</style>

<div>
    <select id="unitsSelector">
        <option value="1" active="T">1</option>
        <option value="2" active="T">2</option>
        <option value="4" active="T">4</option>
        <option value="6" active="T">6</option>
        <option value="10" active="T">10</option>
    </select>
    <select id="hiddenSelectorT" class="hidden">
        <option value="1" active="T">1</option>
        <option value="2" active="T">2</option>
        <option value="4" active="T">4</option>
        <option value="6" active="T">6</option>
        <option value="10" active="T">10</option>
    </select>
    <select id="hiddenSelectorF" class="hidden">
        <option value="3" active="F">3</option>
        <option value="5" active="F">5</option>
        <option value="7" active="F">7</option>
        <option value="8" active="F">8</option>
        <option value="9" active="F">9</option>
    </select>

    <input type="button" onclick="javascript: toggleUnitsSelector('T');" value="Show Active" />
    <input type="button" onclick="javascript: toggleUnitsSelector('F');" value="Show Inactive" />
</div>

<script type="text/javascript">
    function toggleUnitsSelector(active) {
        $("#unitsSelector").empty();
        $("#hiddenSelector" + active + " option").each(function() {
            $(this).clone().appendTo($("#unitsSelector"));
        });
    }
</script>

Every time, you click the buttons, it clears out the displayed dropdown and populates it with the options from whichever hidden dropdown contains the options that it needs. And, it works in all browsers . . .

There are many other approaches that you could potentially use (store the values in an array and build the options that you want to show, for example), but, due to IE's inability to play well with others, they are all going to involve some sort of removal of the options that you don't want to display.

Wish it could be as easier . . .

talemyn
  • 7,822
  • 4
  • 31
  • 52