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

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!


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
August 20th, 2009 at 11:27 amAmit 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.
October 23rd, 2009 at 4:23 amr4 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?
November 6th, 2009 at 5:29 amWill Says:
Hey,
November 6th, 2009 at 9:36 amI’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
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
January 28th, 2010 at 3:57 pmSigfrid Says:
Hello guys,
February 10th, 2010 at 3:08 amyou 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.
Will Says:
Hi Sigfrid,
February 10th, 2010 at 9:46 amYou 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
mas iQ Says:
please I can not make itoggle sample to work,
February 12th, 2010 at 12:27 amis there any zip file contains of working html version ?
Will Says:
Hi Mas,
February 12th, 2010 at 9:48 amIf you right click > view source on the labs page there is a working version.
Cheers,
Will
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,
March 1st, 2010 at 11:29 amMarc
Hasan Gürsoy Says:
You should write better documentation.
March 8th, 2010 at 9:25 amWill Says:
Hi Hasan Gürsoy,
March 8th, 2010 at 9:38 amI’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
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
April 6th, 2010 at 12:17 amthanks
K Says:
Yeah… this simply doesn’t work.
May 1st, 2010 at 4:01 pmnoah Says:
Cant get it to work on all checkboxes on a page
May 6th, 2010 at 6:12 pmaNj 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);
May 21st, 2010 at 11:30 ampearls Says:
Nice post. I will bookmark it.
May 29th, 2010 at 7:56 amEz Says:
Your download code doesnt match up with the tutorial…
I cant get it to work.
great idea though
June 19th, 2010 at 1:25 ammark 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 ?
June 20th, 2010 at 7:54 amDave 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
July 30th, 2010 at 1:56 pmWilliam 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.
August 12th, 2010 at 6:22 amtimmi Says:
Also can’t get it to work, anything I try, the png is not shown. :<
August 30th, 2010 at 6:52 amtimmi 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!
August 30th, 2010 at 2:03 pmKayasax Says:
Hi,
September 2nd, 2010 at 1:17 pmnice stuff, thank you, is there any chance to make this script work on IE6 ?
Thanks
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
November 18th, 2010 at 6:07 pmPeter 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!
December 7th, 2010 at 9:44 pmMikael 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?
December 20th, 2010 at 12:45 pmJoost 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.
December 31st, 2010 at 1:50 pmLine: 156
Char: 295
Code: 0
URI: http://localhost/test/jquery-1.4.4.min.js
Uzair Says:
Not working on jquery 1.4.4 in ie8. Getting same error as Joost.
January 5th, 2011 at 10:19 pmJason 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
March 24th, 2011 at 8:58 pmDr. 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.
May 5th, 2011 at 2:47 pmIlia Lobsanov Says:
I’ve pushed the simplest example to github at https://github.com/nurey/toggle
May 18th, 2011 at 4:16 pmAlso fixed the javascript to make it work with jQuery 1.6.1
alejandro Says:
hi, everything works ok,, but cant get the easing animation working…. what can be wrong?
June 8th, 2011 at 11:50 amRob Says:
@alejandro Try adding the following plugin http://plugins.jquery.com/project/backgroundPosition-Effect
June 10th, 2011 at 1:37 pmAarto Says:
hey, good job!
June 14th, 2011 at 11:13 amI suggest you redo your code with the design of the toggle ios5 I just finished. I can send you files if you wish!
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.
July 21st, 2011 at 2:01 amWill 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
July 21st, 2011 at 8:39 amTai 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.
July 21st, 2011 at 8:46 amJilbo 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”);
}
July 27th, 2011 at 9:04 pmJilbo 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”);
}
July 27th, 2011 at 9:06 pmJilbo Says:
Part 1
July 27th, 2011 at 9:07 pmJilbo Says:
The quotes are for the html to show up on this forum.
”
“
July 27th, 2011 at 9:08 pmJilbo Says:
\
\
July 27th, 2011 at 9:09 pmJilbo Says:
html>
head>
link rel=”stylesheet” type=”text/css” href=”engage.itoggle.css”/>
July 27th, 2011 at 9:10 pmscript type=”text/javascript” src=”jquery.js”>/script>
script type=”text/javascript” src=”easing.js”>/script>
script type=”text/javascript” src=”engage.itoggle.js”>/script>
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>
July 27th, 2011 at 9:13 pm/html>
evan Says:
Does not work with jQuery 1.6.2 Any ideas?
August 17th, 2011 at 3:17 pmNathan 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
September 8th, 2011 at 9:24 pmAdrien 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
September 19th, 2011 at 3:41 pmAndras 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.
October 14th, 2011 at 6:01 pmAlso if($this.attr(‘tagName’) == ‘INPUT’) should be changed to if($this.prop(‘tagName’) == ‘INPUT’)
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
December 22nd, 2011 at 1:28 pmEnes Says:
This thing does not work for latest versions of jQuery! Author should update it immadiately…
December 30th, 2011 at 12:13 amJangla 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.
December 30th, 2011 at 2:59 pm