ajax user suggest

intermediate ajax, css, js, mysql, php, jquery, knockout 779 misterhaan

it’s been a few years since my ajax suggest guide, and since i’ve rewritten my ajax user suggestion code i figured an updated guide is in order. this guide covers using ajax with jquery and knockout to suggest users when typing in a text input field and support selection with the keyboard or mouse. familiarity with php, mysql, javascript, jquery, knockout, html, and css will make this guide more useful. specific css examples are not given since the best look will depend on the website using it. differences from the previous guide are including jquery and knockout, showing avatar and friend status with suggested usernames, and a single mysql query instead of two that get combined in php.

  1. find matching users
  2. define a view model
  3. create the search field
  4. support mouse selection
  5. support keyboard selection
  6. all 5 pages

support keyboard selection

the arrow keys need to move cursor up and down, and the suggestion the cursor is on needs to look different from the others. update the user suggestion li tag to use the highlight css class when the cursor is on it:

  <!-- ko foreach: users -->
  <li class=suggesteduser data-bind="click: $parent.Select, css: {highlight: id == $parent.cursor().id}">
    <!-- ... -->
  </li>
  <!-- /ko -->

knockout’s css binding is set up with possible class names (in this case, just highlight), which are applied when the value evaluates to true. add some css for the highlight class so that it stands out, probably with a different background color.

by default there’s no cursor, so pressing enter won’t do anything. the up arrow should put the cursor on the last suggestion or the down arrow should put it on the first. once there is a cursor, enter selects that user, up goes to the previous (or wraps around to the bottom), and down goes to the next (or wraps back up to the top). the keys need to work when typing in the usermatch field, so look for them in the keydown event (keypress won’t work because it doesn’t run for the arrow keys). using jquery to attach a function to the keydown event handles the relevant browser inconsistencies. here i manipulate the view model from the outside, which can be done because i saved a reference to the view model as a property of the window object:

$(function() {
  ko.applyBindings(window.ViewModel = new UserSuggestViewModel());

  $("#usermatch").keydown(function(e) {
    var vm = window.ViewModel;
    if(vm.users().length && (vm.cursor() && e.which == 13 || e.which == 38 || e.which == 40)) {
      if(vm.cursor())
        if(e.which == 13)
          $("li.highlight").click();
        else if(e.which == 38) {
          for(var u = vm.users().length - 1; u >= 0; u--)
            if(vm.users()[u] == vm.cursor()) {
              vm.cursor(u > 0 ? vm.users()[u - 1] : vm.users()[vm.users().length - 1]);
              break;
            }
        } else {
          for(var u = 0; u < vm.users().length; u++)
            if(vm.users()[u] == vm.cursor()) {
              vm.cursor(u >= vm.users().length - 1 ? vm.users()[0] : vm.users()[u + 1]);
              break;
            }
        }
      else
        vm.cursor(e.which == 38 ? vm.users()[vm.users().length - 1] : vm.users()[0]);
      e.preventDefault();
    }
  });
});

the keydown handler gets attached in the document ready function, which runs as soon as the structure of the page has loaded. i save a reference to the view model in a variable called vm so i don’t have to type out window.ViewModel each time i use it. keydown gets called for any key, so make sure there’s something to do here: only if there is at least one suggestion and either there’s a cursor and enter was pressed or the up or down arrow was pressed. i looked up the 38 and 40 codes for the arrow keys to know what to check e.which against.

the next branch is whether there’s a cursor. enter key only needs to be handled when there is a cursor, and all i need to do is simulate clicking on the highlighted user and let the function set up for the mouse take care of selecting the user. the up and down arrow keys move one space before or after the cursor, wrapping around if it tries to go up from the first or down from the last. without a cursor, just put the cursor on the first or last suggestion. finally, e.preventDefault() makes sure the browser doesn’t go on to do its own handling of the key, such as submitting the form when pressing enter.

with that the input field now searches for users when at least three characters are entered, displays suggestions in a styled dropdown list, supports selection of a suggestion using either the mouse or keyboard, and displays the selected user in place of the input field.

  1. find matching users
  2. define a view model
  3. create the search field
  4. support mouse selection
  5. support keyboard selection
  6. all 5 pages

how was it?

comments

there are no comments on this guide so far. you could be the first!

*