Friday, January 6, 2017

How do I mimic keyboard behavior in my styled select dropdown?

Leave a Comment

I’m using jQuery 1.11. I want to style my select drop-downs because, let’s face it, the default looks sucks. So I found some styles

.selectMenu {   font-family: 'Oxygen', sans-serif;   font-size: 20px;   height: 50px;   -webkit-appearance: menulist-button; }  .select-hidden {   display: none;   visibility: hidden;   padding-right: 10px; }  .select {   cursor: pointer;   display: inline-block;   position: relative;   font-size: 16px;   color: #fff;   width: 220px;   height: 42px; }  .select-styled {   position: absolute;   top: 0;   right: 0;   bottom: 0;   left: 0;   background-color: gray;   padding: 11px 12px;   -webkit-transition: all 0.2s ease-in;   transition: all 0.2s ease-in; } .select-styled:after {   content: "";   width: 0;   height: 0;   border: 7px solid transparent;   border-color: #fff transparent transparent transparent;   position: absolute;   top: 16px;   right: 10px; } .select-styled:hover {   background-color: #7b7b7b; } .select-styled:active, .select-styled.active {   background-color: #737373; } .select-styled:active:after, .select-styled.active:after {   top: 9px;   border-color: transparent transparent #fff transparent; }  .select-options {   display: none;   position: absolute;   top: 100%;   right: 0;   left: 0;   z-index: 999;   margin: 0;   padding: 0;   list-style: none;   background-color: #737373;   overflow: scroll; } .select-options li {   margin: 0;   padding: 12px 0;   text-indent: 15px;   border-top: 1px solid #676767;   -webkit-transition: all 0.15s ease-in;   transition: all 0.15s ease-in; } .select-options li:hover {   color: gray;   background: #fff; } .select-options li[rel="hide"] {   display: none; }  ul.select-options {   max-height: 15em;   overflow-y: scroll;   overflow-x: hidden; } 

and added this jQuery

$(function() {          $('select').each(function(){             styleSelectMenu($(this));         });  });  // This method applies the styles to our select menu function styleSelectMenu(selectMenu) {     var $this = $(selectMenu), numberOfOptions = $(selectMenu).children('option').length;                  /*** NEW - start ***/                 var $paddingCalculator = $('<div />', {                 'class' : "select-styled test"     }).css({                 width : 0,         visibility : "hidden"     }).appendTo("body");     $this.addClass('select-hidden');     var paddingWidth = $paddingCalculator.outerWidth() + 10;     $paddingCalculator.remove();      //var selectWidth = $this.width() + paddingWidth;     var selectWidth = $this.outerWidth() + paddingWidth;     //alert(selectWidth);      if ( !$this.parent().hasClass('select') ) {                 var $wrapper = $("<div />", {                         'class' : "select"         }).css({                         width   : selectWidth         });         $this.wrap( $wrapper );     }   // if                  /*** NEW - end ***/      if ( !$this.next().hasClass('select-styled') ) {         $this.after('<div class="select-styled"></div>');     }    // if      var $styledSelect = $this.next('div.select-styled');     $styledSelect.text($this.children('option').eq(0).text());      if ( $styledSelect.parent().find('ul').length > 0 ) {         $styledSelect.parent().find('ul').remove();     }   // if     var $list = $('<ul />', {         'class': 'select-options'     }).insertAfter($styledSelect);      for (var i = 0; i < numberOfOptions; i++) {         $('<li />', {             text: $this.children('option').eq(i).text(),             rel: $this.children('option').eq(i).val()         }).appendTo($list);     }      var $listItems = $list.children('li');      // This is the event when someone opens the list     $styledSelect.unbind('click')     $styledSelect.click(function(e) {         e.stopPropagation();         $('div.select-styled.active').each(function(){             $(this).removeClass('active').next('ul.select-options').hide();         });         $(this).toggleClass('active').next('ul.select-options').toggle();     });      // This is the event when someone actually selects something from the list     $listItems.unbind('click.selectStyledItem')     $listItems.bind('click.selectStyledItem', function(event) {          clickListItem(event, $styledSelect, $this, $(this), $list);     });      $(document).click(function(event) {         $styledSelect.removeClass('active');         $list.hide();     });       var selectedIndex = $this[0].selectedIndex;     if (selectedIndex > 0) {         var name = $this.attr("name")         var selectedText = $( "select[name='" + name + "'] option:selected" ).text();         selectItemFromStyledList($styledSelect, $this, selectedText, $list);     }   // if  }  // This is the method that will select an item from the styled list function selectItemFromStyledList(styledSelect, selectMenu, selectedText, listToHide) {     $(styledSelect).text(selectedText).removeClass('active');     $(selectMenu).val($(selectMenu).attr('rel'));     $(listToHide).hide();     // Select option in the underlying list so that the form gets submitted     // with the right values     selectedOption = $(selectMenu).find("option").filter(function () { return $(this).html() == selectedText; });     $(selectMenu).find("option[selected='selected']").removeAttr("selected");     $(selectedOption).attr("selected","selected"); }       // selectItemFromStyledList  function clickListItem(event, styledSelect, selectMenu, listItemClicked, list) {         var $styledSelect = $(styledSelect);         var $selectMenu = $(selectMenu);         var $listItem = $(listItemClicked);         var $list = $(list);          event.stopPropagation();         var selectedText = $listItem.text();         selectItemFromStyledList($styledSelect, $selectMenu, selectedText, $list)  }       // clickListItem 

The Fiddle illustrating this is here — http://jsfiddle.net/cwzjL2uw/1/ . The issue is, although I have achieved the style, I have failed to replicate the keyboard behavior that a normal select menu has. My question is, how can I make my menu behave such that when I click the letter “A,” the first “A” item is selected (in this case “Alabama”), just like a regular select menu behaves.

4 Answers

Answers 1

You could use jQuery UI's selectmenu widget, and style it to your liking. Since it already includes keyboard handling, you would only have to worry about styling.

$(function () {    $('select').selectmenu();  });
.ui-selectmenu-button  {    background: gray !important;    padding: 0.4em 0.8em !important;  }  .ui-selectmenu-button *  {     font-family: Verdana;    font-size: 12px;    color: white !important;  }  .ui-menu-item  {     font-family: Verdana;    font-size: 12px;    background: gray;    color: white;  }  .ui-selectmenu-menu ul  {    max-height: 170px;  }  /* Using base64 version of white down arrow */  .ui-icon {    background-image: url('data:image/png;base64,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')!important;   }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>  <select name="user[address_attributes][state_id]" id="user_address_attributes_state_id">    <option value="">Select State</option>    <option value="3526">Alabama</option>    <option value="3556">Alaska</option>    <option value="3547">Arizona</option>    <option value="3510">Arkansas</option>    <option value="3542">California</option>    <option value="3543">Colorado</option>    <option value="3527">Connecticut</option>    <option value="3512">Delaware</option>    <option value="3513">Florida</option>    <option value="3514">Georgia</option>    <option value="3555">Hawaii</option>    <option value="3548">Idaho</option>    <option value="3529">Illinois</option>    <option value="3530">Indiana</option>    <option value="3528">Iowa</option>    <option value="3515">Kansas</option>    <option value="3557">Kentucky</option>    <option value="3516">Louisiana</option>    <option value="3531">Maine</option>    <option value="3517">Maryland</option>    <option value="3558">Massachusetts</option>    <option value="3532">Michigan</option>    <option value="3533">Minnesota</option>    <option value="3519">Mississippi</option>    <option value="3518">Missouri</option>    <option value="3549">Montana</option>    <option value="3534">Nebraska</option>    <option value="3545">Nevada</option>    <option value="3535">New Hampshire</option>    <option value="3536">New Jersey</option>    <option value="3544">New Mexico</option>    <option value="3537">New York</option>    <option value="3520">North Carolina</option>    <option value="3550">North Dakota</option>    <option value="3538">Ohio</option>    <option value="3521">Oklahoma</option>    <option value="3551">Oregon</option>    <option value="3559">Pennsylvania</option>    <option value="3539">Rhode Island</option>    <option value="3522">South Carolina</option>    <option value="3552">South Dakota</option>    <option value="3523">Tennessee</option>    <option value="3524">Texas</option>    <option value="3546">Utah</option>    <option value="3540">Vermont</option>    <option value="3560">Virginia</option>    <option value="3553">Washington</option>    <option value="3511">Washington, D.C.</option>    <option value="3525">West Virginia</option>    <option value="3541">Wisconsin</option>    <option value="3554">Wyoming</option>  </select>

Answers 2

Here is an example of how you can accomplish this using your code. By listening for keys on your active drop down and iterating through the options to find and scroll to a match.

function styleSelectMenu(selectMenu) {         .......      $(document).click(function(event) {         $styledSelect.removeClass('active');         $list.hide();     });       //Example      var keyUps = "", timeOut, $selectOptions = $('.select-options');      $(document).keyup(function(event){       if(!$selectOptions.prev().hasClass('active')){         return false;       }       if(event.key){       keyUps += event.key;       retrieveFromOptions($selectOptions,keyUps);     }     clearTimeout(timeOut);     timeOut = setTimeout(function(){       keyUps = "";     },250);     .......  });  function retrieveFromOptions($options,val){    $options.find('li').each(function(index){     if(this.textContent.substring(0,val.length).toLowerCase() === val.toLowerCase()){         $options.scrollTop(43*index);         return false;     }    }); } 

Fiddle

Notice that this solution does not implement a selection effect equivalent to hovering over the items. That could be done but would require more work.

I would recommend using a solution such as ConnorsFan or one where only css is used to style the select element without replacing it. That way you will retain native functionality.

There are many CSS frameworks which implement the styling of the select element.

Bootstrap is an example.

Answers 3

This feature is not trivial to implement, and involves a few steps:

  1. When the user open the dropdown, attach and event to the document itself listening for keypress events
  2. When the event is fired, get the character from the event and loop over your list looking for the first element that starts with that character
  3. get the position of the list item relative to its container, and scroll the container to that position
  4. you should also check for other relevant keys like arrows up/down, spacebar etc.
  5. remove the listener from the body when the user close the drowdown

Hope I didn't miss anything

Answers 4

You can change your code to this:

$(function() {      $('select').each(function() {      styleSelectMenu($(this));    });  });    // This method applies the styles to our select menu  function styleSelectMenu(selectMenu) {    var $this = $(selectMenu),      numberOfOptions = $(selectMenu).children('option').length;      /*** NEW - start ***/    var $paddingCalculator = $('<div />', {      'class': "select-styled test"    }).css({      width: 0,      visibility: "hidden"    }).appendTo("body");    $this.addClass('select-hidden');    var paddingWidth = $paddingCalculator.outerWidth() + 10;    $paddingCalculator.remove();      //var selectWidth = $this.width() + paddingWidth;    var selectWidth = $this.outerWidth() + paddingWidth;    //alert(selectWidth);      if (!$this.parent().hasClass('select')) {      var $wrapper = $("<div />", {        'class': "select"      }).css({        width: selectWidth      });      $this.wrap($wrapper);    } // if      /*** NEW - end ***/      if (!$this.next().hasClass('select-styled')) {      $this.after('<div class="select-styled"></div>');    } // if      var $styledSelect = $this.next('div.select-styled');    $styledSelect.text($this.children('option').eq(0).text());      if ($styledSelect.parent().find('ul').length > 0) {      $styledSelect.parent().find('ul').remove();    } // if    var $list = $('<ul />', {      'class': 'select-options'    }).insertAfter($styledSelect);      for (var i = 0; i < numberOfOptions; i++) {      $('<li />', {        text: $this.children('option').eq(i).text(),        rel: $this.children('option').eq(i).val()      }).appendTo($list);    }      var $listItems = $list.children('li');      // This is the event when someone opens the list    $styledSelect.unbind('click')    $styledSelect.click(function(e) {      e.stopPropagation();      $('div.select-styled.active').each(function() {        $(this).removeClass('active').next('ul.select-options').hide();      });      $(this).toggleClass('active').next('ul.select-options').toggle();    });      // This is the event when someone actually selects something from the list    $listItems.unbind('click.selectStyledItem')    $listItems.bind('click.selectStyledItem', function(event) {      clickListItem(event, $styledSelect, $this, $(this), $list);    });      $(document).click(function(event) {      $styledSelect.removeClass('active');      $list.hide();    });        var selectedIndex = $this[0].selectedIndex;    if (selectedIndex > 0) {      var name = $this.attr("name")      var selectedText = $("select[name='" + name + "'] option:selected").text();      selectItemFromStyledList($styledSelect, $this, selectedText, $list);    } // if    }    // This is the method that will select an item from the styled list  function selectItemFromStyledList(styledSelect, selectMenu, selectedText, listToHide) {      $(styledSelect).text(selectedText).removeClass('active');      $(selectMenu).val($(selectMenu).attr('rel'));      $(listToHide).hide();      // Select option in the underlying list so that the form gets submitted      // with the right values      selectedOption = $(selectMenu).find("option").filter(function() {        return $(this).html() == selectedText;      });      $(selectMenu).find("option[selected='selected']").removeAttr("selected");      $(selectedOption).attr("selected", "selected");    } // selectItemFromStyledList    // Called when someone clicks an item from the styled list  // The event data should contain the following parameters:  //      styledSelect - the <div> element that contains the styled menu  //      selectMenu - the actual form element that contains the items  //      listItemClicked - the item that was clicked.  //      list - THe <UL> element containig the <li> options  function clickListItem(event, styledSelect, selectMenu, listItemClicked, list) {      var $styledSelect = $(styledSelect);      var $selectMenu = $(selectMenu);      var $listItem = $(listItemClicked);      var $list = $(list);        event.stopPropagation();      var selectedText = $listItem.text();      selectItemFromStyledList($styledSelect, $selectMenu, selectedText, $list)    } // clickListItem    /* New Code */  // Prepare variable to get the entered text  var text = '';    // Handle keydown  jQuery(document).on("keypress", function(e) {          // Only handle event if the menu is open    if (jQuery(".select-styled").hasClass("active")) {      if (e.which != 8) {        var letter = String.fromCharCode(e.which);          // If backspace is pressed        text = text + letter;            jQuery(document).trigger("updateSelect");      }      return false;    }  });    jQuery(document).on("keydown", function(e) {    // Only handle event if the menu is open    if (jQuery(".select-styled").hasClass("active") && e.keyCode == 8) {      text = text.substring(0, text.length - 1);          jQuery(document).trigger("updateSelect");        // If there is no match show original text      if (text.length == 0)        jQuery(".select-styled").text("Select State");      return false;    }  });    jQuery(document).on("updateSelect", function() {      jQuery(".select-styled").text(text);        // Hide all elements    jQuery(".select-options li").hide();      // Show only matching elements    var matchingElements = jQuery(".select-options li:icontains('" + text + "')");    matchingElements.show();      return false;  });    // Add case insitive contains expression  $.expr[":"].icontains = $.expr.createPseudo(function(arg) {    return function(elem) {      return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) == 0;    };  });
/* line 63, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .selectMenu {    font-family: 'Oxygen', sans-serif;    font-size: 20px;    height: 50px;    -webkit-appearance: menulist-button;  }  /* line 70, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-hidden {    display: none;    visibility: hidden;    padding-right: 10px;  }  /* line 76, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select {    cursor: pointer;    display: inline-block;    position: relative;    font-size: 16px;    color: #fff;    width: 220px;    height: 42px;  }  /* line 85, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-styled {    position: absolute;    top: 0;    right: 0;    bottom: 0;    left: 0;    background-color: gray;    padding: 11px 12px;    -webkit-transition: all 0.2s ease-in;    transition: all 0.2s ease-in;  }  /* line 94, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-styled:after {    content: "";    width: 0;    height: 0;    border: 7px solid transparent;    border-color: #fff transparent transparent transparent;    position: absolute;    top: 16px;    right: 10px;  }  /* line 104, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-styled:hover {    background-color: #7b7b7b;  }  /* line 107, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-styled:active,  .select-styled.active {    background-color: #737373;  }  /* line 109, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-styled:active:after,  .select-styled.active:after {    top: 9px;    border-color: transparent transparent #fff transparent;  }  /* line 116, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-options {    display: none;    position: absolute;    top: 100%;    right: 0;    left: 0;    z-index: 999;    margin: 0;    padding: 0;    list-style: none;    background-color: #737373;    overflow: scroll;  }  /* line 128, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-options li {    margin: 0;    padding: 12px 0;    text-indent: 15px;    border-top: 1px solid #676767;    -webkit-transition: all 0.15s ease-in;    transition: all 0.15s ease-in;  }  /* line 134, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-options li:hover {    color: gray;    background: #fff;  }  /* line 138, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    .select-options li[rel="hide"] {    display: none;  }  /* line 144, /Users/davea/Documents/workspace/runtrax/app/assets/stylesheets/profile.css.scss */    ul.select-options {    max-height: 15em;    overflow-y: scroll;    overflow-x: hidden;  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <select class="selectField selectMenu form-control" name="user[address_attributes][state_id]" id="user_address_attributes_state_id">    <option value="">Select State</option>    <option value="3526">Alabama</option>    <option value="3556">Alaska</option>    <option value="3547">Arizona</option>    <option value="3510">Arkansas</option>    <option value="3542">California</option>    <option value="3543">Colorado</option>    <option value="3527">Connecticut</option>    <option value="3512">Delaware</option>    <option value="3513">Florida</option>    <option value="3514">Georgia</option>    <option value="3555">Hawaii</option>    <option value="3548">Idaho</option>    <option value="3529">Illinois</option>    <option value="3530">Indiana</option>    <option value="3528">Iowa</option>    <option value="3515">Kansas</option>    <option value="3557">Kentucky</option>    <option value="3516">Louisiana</option>    <option value="3531">Maine</option>    <option value="3517">Maryland</option>    <option value="3558">Massachusetts</option>    <option value="3532">Michigan</option>    <option value="3533">Minnesota</option>    <option value="3519">Mississippi</option>    <option value="3518">Missouri</option>    <option value="3549">Montana</option>    <option value="3534">Nebraska</option>    <option value="3545">Nevada</option>    <option value="3535">New Hampshire</option>    <option value="3536">New Jersey</option>    <option value="3544">New Mexico</option>    <option value="3537">New York</option>    <option value="3520">North Carolina</option>    <option value="3550">North Dakota</option>    <option value="3538">Ohio</option>    <option value="3521">Oklahoma</option>    <option value="3551">Oregon</option>    <option value="3559">Pennsylvania</option>    <option value="3539">Rhode Island</option>    <option value="3522">South Carolina</option>    <option value="3552">South Dakota</option>    <option value="3523">Tennessee</option>    <option value="3524">Texas</option>    <option value="3546">Utah</option>    <option value="3540">Vermont</option>    <option value="3560">Virginia</option>    <option value="3553">Washington</option>    <option value="3511">Washington, D.C.</option>    <option value="3525">West Virginia</option>    <option value="3541">Wisconsin</option>    <option value="3554">Wyoming</option>  </select>

And here is a JSFiddle: http://jsfiddle.net/noevLzno/2/

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment