4

I started studying javascripting and was wondering if anyone know how to hide values in dropdown list for html?

For example: a dropdwon list with values

Select One   
Item1   
Item2    
Item3  
Item4  
Item5

I wanna hide the Item 4 and 5, like this and show it when "Show... " is clicked.

Select One  
Item1  
Item2  
Item3  
Show 2 more items (Item 4 and 5 hidden)

Is that possible? Below is a piece of code i already started.

var css = select;
var markers = cluster.getMarkers();
var markersLength = markers.length;

var nextOption = new Option("Select One");
css.add(nextOption, 0);

for(var i = 0; i < markersLength; i++) {

    nextOption = new Option(markers[i].title);
    try {
        css.add(nextOption, -1);
    } catch (e) {
        css.add(nextOption, null);
    }
}
user3736748
  • 185
  • 2
  • 3
  • 15
  • Have a look at [How to show and hide a simple
      list with onclick?](http://stackoverflow.com/questions/17561093/how-to-show-and-hide-a-simple-ol-list-with-onclick)
    – Izzy Aug 04 '14 at 09:27
  • 2
    A JSFiddle would be appropriate for this question. Note: You want the answer to be generic and not hard-wired to items 4 and 5 (e.g. all elements after the show more link). – iCollect.it Ltd Aug 04 '14 at 09:27
  • Turns out you cannot *style-out* `select` `option`s consistently across browsers. You need to dynamically alter the list content instead. Reference: http://stackoverflow.com/questions/9234830/how-to-hide-a-option-in-a-select-menu-with-css Answer updated below to cater for this. – iCollect.it Ltd Aug 04 '14 at 10:16

3 Answers3

1

You want a generic solution, so tag the more option and the hidden items with classes.

It turns out you cannot consistently style-out options in a select across browsers, so you need to dynamically alter the list options: Refer to this question: How to hide a <option> in a <select> menu with CSS?

Final solution (append elements from another hidden select):

JSFiddle: http://jsfiddle.net/TrueBlueAussie/93D3h/12/

HTML:

Select One   
<select class="hidden">
    <option>Item4</option>
    <option>Item5</option>
    <option>Item6</option>
    <option>Item7</option>
<select>
<select>
    <option>Item1</option>
    <option>Item2</option>
    <option>Item3</option>
    <option class="more">More</option>
</select>

jQuery:

$('select').change(function(){
    var $select = $(this);
    if ($select.val() == "More"){
    $('.more').remove();
        $select.append($('.hidden').children());
    }
});

Previous info:

Then on then select change event you hide the more option and show the hidden elements:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/93D3h/2/

$('select').change(function(){
    var $select = $(this);
    if ($select.val() == "More"){
    $('.more').hide().prevAll('.hidden').show();
    }
});

There appears to be a weird bug in selects as the last item is always visible (even when styled out!). I added a blank entry to fix this for now. This is also why I did not place the hidden items after the more as the last one always shows (what a strange bug - have asked that as a new question: Why is last select option always shown, even when styled out).

You will also want to clear the selected value of "More" as that will no longer exist.

e.g. http://jsfiddle.net/TrueBlueAussie/93D3h/3/

$('select').change(function () {
    var $select = $(this);
    if ($select.val() == "More") {
        $('.more').hide().prevAll('.hidden').show();
        $select.val('');
    }
});

Followup:

Based on my related question, I was pointed to this one: How to hide a <option> in a <select> menu with CSS? Apparently you cannot style out select options consistently, so adding the items to the list dynamically would be the ideal solution.

Community
  • 1
  • 1
iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
0

Here's my solution:

Html

    <select id="test">
    <option value="1">Select One</option>
    <option value="2">Item 1</option>
    <option value="3">Item 2</option>
    <option value="4">Item 3</option>
    <option value="5">Select Two</option>
    <option value="6">Item 4</option>
    <option value="7">Item 5</option>
    </select>

Script

    var array1 = ["1","6","7"];
    var array2 = ["1","2","3","4"];
    var arrayAll = ["1","2","3","4","5","6","7"];
    function hideOptions(array) {
    for (var i = 0; i < array.length; i++) {
        $('#test option[value="' + array[i] + '"]').hide();
    }
    }

    function showOptions(array) {
    for (var i = 0; i < array.length; i++) {
        $('#test option[value="' + array[i] + '"]').show();
    }
    }


    $("#test").change(function(){
    if($("#test").val()=="5"){ 
        hideOptions(array2);
        showOptions(array1);
    }
    if($("#test").val()=="1"){ 
        hideOptions(array1);
        showOptions(array2);
    }
    });

    hideOptions(array1);

here's the fiddle

Fseee
  • 2,476
  • 9
  • 40
  • 63
  • I see you also hit the browser bug I did, where the last item(s) show on some browsers. – iCollect.it Ltd Aug 04 '14 at 10:06
  • Turns out you cannot *style-out* `select` `option`s consistently across browsers. You need to dynamically alter the list content instead. Reference: http://stackoverflow.com/questions/9234830/how-to-hide-a-option-in-a-select-menu-with-css – iCollect.it Ltd Aug 04 '14 at 10:16
  • I am getting inconsistent results with Chrome too, so it looks like *styling-out* of `option`s is to be avoided completely. Thanks – iCollect.it Ltd Aug 04 '14 at 10:26
  • I've tested it on Firefox and Chrome... it seems to be all rigth – Fseee Aug 04 '14 at 10:29
  • On Chrome V36 (on Win 8 64 bit) I see "Select Two" followed by "Item5" in your Fiddle. The problem is styling options is not a cross browser solution: http://stackoverflow.com/questions/25115869/why-is-last-select-option-always-shown-even-when-styled-out – iCollect.it Ltd Aug 04 '14 at 10:31
0

What about something like:

<head>
  <script type="text/javascript">
  function makeDynamicOption(target, threshold, messageMore, messageLess) {
    var allOptions = collectOptions();
    target.addEventListener("change", updateOptions, false); // Use your own event manager
    showOptions(threshold);
    addMessage(messageMore);

    // ---

    function collectOptions() {
      var options = [];
      for(var ii=0; ii<target.options.length; ii++) {
        options.push(target.options[ii]);
      }
      return options;
    }

    function updateOptions() {
      var selectedText = this.options[this.selectedIndex].text;
      if (selectedText == messageMore) {
        showOptions(allOptions.length);
        addMessage(messageLess);
      } else if (selectedText == messageLess) {
        showOptions(threshold);
        addMessage(messageMore);
      }
    }

    function showOptions(upToIndex) {
      removeOptions();
      for (var ii=0; ii<upToIndex; ii++) {
        target.options[ii] = allOptions[ii];
      }
    }

    function removeOptions() {
      while(target.options.length > 0) {
        target.removeChild(target.options[0]);
      }
    }

    function addMessage(message) {
      target.options[target.options.length] = new Option(message, "");
    }
  }
  </script>
</head>

<body>
  <select id="foo">
    <option value="value1">item1</option>
    <option value="value2">item2</option>
    <option value="value3">item3</option>
    <option value="value4">item4</option>
    <option value="value5">item5</option>
  </select>
  <script type="text/javascript">
  makeDynamicOption(
    document.getElementById("foo"),
    3,
    "More...",
    "Less..."
  );
  </script>
</body>

This design separates the lib part (to be linked in the HEAD as an external script) from the activation part. It also lets you inject localized text while generating the view, and preserve existing options in case you have other scripts interacting with them. Note that you should still use your own event manager, and not addEventListener directly as shown in the script, for better cross-browser support.

EDIT: here's how the scripts works:

  • You call the makeDynamicOptions() function on the select object you want to augment, passing the number of options you want to display, as well as messages to expand/collapse other options. The messages can be written by the view manager, i.e. it could be easily localized if needed.
  • The first initialization step sees that all original options be collected, so that they can be added back when the user wants to expand the select. Note that we collect the objects themselves, and not only their value/text property values, as other scripts could reference these objects.
  • The second initialization step registers a change handler on the select, so as to trigger the update on the options list. The script uses addEventListener, but one should substitute one's own event management mechanism, for better cross-browser support.
  • The last initialization step collapses the select in the intended start position.
  • The rest is pretty straightforward. Once the user selects an option, the script decides whether the list of options should be repopulated, by analyzing the text of the selected option, and comparing it to the provided expand/collapse labels. If options are to be redrawn, then the script removes all options, adds the expected ones, then adds the new expand/collapse message.

HTH.

Elegie
  • 340
  • 1
  • 5
  • 16
  • As it is a `jQuery` tagged question, you could do all that in a fraction of the code shown. Your key point is however that you need to change the DOM and not use styles (I assume that was your key point as the code shown requires a lot of explanation) :) – iCollect.it Ltd Aug 04 '14 at 10:29
  • Hello. Sorry, I'm not used to posting here yet, and hadn't paid attention to the tags. Should I remove the post? And yes, while changing the style is the proper approach here, I fear that options styling is not well supported, especially in older browser generations, so believe it'd be more effective to alter the document structure. – Elegie Aug 04 '14 at 10:44
  • Actually, my investigations lead me to believe *styling* `option`s is *not* the solution (as you get different results on different browsers). Changing the DOM *is* the best solution. Leave your answer. It may be of value to someone later on (but I would explain your code a but more than you do now) :) – iCollect.it Ltd Aug 04 '14 at 10:46
  • Hello, post updated, as per your recommendation. Thank you for guiding me into the good posting practices! I like this website very much, and would be happy to contribute quality answers when I can. Cheers. – Elegie Aug 04 '14 at 11:05