64 thoughts on “Zebra_TransForm, a tiny jQuery plugin for replacing checkboxes, radio buttons and select boxes

  1. phil

    Nice addon, but not really nessesary.

    Check out “http://uniformjs.com/” does the same, even supports file upload fields.

    1. Stefan Gabos Post author

      I know about Uniform but it doesn’t quite fit to my needs. My primary issue was that select boxes didn’t have padding in IE 6 and 7. Also, Uniform select boxes have the same width no matter what. Not to mention that I can’t alter the padding. Or the fact that the replacement doesn’t replicate the original select box’s font styles. Also, I wanted controls to be replaced no matter if they are floated, fixed, absolutely positioned, whatever margins or borders or whatever exotic CSS properties they may have applied to them.

      Anyways, it is always good to have a choice 🙂

    2. phil

      Ok, thats some valid points. (the selectbox width is with custom css code also possible, but if zebra does that automatically its great.)

      If you add file upload boxes i will use it 🙂 also text boxes and buttons would be great but not really needed.

    3. Stefan Gabos Post author

      i plan on replacing the file upload control in the next version. no plan on styling other controls though. i use this together with Zebra_Form which already does that.

  2. Alex

    There’s a small bug in the code. It doesn’t handle radio input with a “[” and “]” in the name – while having a radio that has a name of “field[]” isn’t likely to happen, in my case I need a few radios with the name “field[idvalue]” (where idvalue is a numeric ID.

    Anyway, there’s a quick fix. I just quickly patched my minified version to add single quotes around the jQuery selector “input:radio[name=”+s.attr(“name”)+”]” to make it “input:radio[name='”+s.attr(“name”)+”‘]”.

    In the source code this appears on line 347. An untested replacement is:

    $('input:radio[name="' + $element.attr('name') + '"]').each(function(index, control) {

    For some reason the quotes are the other way around (single most useful in minified version, double in source version) but it should work.

    1. Stefan Gabos Post author

      couldn’t reproduce the problem…
      i’ve tried all sorts of combinations like

    2. Alex

      Hmm, the specific code I’m using is like this:


          <input type="radio" name="choice[8]" id="choice-8-6" value="6"> 
          <label for="choice-8-6">Gold</label><br>
          <input type="radio" name="choice[8]" id="choice-8-7" value="7"> 
          <label for="choice-8-7">Chrome</label><br>
          <input type="radio" name="choice[9]" id="choice-9-10" value="10"> 
          <label for="choice-9-10">Brass</label><br>
          <input type="radio" name="choice[9]" id="choice-9-11" value="11"> 
          <label for="choice-9-11">Gold</label>


      // it's actually a little more complicated than this, but it's not the source of the bug that I can tell
      $.Zebra_TransForm($('input[type=checkbox], input[type=radio], select'));

      Maybe I didn’t make myself clear (in fact I know I didn’t). The plugin works, in that it transforms all controls, but the radios no longer act properly.

      So using the above HTML, the first two should be a radio group, allowing one option to be selected between the two, and the second two should be the same, thus the user can make two selections only in the whole snippet. But if you apply Zebra_TransForm to this (without my fix) then they all act as if they’re one group, allowing only one selection between the four radios.

      The issue, as I see it, is that your jQuery selector, when it eventually goes into the selector will turn from:

      $('input:radio[name=' + $element.attr('name') + ']').each(function(index, control) { ... });


      $('input:radio[name=choice[8]]').each(function(index, control) { ... });

      So as you can see, my “]” in “choice[8]” will end the CSS attribute selector, making the jQuery selector invalid and probably end up matching either all or none of the radios, and having the side-effect of making them all act as one grouping.

      When you apply my fix, the selector gets interpreted correctly as:

      $('input:radio[name="choice[8]"]').each(function(index, control) { ... });

      And jQuery appears to like it.

      For reference, here’s a Fiddle with the not-working version:

      And here’s one with my fix applied:

      Hopefully that clarifies things a bit. (Hopefully I’ve used the code blocks better this time, too. Although I don’t know the syntax to switch between JS and HTML)

    3. Stefan Gabos Post author

      I see now! That is some exotic approach! Can’t you just have the radios named “choice8” the first two and “choice9” the other two? I’ll try and make it work for these kinds of situations. I’ll keep you updated.

  3. Alex


    Yeah I could do that, but the proper way to do it (I’d say) is the way I’ve done it. These numbers in “choice[8]” and “choice[9]” refer to ids in a database that someone’s choosing something about. (Specifically the finishes they want on a certain thing, e.g. kitchen cupboard door handles, hence gold, chrome etc. in my example)

    As I said, the fix is really simple (and it works, I tested it and indeed am using it), just change line 347 so that the jQuery selector has quotes around the dynamic attr(‘name’) that you’re putting in.

    Otherwise, great plugin by the way. Works great and like you said above, it appears to work in many situations (floated, positioned, etc.) which is great for me as my pages are as complex as my choice of input names!

    A patch (created with `diff -u old.js new.js > fix.patch`, no idea if that’s the correct way to do it for actual patch applying) is uploaded at http://clevercherry.com/zebra/fix.patch if you wanted a patch.

  4. Alex

    Is there any way to update the already existing ZTs? I have a form that needs to show/hide a section based on something else, and as I hide the section its transformed floating checkboxes stay on the page.

    I’ve tried using the update method and passing in the original selector but it doesn’t appear to work.

    At the very worst is there an undo/detach thing so I can just re-add ZT?

    1. Alex

      Ahh, found a quick bodge around it – set the container of all ZT inputs you have to position: relative. It’s not idea but is (so far) a viable solution for me. Still, it’d be nice to have a “recalculatePositioningAndWhatNot” function on ZT.

  5. Michael

    In your Javascript demo code you have:


    You must have been in PHP mode still as was I. Should be:


    I end up getting “h.destroy is not a function”.

    1. Michael

      I’m new to jQuery (Mootools user…), but I changed the reference from destroy to remove. That appears to make it work correctly. Now when I call transform.update(), the select boxes resize.

    2. Alex

      A-ha, this may have been what was breaking for me above in my comment that says “I’ve tried using the update method and passing in the original selector but it doesn’t appear to work.” I just figured the “h.destroy is not a function” was something I did wrong.

      Oh well the bodge I found kinda works anyway.

  6. zvzz

    Hoi Stefan
    There are some performance issues when there are many of them controls on the page. In my case, 15 rows with 5 checkboxes on each would freeze up my PC for a few seconds every time the data grid opens with some fresh data – unacceptable for me, had to switch it off, but I loved your thing anyway. Thanks for the efforts !

  7. Jesse

    Hi Stefan. Thanks for this great tool! So far it works beautifully. This isn’t a make or break for me, but is there a way to add my own onClick event to the new checkboxes/buttons?

    1. Stefan Gabos Post author

      that’s a good point but it’s only possible by adding the onClick event manually to the new elements – which are always divs injected into the DOM right *after* the original elements – so you’ll have to find them first.

      but what you are asking makes a lot of sense and I’ll try and have a new version by the end of the week where the events of the original elements will be copied to the new element. the drawback is that only the events binded *before* calling Zebra_Transform will be copied…


    2. Stefan Gabos Post author

      you can now download the new version which should be what you are looking for. you have to attach the events to the original elements and prior to running the plugin and these will be also triggered by the replacement elements.

      let me know if it works.


    3. Jesse

      Wow, thanks so much for the amazing response time! This solved my problems! Keep up the great work.

  8. Chris

    Hi Stefan. Thanks so much for this great plugin. I’ve got a quick question… I’m trying to apply the transforms on a page where I’m dynamically removing and creating checkboxes based on a different selector. I’m having a problem with getting the dynamically created checkboxes to be transformed. Just calling $.Zebra_TransForm() again after creating the new elements doesn’t seem to do the trick. Any hints?

    1. Stefan Gabos Post author

      call the “update” method – see the last line in the examples on this page

  9. Chris

    I figured it out… I called the transform function on each dynamically created element at creation time, passing the jQuery object to the transform function.

  10. Chris

    Thanks again, Stefan, for this really useful plugin.

    I encountered a minor issue with the new event handler functionality, I think. In IE8/IE9 with a click or onchange event registered on a radio and select element with jQuery, the elements are not transformed and I get the error: “Object doesn’t support property or method ‘propertychange'” on line 187 – replacement[event_type]($.proxy(events[event_type][idx].handler, $element.get(0)));

    To fix it I changed line 177 from thisif(events) to if(events && (typeof events !== 'undefined'))
    I inserted braces around the if statement and inserted this line above line 187: if(event_type !== 'propertychange')

    This seems to have fixed my issues in IE8 & IE9 without breaking the latest versions of Firefox and Chrome. I’m new to jQuery so I could be breaking something by doing this but in my case it seems to work OK. I’m using jQuery 1.7.2, BTW.

    1. Stefan Gabos Post author

      Chris, I am unable to reproduce the error in Internet Explorer 8 nor 9. Can you email me your script that’s causing the bug?

  11. JoeBlack

    Your javascript is one of the better ones out there – tags function correctly.

    Can you extend it to include keyboard navigation – especially the TAB key?

  12. Axel Foley

    Hi There,

    This may be a silly question, as i’m no expert… but how can i disable the transform on a particular page. I am using a global replace on all select boxes across the whole site, but one particular page i dont want the transform to occur.

    My global script;

    How can I negate this?


    1. Stefan Gabos Post author

      you could add a class to the &ltbody> of that particular page, like “exception” and then, in JavaScript, do:

      if ($('body.exception').length == 0) 
  13. Kristoffer Kjelde

    Hey Stefan,
    If you have a different design than the normal checkbox, lets say my checkbox has to use a sprite image with height 32px and width 32px. You have to set the height and width on you input via CSS , othervise your placement calculation in linje 190 won’t work.


    1. Stefan Gabos Post author

      that is correct – if you alter the sprite and change the default sizes of the elements, you have to also alter the CSS

  14. John Elli

    Hi Stefan,

    I have a problem. I tried to use it and everything works fine but when I tried to click on my header checkbox on my gridview it will not check the other checkboxes. I have this function that when I select the header checkbox then all checkbox will automatically selected. I guess the ID of the header checkbox is transformed so javascript cant see it. Please help me on this I really want to use this plugin. Thanks

  15. Dino

    Hello Stefan
    Just send you some money, because this little peace of brilliant work is definately worth it. Tried a lot, but nothing was so easy to implement.
    Thank you very much!


Leave a Reply

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