Thursday 27 September 2012

jQuery.showWhen

I've created a small jQuery plugin to allow for more responsive forms. Sometimes you only want to show parts of a form when other parts are complete. This helps you simplify forms and only go into detail when the user has already filled in some field. Here is an example, and an example with a checkbox instead
Think about a survey:
  1. Do you smoke?
    1. Yes
    2. No (skip to 4.)
  2. How often do you smoke?
    1. Every hour
    2. Every two hours
  3. Do you realize ...
    1. Not really
  4. Is question four a question?
    1. Yes
    2. No
In this survey, we could have tried to follow the standard of interactive and intuitive forms to hide questions number 3. and 4.
This could be done in a non-obstrusive way: If the "(skip to 4.)" text was inside its own span with its own CSS class, it would be trivial to add data-skip-questions to that span, and have jQuery look for span[data-skip-questions], and use String.split with jQuery.add to register with this plugin.
html code:
<ol class="questions">
    <li>Do you smoke?
        <ol>
            <li><input type="radio" name="q1" value="y" />Yes</li>
            <li><input type="radio" name="q1" value="n" />No <span data-skip-questions="2 3">(skip to 4.)</span></li>
        </ol>
    </li>
    <li>How often do you smoke?
        <ol>
            <li><input type="radio" name="q2" value="1" /> Every hour</li>
            <li><input type="radio" name="q2" value="2" /> Every two hours</li>
        </ol>
    </li>
    <li>Do you realize ...
        <ol>
            <li><input type="radio" name="q3" value="n" /> Not really...</li>
        </ol>
    </li>
    <li>Is question four a question?
        <ol>
            <li><input type="radio" name="q4" value="y" /> Yes</li>
            <li><input type="radio" name="q4" value="n" /> No</li>
        </ol>
    </li>
</ol>
javascript code:
$('span[data-skip-questions]').each(function() {
    var questionsToSkip = $(this).data('skip-questions').split(' '),
        q = $(null),
        watchedInput = $(this).parents('li:first').find('input[type="radio"]');

    $.each(questionsToSkip, function(i, val) {
        q = q.add($('ol.questions > li')
              .eq(val - 1));
    });

    $(q).hide().showWhen(watchedInput, true);

})
// Hide the span, since the user doesn't have to skip the questions snymore.
.hide();
Here's a fiddle for the survey example.

Edit:
The plugin is now on github. It was released under the WTFPL. Feel free to fork and use!

No comments:

Post a Comment