Create iPhone-style buttons with the iButton jQuery Plug-in

Categories: jQuery

At work we just released another jQuery plug-in called the iButton jQuery Plug-in (which brings the total of open source jQuery plug-ins we've released to four.) This plug-in allows you to generate iPhone-style buttons from checkbox and radio elements. While there are several libraries out there that generated iPhone-style buttons, we couldn't find one that did everything we needed, so I wrote one!

The users of our application are very keyboard centric, so it was very important that we supported keyboard entry. Keyboard support often seems to be overlooked in most UI plug-ins—developers get so focused on the mouse interaction, they forget completely about keyboard entry. So we always make keyboard support a key feature in the jQuery plug-ins we write.

Anyway, here's a list of the key features:

  • Works with checkboxes or radio elements
  • Full keyboard support — use the [TAB] key to move from field to field and use the spacebar to toggle the status of the iButton (or use the arrow keys for radio buttons)
  • Custom event handlers
  • Detach iButton behavior from the element
  • Metadata support — when used with the jQuery Metadata Plug-in, you can define the properties for your button completely within the class attribute of your input elements
  • Enable/disable drag support — while the dragging behavior is intuitive on touch-based devices, it's not always be the best or expected UI behavior and may cause some mouse users problems (NOTE: In order to help differentiate between an intended mouse click or an actual drag event, we're developed the clickOffset option. If the time (in milliseconds) is under this value (120ms by default) it's assumed the user was attempting to click the button and not drag the handle.)
  • Enable/disable animation
  • Single sprite image — easily change the look of your button by just replacing the image sprite
  • Customizable labels — use any labels you want for your buttons
  • Support for disabled buttons
  • Easing support for animations
  • iPhone support

You can see a demo of the plug-in on the Giva Labs - iButton Example Page.

We're pretty happy with the end result and are planning on using it in a few locations in our application. If you like plug-in, don't forget to Digg it!

Comments

Bat's Gravatar Thanks a lot for this great plugin.
But there a lot of problems with Twitter Bootstrap :(
I think stylesheet is not enough robust...
Dan G. Switzer, II's Gravatar @Bat:

Since this was released long before Twitter Bootstrap came out, feel free to contribute any CSS changes that fix the problem w/bootstrap and I'll look at adding them to the default stylesheet.
Gerrit's Gravatar Hi Dan,

I just wanted to let you know that there seems to be a bug with this plug-in, and I was unsure where to post it. Maybe you could mention it at work.

If you use a google map on the same page as the iButton plugin, the marker drag-n-drop function is messed up. You can pick up the marker,, but you can't drop it anymore. If you drop it without moving it, it will work, but as soon as you would want to move the marker, it will not drop anymore.

So it seems the plug-in messes with the markers of google maps.
Dan G. Switzer, II's Gravatar @Gerrit:

I wouldn't think anything in the plug-in would be problematic. I'd check your markup to make sure there isn't something askew. Besides, doesn't the Google Maps stuff run w/in an iframe? That should isolate everything completely from any other plug-ins.
Dara's Gravatar Hi, Great plug-in and well-documented, thanks a lot!

I'm also having problems with Twitter Bootstrap - the Bootstrap CSS causes the button text to display askew. Have you encountered a fix for this?
Dan G. Switzer, II's Gravatar @Dara:

The button formatting is all CSS-based. All you need to do is use a CSS inspector to figure out what properties are being inherited by bootstrap and overwrite them in your CSS.
Dino's Gravatar Hi Dan,

Thank you for your nice plugin but i have a problem when run it on Chrome on Android OS. After i initial iButton all input field cannot focus and all onclick function of javascript cannot run.

Please help me check this issue.

Thanks,
Dino
Dan G. Switzer, II's Gravatar @Dino:

Unfortunately, I do not have an Android-based device to test against. Somebody did report a similar issue on iOS, so you can try the following path:

--- a/lib/jquery.ibutton.js    Mon Nov 12 12:55:34 2012 -0600
+++ b/lib/jquery.ibutton.js    Mon Nov 12 12:55:40 2012 -0600
@@ -254,7 +254,7 @@
  
        // monitor when the mouse button is released
        $(document).bind("mouseup.iButton_" + id + "
touchend.iButton_" + id, function(e) {
-            if( mouse.clicked != $handle ){ return false }
+            if( mouse.clicked != $handle ){ return }
            e.preventDefault();

            // track if the value has changed
Dino's Gravatar Thank you,
I resolved it with your suggestion but i don't know why you using "return false" without "return;"
Léo's Gravatar I encountered a little bug, in case of a checkbox inside a <label></label>, the button don't switch state with a single click, it needs to be dragged. There is a simple solution for this?

Congrats for the excellent plugin.
Coz's Gravatar Not asking for help lol just wanted to say thanks for this plugin, certainly brings style to my site and it works great! :)
Max's Gravatar Great work!

However, the keyboard TAB doesn't seem to work with safari. Chrome = OK
Luther's Gravatar Hi Dan. Thanks for the great plugin. I was running into a strange problem where my toggles worked just fine on a desktop browser but not iOS. For some reason, after the toggle was initialized, the jQuery click events on my SVG graphic were no longer firing. I troubleshooted for several hours and was about to give up. But, then I stumbled upon the recommendation you gave Dino above. For whatever reason, changing that one line of code saved me. Great! Thanks again.
Adam's Gravatar Hi Dan,

Nice plugin but I am strugling to get something to work.
I would like to add a confirmation box where the user could cancel the action. This means that I nead to abort the click event.

Any idea's on how to do this?

I am using the "change" event now.

Thanks in advance!
sakeferret's Gravatar looks like it breaks with jquery 1.9.1 . any fixes in the works? Otherwise, great plugin!
Dan G. Switzer, II's Gravatar @sakeferret:

You'll probably need to load the jQuery Migrate plug-in w/jQuery 1.9.x--which preserves backwards compatibility for depreciated methods. jQuery has depreciated some of the API methods that this plug-in was built around.
Dan G. Switzer, II's Gravatar @Adam:

Since you're most likely handling things in an async manor w/the modal, you wouldn't be able to "cancel" the click even if the API supported it (which it doesn't.)

Instead, you just need to use the "change" event to trigger off the modal and then based upon their response decide whether or not to undo the change. You can use $("#id").iButton("toggle", value) to set the value of the button or just call $("#id").iButton("repaint") to have it repaint based upon the new form values.
Adam's Gravatar @Dan:

Thanks for the feedback.
Using the toggle function does not work in the "change" event, because it will call the function again ending up in an endless recursive function call.

I was thinking on using the "click" event and then to decide to toggle the button (this way the click event will not be triggered).
The problem with this is that I can not figure out on how to retrieve the element ID.
I have multiple buttons which are using the same event handler.

Thanks

Adam
Jacek's Gravatar The plugin is wonderful, really works fine. Do you plan to make it work with newest jquery 1.9.x / 2.x?

This would be great.
inshan2@hotmail.com's Gravatar Hi, I cannot get the labelon and labeloff to work with something else other than "ON" and "OFF". Is anyone having this problem?
Jacek's Gravatar In order to make it work with newest query 1.9.x / 2.x - you need to:
1) get rid of all $.browser - 2 occurrences
2) replace attr("checked" - with prop("checked" - 3 occurrences
Jacek's Gravatar Additionally - if you would like to use this with Bootstrap (http://http://twitter.github.io/bootstrap/) following changes needs to be made in jquery.ibutton.css:

- find the line with .ibutton-container label { ... } definition
- in it add below 3 lines:
  display: inline;
  font-weight: 700;
  line-height: 17px;
jens's Gravatar Hi,

very nice plugin. Thanks.

My problem is, that I need the id of the original element to set a value depending on the buttonstate for later SQL Queries. But $(this).id or this.id does not work.

My approach:
  $(".checkbox").iButton(
        
      {

   labelOn: "Yes",
   labelOff: "No", 
   change: function ($input){
    
     if ($input.is(":checked") )
     {
$(#selector).val("10"); //here i want set the value of the element
     }
else
{
$(#selector).val("20"); //here i want set the value of the element
}
     },
   disable:function()
   {
$(#selector).val("30"); //here i want set the value of the element
   } 
        });
Dan G. Switzer, II's Gravatar @jens:

The $input element in your change event example should be a reference to the original form field.
jens's Gravatar Hi Dan,

thanks for this nice tool.
My problem: If I want to load the ibutton into a div, which is set to "display none". the iButton shrinks to a minimum. Same problem, if i destroy and reinit the button in a div, which is hidden.

Do you have a workaround or solution
Thanks again

Jens
Dan G. Switzer, II's Gravatar @Jens:

Have you tried waiting to initialize the plugin until you show the parent div? I suspect the problem is it can't calculate it's width/height correctly unless the element is visible, so just delay the initialization until you actually need to see it.

Another thing you could do is instead of setting the display: none, is make the element positioned absolute and give it a negative top/left so the element is rendered offscreen. Then when you want to show it, just make sure it's statically positioned (you can obviously do this w/CSS classes.)

Add Comment

Leave this field empty


If you subscribe, any new posts to this thread will be sent to your email address.