Search code examples
javascriptjquerystringdetectionkeypress

Capture keypress to filter elements


I'm creating a <select> replacement using jQuery to replace it with divs and links.

Now I want to filter it when I start to type something with the new select open.

Like Google Translate does on the language selector.

Do you have any advice how do i proceed?

I started something with:

$(document).bind('keypress', function(event) {
   //...
});

But I capture only single keys, not the whole typed string.


Important:

  • I don't have an <input /> to detect the keypress or keyup events on it
  • I prefer not to create this <input /> since I want to use only <div>'s and <a>'s on the "new select"
  • Lately I'll need to navigate on the open select with arrow keys + enter to select the option with my keyboard

Solution

  • You could achieve this by 'listening' about what is pressed on the window, and then detecting the particular letter/string pressed, search through items list and if you find it change its css properties or add a new 'selected' class i.e. (demo => http://jsfiddle.net/steweb/mC6tn/ ..try pressing whatever :) and added after something found press left or right btns, or enter) :

    JS: (supposing that each element you want to find something into and select it has class 'elem')

    var whatYouAreSearching = $('<div class="searching-string"></div>'); //just to see what string you're typing
    $(document.body).append(whatYouAreSearching);
    
    function search(what){
        what = what.toLowerCase();
        $('.elem').removeClass('selected'); //reset everything
        $.each($('.elem'),function(index,el){
            if($(el).html().toLowerCase().indexOf(what) > -1){
                $(el).addClass('selected');
                return false; //found, 'break' the each loop
            }
        });
    }
    
    var letterPressed = [];
    var timeOutResetLetters = null;
    
    $(window).keypress(function(e) {
        clearTimeout(timeOutResetLetters); //clear timeout, important!
        timeOutResetLetters = setTimeout(function(){ //if 500 ms of inactivity, reset array of letters pressed and searching string
            letterPressed = []; 
            whatYouAreSearching.html('');
        },500);
        letterPressed.push(String.fromCharCode(e.keyCode)); //look at the comment, thanks Niclas Sahlin 
        whatYouAreSearching.html(letterPressed.join('')); //show string
        search(letterPressed.join('')); //and search string by 'joining' characters array
    });
    

    EDIT added left/right/enter keys handling

    $(window).keydown(function(e){ //left right handling
        var currSelected = $('.elem.selected');
    
        if(e.keyCode == "37"){ //left, select prev
            if(currSelected.prev() && currSelected.prev().hasClass('elem')){
                currSelected.prev().addClass('selected');
                currSelected.removeClass('selected');   
            }
        }else if(e.keyCode == "39"){ //right, select next
            if(currSelected.next() && currSelected.next().hasClass('elem')){
                currSelected.next().addClass('selected');
                currSelected.removeClass('selected');   
            }
        }else if(e.keyCode == "13"){ //enter
           $('.entered').remove();
           $(document.body).append(currSelected.clone().addClass('entered'));
        }
    });