There are lots of jQuery plugins out there regarding custom radio buttons and checkboxes, but for the life of me, I couldn't find a robust, simple, full-featured plugin. So, as usual, I went to work on a plugin of my own that would be easy to use, act as much like real input fields as possible, and degrade gracefully.
I couldn't come up with a succinct name that aptly described what it does, so instead of Fancy Custom Image Radio Buttons and Checkboxes, I just named the plugin Fancy Opts.
See the demo page for a few examples of custom radio button and checkbox inputs.
/**
* v0.6 Fancy Opts plugin for jQuery
* http://rommelsantor.com/jquery/fancyopts
*
* Author(s): Rommel Santor
* http://rommelsantor.com
*
* This plugin allows you to create custom, image-based radio buttons and
* checkboxes seamlessly integrated into existing forms with graceful
* degradation.
*
* Copyright (c) 2011 by Rommel Santor <rommel at rommelsantor dot com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
@*/
/**
* >> Requirements <<
* jQuery v1.4 or better
*
* >> Version History <<
* Var 0.6 - 2013-10-23 - Rommel Santor
* Fixed (long-overdue) checking of DOM radio to use .prop()
* (if available), which replaced .attr() in jQuery v1.6 for
* setting the 'checked' and 'disabled' properties
* Ver 0.5 - 2011-05-05 - Rommel Santor
* Fixed method .fancyopts('check',true) for radio buttons to make
* sure all other buttons of the same name become unchecked
* Ver 0.4 - 2011-05-03 - Rommel Santor
* Added getters for 'checked' and 'disabled'; added additional
* optional params to 'check', 'disable', and 'focus' methods
* to prevent invoking callbacks onCheck(), onDisable(), and
* onFocus()
* Ver 0.3 - 2011-04-28 - Rommel Santor
* Modified onCheck() callback to be passed radio currently
* selected value only with "checked" value of true; reversed
* order of args
* Ver 0.2 - 2011-03-27 - Rommel Santor
* Fix for radio buttons in Chrome (Thanks, Patrick Connolly)
* Ver 0.1 - 2011-03-16 - Rommel Santor
* Initial Release
*
* >> Tested <<
* Mozilla (Firefox 3+)
* Webkit (Chrome 9+, Safari for Windows 5+)
* MSIE 7, 8
* Opera 11+
*
* >> Known issues <<
* - none known
*/
/**
* Methods:
* .fancyopts([options])
* .fancyopts('init', [options]) - initialize FancyOpts on a new jQuery object
* options : see "Options" below
*
* .fancyopts('disable', [on], [nocallback]) - disable/enable the custom input (like calling .prop({disabled:on}))
* on : true/false to force on/off; if unspecified, the disabled state is toggled
* nocallback : if non-empty, onDisable() callback will not be invoked
*
* .fancyopts('check', [on], [nocallback]) - check/uncheck the custom input (like calling .prop({checked:on}))
* on : true/false to force on/off; if unspecified, checkbox state is toggled and radio is checked
* nocallback : if non-empty, onCheck() callback will not be invoked
*
* .fancyopts('focus', [on], [nocallback]) - focus or blur the custom input
* on : if true, the first matching element receives focus; if false, all matching elements blur
* nocallback : if non-empty, onFocus() callback will not be invoked
*
* .fancyopts('checked') - determine if first element in set is checked (like .prop('checked'))
*
* .fancyopts('disabled') - determine if first element in set is disabled (like .prop('disabled'))
*/
/**
* Required Options:
* image - the url to the image containing the custom input states; must be sprite vertically
* stacked in order of:
* unchecked
* [unchecked-active]
* checked
* [checked-active]
* unchecked-disabled
* checked-disabled
*
* width - the width of the supplied image
*
* height - the height of each sub-image sprite within the supplied image
*
* hasActive - whether the unchecked-active and checked-active images are included in the supplied image
*
* Optional Options:
* activeHover - whether the active state should be triggered on hover; ignored if hasActive if false
* true for active onhover, false for active onmousedown
*
* onCheck - see "Overridable Events" below
*
* onDisable - see "Overridable Events" below
*
* onFocus - see "Overridable Events" below
*/
/**
* Overridable Events:
* onCheck(value, checked) - triggered after checkbox is checked/unchecked or after new radio button is checked
* value : for checkbox, value of element; for radio, value of newly selected element
* checked : for checkbox, true if element is checked, false if unchecked; for radio, always true
*
* onDisable(disabled) - triggered after being disabled or enabled
* disabled : true if element has become disabled; false if enabled
*
* onFocus(focused) - triggered after a FancyOpt element gains or loses focus
* focused : true if element received focus; false if it lost focus
*/
If you are considerate enough to show your appreciation for this software, your contribution will be sincerely appreciated.
Feel free to send any questions/comments/suggestions to me at rommel at rommelsantor dot com.