Filtering with JavaScript’s onhashchange Event

I recently discovered a very neat way of using JavaScript to filter which records are shown on a page.

Filtering with JavaScript’s onhashchange Event – Example (opens in new window)

For a long time I’ve been using links to trigger JavaScript functionality, using them like buttons. The problem with this has always been what to put in the href attribute. There are basically 2 choices:

  1. Use”#” or any meaningless bit of text and then prevent the default behaviour on click so that the URL doesn’t change. I’ve generally used “#” and then event.preventDefault() in my JavaScript.
  2. Leave out the href attribute. This causes some behaviour changes in browsers, such as not changing the cursor to a pointer on hover but these things can be overridden with CSS.

There’s a better way. Rather than prevent the link from doing its natural job of navigating to a new URL, we can allow it to navigate to an anchor point, e.g. #male, and then get our JavaScript to detect any changes in the text after the #, the hash value.

This method has a lot of good things going for it:

  • The links are used rather than hacked around, which feels better.
  • We have a URL which goes directly to the filter state.
  • We can use the browser’s Back button to return to the previous filter state.

Here’s how the code in the example fits together.

Firstly in our HTML, we point our filter links at appropriate hash values, e.g. #male, #female. In the table data we need a way of identifying the male/female rows so we used classes.

<a href="#male">Male</a>
<tr class="male">...</tr>

In the JavaScript, we create variables for our different filters:

var all = document.getElementsByTagName('tbody')[0].getElementsByTagName('tr'),
    males = document.getElementsByClassName('male'),
    females = document.getElementsByClassName('female');

In this example I’ve created show() and hide() functions to apply to matched or unmatched rows but if you’re using jQuery you could simply do $(‘tr.male’).show().

The actual filtering happens in our filter() function:

function filter() {
    switch (window.location.hash) {
        case "#male":
        case "#female":

The hash value is read in using window.location.hash. The switch statement finds which filter we want applied and modifies the DOM accordingly. The “all” option which is the same as no filter being applied is the default.

Finally, we call the filter() function whenever the hash value changes, onhashchange, and when the page initially loads in case it comes with a filter already applied:

window.onload = filter;
window.onhashchange = filter;

Filtering with JavaScript’s onhashchange Event – Example (opens in new window)

This could be extended further for use with multiple filters by using a comma separated list after the # and checking for each within the filter function.

Posted in JavaScript, onhashchange | Comments Off

ADVERT – Premium Domain Names For Sale!

The following domains are currently available for purchase or lease:

Please contact @chris22smith on twitter if interested.

Posted in Adverts | Tagged , , , , , , , , , , , , , | Comments Off

Checking a Checkbox inside a List Item by Clicking the Parent or Child

It’s quite common to see list items <li> or table rows <tr><td> which contain a checkbox <input type=”checkbox”/>. Rather than the user having to be very precise and click/touch on the checkbox, it’s often preferable, especially on mobile devices, to be able to click/touch anywhere in the item or row.

This sounds simple but throws up a problem. If we have click events on the item/row and the checkbox then a click on the checkbox fires both events, checking and then unchecking the checkbox. Setting e.stopPropagation on the checkbox click event doesn’t seem to work.

There are 2 solutions. The first is arguably simpler and more semantic. Simply wrap the checkbox in a <label> tag and then change the label’s CSS so that it fills the list item or row.

If this isn’t an option then it can be handled in JavaScript.

See the Pen Checking Checkboxes by Clicking Parent List Item by Chris Smith (@chris22smith) on CodePen

The refers to the element that was clicked. If, within the list item click, the checkbox is not clicked then change the checked state.

Posted in click(), JavaScript, jQuery | Tagged , , , , , , , , , | 1 Comment