ajax user suggest

intermediate ajax, css, js, mysql, php, jquery, knockout 896 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 mouse selection

selecting a user suggestion with the mouse needs to do something when the user clicks on a suggested user. add a Select function to the data model which takes a user as a parameter, which will later be linked up to clicking a user suggestion:

function UserSuggestViewModel() {
  var self = this;
  // ...
  self.Select = function(user) {
    self.selectedUser(user);
    self.usermatch("");
    $("#nextfield").focus();
  };
}

whichever user is selected gets stored in the selectedUser observable, then the usermatch field gets cleared, and the focus moves to whatever field is next (replace nextfield with the id of the field that comes after the user search field). clearing usermatch clears the field and gets rid of the suggestions list. some uses will be better suited with a different Select function. for example, on the track7 messages page for a logged-in user actually finds the existing conversation with the selected user or starts a new conversation with that user. it doesn’t track which user was selected and instead selects the conversation with that user immediately. it also doesn’t do this next part, so make changes an necessary to fit the desired use.

change the html so when a user has been selected, that user gets displayed instead of the input field:

<input id=usermatch placeholder="find a person" autocomplete=off data-bind="textInput: usermatch, visible: !selectedUser()">
<span data-bind="visible: selectedUser">
  <img class=avatar data-bind="attr: {src: selectedUser().avatar}">
  <a data-bind="attr: {href: '/user/' + selectedUser().username + '/'}, text: selectedUser().displayname || selectedUser().username"></a>
</span>

the input now has a visible binding in addition to its textInput binding, so it only shows when there is no user selected. the span is new, and contains an avatar image and a link showing the user’s name linked to their profile. in this case the user properties need to be accessed like selectedUser().username value, while previously inside the foreach just username was enough because foreach put it into a user context. another nice touch to add here is a clear icon that sets selectedUser back to false and focuses the usermatch field, so accidentally selecting the wrong user doesn’t mean you need to reload the page. track7 does this but i won’t go into it here.

add a click handler to each user li to call the Select function via the knockout click binding:

  <!-- ko foreach: users -->
  <li class=suggesteduser data-bind="click: $parent.Select">
    <!-- ... -->
  </li>
  <!-- /ko -->

from inside the foreach $parent.Select accesses the Select function defined in the view model and also passes the current user as the first parameter, which is exactly how Select was written. that covers selection with the mouse. next, keyboard selection will build on mouse selection.

  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!

*