From the lab: iToggle for jQuery
…written by Will and has 52 comments so far

itoggle

For a little challenge the other day we decided to see how closely we could re-create the iPhone’s toggle switches on the web. Into the labs we went, and the result was a brand new plugin!

Using just one image, some simple CSS, almost no HTML and a compact bit of Javascript (3kb) we’ve forged this little plugin to replace those boring checkboxes and radio buttons with something far more fancy looking!

With the help of jQuery this plugin will replace any checkbox or radio element you want with this sliding alternative.

Head over to the labs page for an in depth explanation and links to download the files, including a PSD template. Questions or examples of iToggle in action? let us know below!

Labs link button

Have your say
  1. Petoz Says:

    hi I download it and make some try but don’t work on “onclick” or better, the value don’t change.
    any hints or example to use it like a input button ?
    many thanks in advance

    Petoz

  2. Amit Singh Says:

    Excellent peice of work!!! I was just wondering if you had any hints on how to make it work within a gridview? I can’t seem to get the image to render. The gridview is bound on the pageload, however I don’t think that should be a problem.

    The checkbox works perfectly outside the gridview. Any tips would be much appreciated.

  3. r4 Says:

    The source of the plugin has this in the header:

    jQuery Last.Fm Plugin by Engage Interactive

    You might want to change that to … well, “iToggle” or something, eh?

  4. Will Says:

    Hey,
    I’ve had a look through the zip and the actual files on the site, but I can’t find that anywhere… Not to worry though, I’m sure people can figure it out :p
    Thanks though,
    Will

  5. Sven Says:

    Hello

    I have question

    I try your code and it’s works fine except i cant get to change value of checkbox or radio

    i try to place some code into onclick but without success

    anyone figure this out

    any working sample will be nice

  6. Sigfrid Says:

    Hello guys,
    you should specify in the documentation that everything must be inside a div with itoggle as id otherwise it doesn’t work. I spent almost 1 hour to figure it out.

  7. Will Says:

    Hi Sigfrid,
    You don’t actually have to, that’s just the example I used. You can target any containing div using the jQuery selector engine. For example: #form_1 div.iToggle would work, as would: #form_2 div.i_toggle
    Will

  8. mas iQ Says:

    please I can not make itoggle sample to work,
    is there any zip file contains of working html version ?

  9. Will Says:

    Hi Mas,
    If you right click > view source on the labs page there is a working version.
    Cheers,
    Will

  10. Marc Says:

    Hi,

    I’ve got the same question as Sven, how do you change the setting of the checkbox/radiobutton dynamically from javascript?
    I’ve tried removing the “checked” attribute, but it doesn’t change what’s checked. E.g:

    jQuery(“#itoggle #example_1″).removeAttr(“checked”);
    or
    jQuery(“#example_1″).removeAttr(“checked”);

    Also tried sending a click and mousedown event, but that didn’t trigger it either (nor is any of the iToggle callbacks invoked).

    Cheers,
    Marc

  11. Hasan Gürsoy Says:

    You should write better documentation.

  12. Will Says:

    Hi Hasan Gürsoy,
    I’m sorry if you feel that there isn’t enough documentation, but we use our labs area to put ideas down and share bits of code that we’ve created while working on other projects. They are aimed more at people who have prior knowledge of the subject – in this case jQuery. We simply don’t have time to sit down and write in-depth documentation for people who don’t.
    As with the last.fm plugin we hope that people from the web will take interest and advance the plugin themselves, writing proper documentation and making improvements along the way.
    Thanks,
    Will

  13. Anderson Soares Says:

    Hi. Good job guys. Im using itoggle and i have a question.

    How can i configure the size of image?

    I configured the image itoggle.png to 50% of original
    ok
    In this case, wich value should i put on width(93px is original) and height(27px is original) ?

    sorry, my english is no good
    thanks

  14. K Says:

    Yeah… this simply doesn’t work.

  15. noah Says:

    Cant get it to work on all checkboxes on a page

  16. aNj Says:

    Nice work!

    It works good, but now i want to access your function “slide”. My situation is that the checkbox is used to show elements from a grid, so i want to change the checked status of the checkbox with a call. But howto? I cannot access the “slide” function directly or am i wrong?

    Anotherone is, maybe you can extend your options with the “scope”:

    var defaults = {
    scope: this,
    [...]
    },

    and then call every function like this:

    settings.onClickOff.call(settings.scope, $object);

  17. pearls Says:

    Nice post. I will bookmark it.

  18. Ez Says:

    Your download code doesnt match up with the tutorial…
    I cant get it to work.

    great idea though

  19. mark Says:

    Do you have a ZipFile that has all the files including the index.html with the correct coding for newbies? basically download and the sample just works ?

  20. Dave Says:

    Hi does anyone now a global way of setting itoggle for the whole page instead of using and id use an .each() command or somthing i need this becauce of so many itoggles on my page that the js file is growing fast

  21. William Says:

    You amazing iToggle code doesn’t seem to play nice with the http://ajax.googleapis.com/ajax/libs/prototype/1.6.1/prototype.js library. Any idea why? Thank you.

  22. timmi Says:

    Also can’t get it to work, anything I try, the png is not shown. :<

  23. timmi Says:

    okay, it’s working now. had to surround a div with an id called “itoggle” around the html stuff, otherwise the ready function code doesn’t match.

    how can i make this button smaller? created a new png with 50% in size and changed the following within the css file but this looks a bit strange:

    #itoggle label.itoggle span{
    display: block;
    width: 93px; -> 47px
    height: 27px; -> 13px
    margin-bottom: 20px;
    background: url(itoggle.png) left bottom no-repeat;
    cursor:pointer;
    text-indent:-5000px;
    }

    thanks!

  24. Kayasax Says:

    Hi,
    nice stuff, thank you, is there any chance to make this script work on IE6 ?
    Thanks

  25. Vinny Says:

    Your code will not alter the state of the toggle switch if the input is focused by Tabbing through the form elements and selected by hitting the space bar. The following code fixes that (I added a function variable to slide():

    $(‘input.iT_checkbox’).keypress(function(event) {
    if(event.which == 32) {
    if(clickEnabled == true){
    clickEnabled = false;
    slide($(this).prev(‘label.itoggle’),false,true);
    }
    }
    return true;
    });

    function slide($object, radio, keypress){
    settings.onClick.call($object); //Generic click callback for click at any state
    h=$object.innerHeight();
    t=$object.attr(‘for’);
    if($object.hasClass(‘iTon’)){
    settings.onClickOff.call($object); //Click that turns the toggle to off position
    $object.animate({backgroundPosition:’100% -’+h+’px’}, settings.speed, settings.easing, function(){
    $object.removeClass(‘iTon’).addClass(‘iToff’);
    clickEnabled = true;
    settings.onSlide.call(this); //Generic callback after the slide has finnished
    settings.onSlideOff.call(this); //Callback after the slide turns the toggle off
    });
    if(keypress != true) {
    $(‘input#’+t).removeAttr(‘checked’);
    }
    }else{
    settings.onClickOn.call($object);
    $object.animate({backgroundPosition:’0% -’+h+’px’}, settings.speed, settings.easing, function(){
    $object.removeClass(‘iToff’).addClass(‘iTon’);
    clickEnabled = true;
    settings.onSlide.call(this); //Generic callback after the slide has finnished
    settings.onSlideOn.call(this); //Callback after the slide turns the toggle on
    });
    if(keypress != true) {
    $(‘input#’+t).attr(‘checked’,'checked’);
    }
    }
    if(radio == true){
    name = $(‘#’+t).attr(‘name’);
    slide($object.siblings(‘label[for]‘));
    }
    }

    Note that it must return ‘true’ otherwise it won’t work in Firefox.

    Hope that helps someone

  26. Peter Ripley Says:

    Very nice Will. Thanks for this.

    For the person who enquired about IE6. I use “IE collection” for IE testing. They provide 2 version of IE6:

    IE 6.0 (6.00.2800.1106)
    IE 6.0 (6.00.2900.2180)

    I believe the former is IE 6 SP 1 released in 2002, and the latter is IE 6 SP 2, released in 2004.

    In my testing I was able to get Engage’s itoggle to work in the latter one by using a GIF instead of a PNG for the toggle sprite.

    I did this in a separate IE 6 stylesheet so the rest of the world gets the PNG which has nicer corners than the GIF I created.

    I am not sure of the prevalence of these two versions in the wild. On my site IE6 is down to less than 5% of total visits. I am going to tell folks that the SP1 version is vanishingly small, less than 1%. We are talking about folks who haven’t upgraded since 2003!

  27. Mikael Says:

    It seems that your plugin has a problem with the latest jquery version: 1.4.4. in IE. When clicking the toggle element the script breaks in IE, throwing the following error:

    Invalid argument on line 6775 in the uncompressed version.

    Have anyone any idea how to fix this?

  28. Joost Says:

    Issue with jQuery 1.4.4 confirmed. It does not work
    Details
    ===================================================
    Error message
    Webpage error details

    User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; FDM; Tablet PC 2.0; .NET4.0C; .NET4.0E)
    Timestamp: Fri, 31 Dec 2010 13:49:52 UTC

    Message: Invalid argument.
    Line: 156
    Char: 295
    Code: 0
    URI: http://localhost/test/jquery-1.4.4.min.js

  29. Uzair Says:

    Not working on jquery 1.4.4 in ie8. Getting same error as Joost.

  30. Jason Says:

    Wondering how to get this to work when I have multiple rows with a checkbox but I need to know which one cause the click and get the value attribute to do a ajax call.

    Thanks, Jason

  31. Dr. Dre Says:

    To fix IE 7 – 8 bug

    remove
    $object.animate({backgroundPosition:’0% -’+h+’px’}, settings.speed, settings.easing, function(){

    from the JS file. That is what is throwing the error.

  32. Ilia Lobsanov Says:

    I’ve pushed the simplest example to github at https://github.com/nurey/toggle
    Also fixed the javascript to make it work with jQuery 1.6.1

  33. alejandro Says:

    hi, everything works ok,, but cant get the easing animation working…. what can be wrong?

  34. Rob Says:

    @alejandro Try adding the following plugin http://plugins.jquery.com/project/backgroundPosition-Effect

  35. Aarto Says:

    hey, good job!
    I suggest you redo your code with the design of the toggle ios5 I just finished. I can send you files if you wish!

  36. Tai Nguyen Says:

    You’re wrong when you say that “You don’t actually have to [surround the checkbox with a DIV of id "iToggle"], that’s just the example I used. You can target any containing div using the jQuery selector engine”

    In the CSS, you reference div#itoggle throughout and the styles will not apply unless you have this div or fix the CSS. Also, the label is actually hardcoded in the image, which is a pretty poor design IMO.

  37. Will Says:

    Hi Tai,

    You can change the CSS if you want. Or the Javascript. Or even the HTML and images. We provide the labs projects for people so that they can customise and improve our code to suit their own needs.

    Hope that’s ok for you.

    Will

  38. Tai Nguyen Says:

    @Will:

    Considering that it’s free code, of course it’s ok :)

    The directions given simply don’t match the code provided as is, that’s all. Customization is not an “option”, it’s a requirement in order for the code to work so I’m letting people know this.

  39. Jilbo Says:

    This Totally Worked. Awesome job. I was also able to create my own button design with adobe.
    Example of working code.

    $(document).ready(function() {
    // Start jQuery goodness
    $(‘#itoggle input#example_1′).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    $(‘#console’).show().css({opacity:0}).animate({opacity:1},400);
    statusUpdate(‘Console on’);
    $(‘input:checkbox’).addClass(‘iT_checkbox_on’);
    $(‘input:radio’).addClass(‘iT_checkbox_on’);
    },
    onClickOff: function(){
    statusUpdate(‘Console off’);
    $(‘#console’).animate({opacity:0},400);
    $(‘input:checkbox’).removeClass(‘iT_checkbox_on’);
    $(‘input:radio’).removeClass(‘iT_checkbox_on’);
    }
    });
    $(‘#itoggle #example_2′).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });
    $(‘#itoggle #photo’).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });

    $(‘#itoggle #example_3′).iToggle({
    easing: ‘easeOutExpo’,
    type: ‘radio’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });

    function statusUpdate(text){
    $(‘#console’).prepend(”+text+”);
    $(‘#console p:nth-child(1)’).css({color:’#0F0′});
    $(‘#console p:nth-child(2)’).css({color:’#0C0′});
    $(‘#console p:nth-child(3)’).css({color:’#090′});
    $(‘#console p:nth-child(4)’).css({color:’#090′});
    $(‘#console p:nth-child(5)’).css({color:’#060′});
    $(‘#console p:nth-child(6)’).css({color:’#030′});
    $(‘#console p:nth-child(7)’).remove();
    }

    // End jQuery goodness
    });
    function check()
    {
    alert(“yeah”);

    }

  40. Jilbo Says:

    Hold on that didn’t work. Here is full webpage test.

    $(document).ready(function() {
    // Start jQuery goodness
    $(‘#itoggle input#example_1′).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    $(‘#console’).show().css({opacity:0}).animate({opacity:1},400);
    statusUpdate(‘Console on’);
    $(‘input:checkbox’).addClass(‘iT_checkbox_on’);
    $(‘input:radio’).addClass(‘iT_checkbox_on’);
    },
    onClickOff: function(){
    statusUpdate(‘Console off’);
    $(‘#console’).animate({opacity:0},400);
    $(‘input:checkbox’).removeClass(‘iT_checkbox_on’);
    $(‘input:radio’).removeClass(‘iT_checkbox_on’);
    }
    });
    $(‘#itoggle #example_2′).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });
    $(‘#itoggle #photo’).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });

    $(‘#itoggle #example_3′).iToggle({
    easing: ‘easeOutExpo’,
    type: ‘radio’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });

    function statusUpdate(text){
    $(‘#console’).prepend(”+text+”);
    $(‘#console p:nth-child(1)’).css({color:’#0F0′});
    $(‘#console p:nth-child(2)’).css({color:’#0C0′});
    $(‘#console p:nth-child(3)’).css({color:’#090′});
    $(‘#console p:nth-child(4)’).css({color:’#090′});
    $(‘#console p:nth-child(5)’).css({color:’#060′});
    $(‘#console p:nth-child(6)’).css({color:’#030′});
    $(‘#console p:nth-child(7)’).remove();
    }

    // End jQuery goodness
    });
    function check()
    {
    alert(“yeah”);

    }

  41. Jilbo Says:

    Part 1

  42. Jilbo Says:

    The quotes are for the html to show up on this forum.

  43. Jilbo Says:

    \

    \

  44. Jilbo Says:

    html>
    head>

    link rel=”stylesheet” type=”text/css” href=”engage.itoggle.css”/>
    script type=”text/javascript” src=”jquery.js”>/script>
    script type=”text/javascript” src=”easing.js”>/script>
    script type=”text/javascript” src=”engage.itoggle.js”>/script>

  45. Jilbo Says:

    This is a complete test page all html has the less than sign removed to show up on this site.

    html>
    head>

    link rel=”stylesheet” type=”text/css” href=”engage.itoggle.css”/>
    script type=”text/javascript” src=”jquery.js”>/script>
    script type=”text/javascript” src=”easing.js”>/script>
    script type=”text/javascript” src=”engage.itoggle.js”>/script>
    script type=”text/javascript”>
    $(document).ready(function() {
    // Start jQuery goodness
    $(‘#itoggle input#example_1′).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    $(‘#console’).show().css({opacity:0}).animate({opacity:1},400);
    statusUpdate(‘Console on’);
    $(‘input:checkbox’).addClass(‘iT_checkbox_on’);
    $(‘input:radio’).addClass(‘iT_checkbox_on’);
    },
    onClickOff: function(){
    statusUpdate(‘Console off’);
    $(‘#console’).animate({opacity:0},400);
    $(‘input:checkbox’).removeClass(‘iT_checkbox_on’);
    $(‘input:radio’).removeClass(‘iT_checkbox_on’);
    }
    });
    $(‘#itoggle #example_2′).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });
    $(‘#itoggle #photo’).iToggle({
    easing: ‘easeOutExpo’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });

    $(‘#itoggle #example_3′).iToggle({
    easing: ‘easeOutExpo’,
    type: ‘radio’,
    onClickOn: function(){
    statusUpdate(‘Clicked on ‘+$(this).attr(‘for’));
    check();
    },
    onSlideOn: function(){
    statusUpdate(‘Slide on ‘+$(this).attr(‘for’));
    },
    onClickOff: function(){
    statusUpdate(‘Clicked off ‘+$(this).attr(‘for’));
    },
    onSlideOff: function(){
    statusUpdate(‘Slide off ‘+$(this).attr(‘for’));
    }
    });

    function statusUpdate(text){
    $(‘#console’).prepend(”+text+”);
    $(‘#console p:nth-child(1)’).css({color:’#0F0′});
    $(‘#console p:nth-child(2)’).css({color:’#0C0′});
    $(‘#console p:nth-child(3)’).css({color:’#090′});
    $(‘#console p:nth-child(4)’).css({color:’#090′});
    $(‘#console p:nth-child(5)’).css({color:’#060′});
    $(‘#console p:nth-child(6)’).css({color:’#030′});
    $(‘#console p:nth-child(7)’).remove();
    }

    // End jQuery goodness
    });
    function check()
    {
    alert(“yeah”);

    }
    /script>
    /head>
    body>

    div id=”itoggle” class=”project”>
    input type=”checkbox” id=”example_2″ onclick=”check()” />
    input type=”checkbox” id=”photo” ” />
    div>

    /body>
    /html>

  46. evan Says:

    Does not work with jQuery 1.6.2 Any ideas?

  47. Nathan Says:

    Looking to see if anyone has looked into updating the iToggle code for jQuery 1.6.2 support.

    I have some other plugins that require 1.6.2 to work and the itoggle function as nice as it looks does not work past 1.4.2 for me, so I have to turn it off for now.

    Thanks everyone,

    Nathan

  48. Adrien Says:

    You have to change this in the source code (engage.itoggle.js) :

    if ($this.get(0).tagName == ‘INPUT’)

    instead of

    if($this.attr(‘tagName’) == ‘INPUT’)

    Now it works for me

  49. Andras Says:

    Fro jquery 1.6 all occurrences of attr() should be changed to prop, it seems attr(“checked”) is not the same as it was in older versions of jquery.
    Also if($this.attr(‘tagName’) == ‘INPUT’) should be changed to if($this.prop(‘tagName’) == ‘INPUT’)

  50. Jangla Says:

    @Andras – that’s not quite true. attr(‘id’) will still work as before in jQuery. Prop is not a replacement for attr, it’s an additional tool

  51. Enes Says:

    This thing does not work for latest versions of jQuery! Author should update it immadiately…

  52. Jangla Says:

    @Enes – read the thread. There’s a solution posted which is super easy to follow and implement. Fixed mine in literally 5 seconds flat.

(Trackbacks / pingbacks)

Have your say