I better blog about this before I forget how to do it. I recently worked on a project where I had to find a way to filter the results on a page using jQuery and custom HTML namespace selectors through a search box. There may be plenty of ways of doing this – probably a better one is to bind the keyup event of the input form field to an Ajax call that fetches the records from the server. For simplicity’s sake, I’ll go through an example of how to do this without any server queries, by using jQuery to filter the already displayed content on the client side.

The HTML

So let’s start with our HTML. This is basic stuff: we set up our page structure, include the jQuery file, create a form with just one text input field which will be used for searching, and a bunch of UL-LIs for listing out the contacts. We’ll assume that each contact has a name, phone and email address which we want to make searchable. We’ll also give our LIs a class which will make it easier to select them through jQuery and also to style them through CSS.

So the first thing we need to do is set up our customized namespace. I decided to give all my custom HTML properties a prefix of “custom“. Therefore, I need to add this to my HTML declaration like so:
<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:custom=”www.evagoras.com”>

I believe the domain you choose can be anything you like, and it doesn’t even have to be the same domain that the page is running under. It is however necessary to use something there, if you want your XHTML to pass the W3C validation.

The second thing we need to do is add the custom attributes inside our HTML. Since I am searching through my contact list, I created an attribute called “searchtext” which holds all the information that I want to make searchable and lives under the “custom” namespace:
<li custom:searchtext=”evagoras kouttouki 652-146-6760 evagoras.kouttouki@gmail.com”>…

The contents of this custom field are all in lowercase to make it consistent with my JavaScript function below.

The JavaScript

We then hook up our form input field to jQuery by binding it to the “keyup” listener which will run our search when a user types something in. The code first:

When we detect that the user has started typing in the search form, we first hide all the LIs with class “contact“, and then display only those that match the search criteria. The most important line of the code is this:
$( ‘li.contact[custom\\:searchtext*=”‘ + EscapeExpression( searchString ) + ‘”]‘ ).show();

Keep in mind that when using square bracket selectors in jQuery, i.e. [], you will need to escape the custom namespace attributes with two backward slashes just like I did.

So there you have it. I think of custom namespace attributes as a sort of a hack, but they work wonders with jQuery and as long as you make sure to define them properly in your HTML document, then they should pass all XHTML validators as well. Please keep in mind that unless you’re actually serving the document as an XML Content-Type, all of your namespace stuff isn’t actually using namespaces anyway – at the end of the day this is all just a hack. In [X]HTML5 they are thinking of allowing custom attributes which will start with “data-“. In the meantime you may decide to hide your attribute in other HTML attributes, like for example the class definition:

2 Responses to jQuery custom namespace attribute selectors used for filtering HTML

  • Ville Walveranta

    Thank you so much for this post; it was exactly what I was looking for!

    One small correction.. I think you meant for each li to have the ‘contact’ class in it.

    • Evagoras Charalambous

      @Ville

      Glad to hear you found it useful. You are right of course about forgetting to add the ‘contact’ class inside of each LI. The downloadable code is correct, but the post was indeed missing the class. I have corrected the post by adding it in. Thanks for letting me know.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.