3 Value Checkbox with JQuery

Few days ago I did that whole 3-value checkbox thing basing it on some script I found online. I went back and I re-implemented it using some JQuery magic. I’m not going to reiterate the whole setup here. I recommend that you check the linked post for details. You can find the JQuery-fied code below:

   checked = '/path/to/checked.jpg';
   unchecked = '/path/to/unchecked.jpg';
   na = '/path/to/na.jpg';
   i = 0;
   // replace the checkboxes with images    
   $("form.funky_form > fieldset.funky_set :checkbox.funky_box").hide().each(function() {
      img = document.createElement('img');
      img.className = "funky_image";
         case "0":
            img.src = unchecked;
            $(this).attr("checked", "false");
         case "1":
            img.src = checked;
            $(this).attr("checked", "true");
         case "2":
            img.src = na;
            $(this).attr("checked", "true");
      // these will let us identify which image was clicked
      // and which checkbox does it belong to
      $(this).attr("id", "input" + i + "image" + i);
      $(img).attr("id", "" + i + "image" + i);
   // add onClick functionality to the new images
   $(".funky_image").click(function() {
      // select the checkbox corresponding to the clicked img
      t = $("#input" + $(this).attr("id"));
         case "0":
            $(this).attr("src", na);
            t.val(2).attr("checked", "true");
         case "1":
            $(this).attr("src", unchecked);
         case "2":
            $(this).attr("src", checked);

The major difference from the other version is that I’m much more discerning in which checkboxes get converted. The code will select only a box that is of the class funky_box and is inside a fieldset with a class of funky_set and inside a form with a class of funky_form. I’m mostly doing that to show power of JQuery – this is all specified in that very first select statement. I was trying to do something similar in the old code, but I was getting hung up on the silly DOM gotchas. JQuery makes this easy.

Also note the chaining functions. The first line after I declere i both hides all the selected check-boxes and begins the each block. Similarly, check out the second switch statement. In several places I set the value of t and change the checked attribute on the same time. It’s very expressive, and lends itself toward very compact and concise code.

Here is the HTML for the form to go with the code above (note the inclusion of the fieldset tag):

<form name="funky_form" method="POST">
      <fieldset class='funky_set'>
         <label for="c1">
            <input type="checkbox" name="c1" value="1" class="funky_box" checked>
            Some Important Task
         <label for="c2">
            <input type="checkbox" name="c2" value="1" class="funky_box" checked>
            Some Important Task #2
      <label for="c3">
         <input type="checkbox" name="c3" value="1" class="funky_box" checked>
         This is a checkbox with the funky_box class outside the funky_set
   <input type="submit" value="Submit">

How readable is this version? To me it is actually better because it’s smaller, and more compact. To someone who never worked with JQuery it might be a bit confusing at first but I think you get used to the weirdness pretty quickly. I find the selection statements much more elegant than nested loops for example, even if they might The more code I can see on my screen the better. I’m not golfing though – all the methods and most variables have meaningful names (well, except stuff like t and i but you know how it goes).

Which version do you like better?

[tags]javascript, check-box, 3 state check box, web design, html, scripting[/tags]

This entry was posted in programming and tagged , . Bookmark the permalink.

5 Responses to 3 Value Checkbox with JQuery

  1. jambarama UNITED STATES K-Meleon Windows Terminalist says:

    The second version is more readable. I’ve been finding compactness is more and more relevant to readability than I ever thought. That thought has reduced my commenting by a large amount. When I’m reading someone else’s code (which is most of the time I’m reading code now) and I want to see a function – scrolling, and searching is the worst way. I just want to read it through like a book, and the more of the code I can see at once, the faster I can read it. There is a lot to say about code modularity, but if I’m wasting time hunting down a 5 line function, I’m going to be mad.

    Excellent work. If I had written both iterations, I’d be awfully proud of the second block.

    Reply  |  Quote
  2. Luke Maciak UNITED STATES Mozilla Firefox Ubuntu Linux Terminalist says:

    [quote post=”2353″]There is a lot to say about code modularity, but if I’m wasting time hunting down a 5 line function, I’m going to be mad.[/quote]

    Heh, been there, done that. Bonus points if it’s a global function called a() which gets overloaded in 7 different places, and the real function is buried under many levels of dependencies (ie. A imports B which imports C and etc – and a() is conveniently located in Z on the bottom of this linked list).

    Spaghetti code FTW. :mrgreen:

    Reply  |  Quote
  3. linoj UNITED STATES Safari Mac OS says:

    I think it’d be more correct when js is disabled it degrades to radio buttons so the 3 states are still available. Thus the html starts out as radio buttons, the js rewrites it into the multistate checkbox.

    Reply  |  Quote
  4. Brian UZBEKISTAN Mozilla Firefox Windows says:

    Thanks for the post Luke.

    I would also like to share my experience with using .change() for checkboxes in IE. I think it’s better to use .click() for checkboxes and jquery. Cuz .change() seems to be having problems in IE6 & IE7!!!

    Hope this tip will save you guys time…

    Reply  |  Quote
  5. Ryan SINGAPORE Safari Mac OS says:

    I’ve been unable to get your code to work. Would really appreciate it if you could whip up a quick demo page. Thanks!

    Reply  |  Quote

Leave a Reply

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