0

I have the following code that works in Firefox, but doesn't work in IE. IE throws the error:

The option tag doesn't support the CSS display attribute

How would I solve this so that it is cross browser compatible. I would prefer vanilla JavaScript but jQuery could be used as a last resort.

Here is a JSFiddle: http://jsfiddle.net/djlerman/zP9uC/

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Search in Select Multi Drop Down List</title>
  <script type='text/javascript'>

    function searchSelect(searchForID, searchInID) {
      var input = document.getElementById(searchForID).value.toLowerCase();
      var output = document.getElementById(searchInID).options;

      for (var i = 0; i < output.length; i++) {
        if (output[i].text.toLowerCase().indexOf(input) < 0) {
          output[i].style.display = "none";
          output[i].setAttribute('style', 'display:none');

        } else {
          output[i].style.display = "";
          output[i].setAttribute('style', 'display:');
        }
      }
    }

  </script>
</head>

<body>
Search:
<input type="text" size="25" ID="searchFor" onkeyup="searchSelect(this.id,'searchIn')">
<br />
<select size="3" multiple="multiple" name="searchIn" id="searchIn">
  <option value="abc">Option abc</option>
  <option value="123">Option 123</option>
  <option value="abc123">Option abc123</option>
  <option value="xyz">Option xyz</option>
  <option value="789">Option 789</option>
  <option value="xyz789">Option xyz789</option>
</select>

</body>

</html>
Eugene
  • 4,829
  • 1
  • 24
  • 49
Donavon Lerman
  • 343
  • 1
  • 6
  • 19

3 Answers3

1

I have built a solution by jQuery. It allows to search by special characters, unicode characters. It's fast enough for search 10k options. http://jsfiddle.net/thongduong/3528xg7q/4/

var showOnlyOptionsSimilarToText = function (selectionEl, str, isCaseSensitive) {
    if (typeof isCaseSensitive == 'undefined')
        isCaseSensitive = true;
    if (isCaseSensitive)
        str = str.toLowerCase();

    var $el = $(selectionEl);

    $el.children("option:selected").removeAttr('selected');
    $el.val('');
    $el.children("option").hide();

    $el.children("option").filter(function () {
        var text = $(this).text();
        if (isCaseSensitive)
            text = text.toLowerCase();

        if (text.indexOf(str) > -1)
            return true;

        return false;
    }).show();

};
$(document).ready(function () {
 var timeout;
 $("#SearchBox").on("keyup", function () {
  var userInput = $("#SearchBox").val();
  window.clearTimeout(timeout);
  timeout = window.setTimeout(function() {
   showOnlyOptionsSimilarToText($("#SelectBox"), userInput, true);
  }, 500);

 });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<input type="text" name="SearchBox" id="SearchBox" placeholder="Search" />
<select name="SelectBox" id="SelectBox" required="required" size="5">
 <option value="">Please select</option>
 <option value="1">option 1</option>
 <option value="2">option (1)</option>
 <option value="3">option @ (1)</option>
</select>
0

This is just a quick idea, so there is definitely room for improvement, but you could actually remove the options instead of just trying to hide them, and then restore and filter again on keyup:

var restore;
function searchSelect(searchForID, searchInID) {
  restore = restore || document.getElementById(searchInID).innerHTML;
  document.getElementById(searchInID).innerHTML = restore;
  var input = document.getElementById(searchForID).value.toLowerCase();
  var output = document.getElementById(searchInID).options;
  for (var i = 0; i < output.length; i++) {
    if (output[i].text.toLowerCase().indexOf(input) < 0) {
        output.remove(i);
    }
  }
}

http://jsfiddle.net/RU5mP/

dave
  • 62,300
  • 5
  • 72
  • 93
  • jsfiddle returns and error on line 5 "Expected an assignment or function call and instead saw an expression." I don't understand how it would restore the options if the search box is empty. – Donavon Lerman Mar 20 '14 at 23:10
  • http://jsfiddle.net/RU5mP/1/ try that, and it restores the options when it's empty by replacing the innterHTML with the original HTML every time, and only removing options when indexOf(input) returns -1, which it won't when input is empty – dave Mar 21 '14 at 01:40
  • Hmm.. In Fire Fox is removes some options but keeps others that don't fit the search criteria. Example: When I type "abc" it also displays "Option 789". On IE as soon as the 1st key is pressed it removes ALL of the options and it never returns them. Thank you for helping me with this. – Donavon Lerman Mar 21 '14 at 18:52
0

This is the final solution I came up with. Hopefully some others will find it useful.

The main thing I had to do was load the DropDown data from a variable. That way as the DropDown was being loaded I could filter for the wanted results.

http://jsfiddle.net/djlerman/cYkb4/

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>

  <body>
    Search <input type="text"  ID="searchFor" onkeyup="searchSelect(this.id,'searchIn')">
    <br />
    <select id="searchIn" size="10" multiple>  </select>

    <script type='text/javascript'>//<![CDATA[ 
      window.onload = function () {
        setOptions("searchIn");
      };

      var jsonObj = {};

      jsonObj = {"group1":
                  {"option1":"Option 1",
                   "option2":"Option 2"},
                 "group2":
                  {"option3":"Option 3",
                   "option5":"Option 5",
                   "option7":"Option 7"}
                };

      function setOptions(searchInID) {
        var theSelect = document.getElementById(searchInID);

        for (var key in jsonObj) {
          // set option groups
          var optionGroup   = document.createElement("optgroup");
          optionGroup.label = key;


          for (var key1 in jsonObj[key]) {         
            // set options
            var option   = document.createElement("option");
            option.value = key1;
            option.text  = jsonObj[key][key1];
            option.label = jsonObj[key][key1];
            optionGroup.appendChild(option);
          }

          theSelect.appendChild(optionGroup);
        }
      }

      function searchSelect(searchForID, searchInID) {
        var input     = document.getElementById(searchForID).value.toLowerCase();
        var theSelect = document.getElementById(searchInID);

        theSelect.innerHTML = '';

        for(var key in jsonObj) {
          var optionGroup   = document.createElement("optgroup");
          optionGroup.label = key;


          for(var key1 in jsonObj[key]) {
            if(jsonObj[key][key1].toLowerCase().indexOf(input) >= 0) {
              var option   = document.createElement("option");
              option.value = key1;
              option.text  = jsonObj[key][key1];
              option.label = jsonObj[key][key1];
              optionGroup.appendChild(option);
            }
          }

          theSelect.appendChild(optionGroup);
        }
      }
      //]]>  
    </script>
  </body>
</html>
Donavon Lerman
  • 343
  • 1
  • 6
  • 19