JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.3/themes/base/jquery-ui.css">
<ul id="example">
<li><span>Hello world?</span>
<div class="slideButton">
<input type="radio" id="hworld-on" value="on" name="hworld" /><label for="hworld-on">On</label>
<input type="radio" id="hworld-off" value="off" name="hworld" /><label for="hworld-off">Off</label>
</div>
</li>
<li><span>Filling in your text returns? </span>
<div class="slideButtonWide">
<input type="radio" id="tax-yes" value="yes" name="taxreturn" /><label for="tax-yes">Yes</label>
<input type="radio" id="tax-no" value="no" name="taxreturn" /><label for="tax-no">No</label>
</div>
</li>
<li><span>Having difficulties?</span>
<div class="slideButton">
<input type="radio" id="diff-yes" value="yes" name="difficulty" checked="checked" /><label for="diff-yes">Blaarg!</label>
<input type="radio" id="diff-no" value="no" name="difficulty" /><label for="diff-no">Brilliant!</label>
</div>
</li>
</ul>
CSS
body {
font-family: Arial, sans-serif;
font-size: 13px;
}
#example li {
margin: 5px 0;
}
#example li > span {
display: inline-block;
vertical-align: center;
width: 200px;
}
.ui-sbutton-container {
border: 1px solid #666;
position: relative;
font-family: Arial;
font-weight: bold;
-moz-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
overflow: hidden;
display: inline-block;
vertical-align: middle;
}
.ui-sbutton-container .ui-sbutton-handle {
display: block;
background-color: #999;
border: 1px solid #666;
text-indent: -9999px;
-moz-box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.4);
-webkit-box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.4);
box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.5);
position: absolute;
top: -1px;
left: -1px;
cursor: w-resize;
height: 100%;
}
.ui-sbutton-container .ui-sbutton-handle.ui-sbutton-active {
background-color: #aaa;
}
.ui-sbutton-container .ui-sbutton-label {
display: block;
text-align: center;
padding: 0.3em 0.5em 0.35em;
float: left;
font-size: 0.9em;
}
JavaScript
(function($) {
$.fn.slideButton = function(options) {
// Settings
var settings = $.extend({
slideSpeed: 8,
revertSpeed: 3,
labelWidth: 0
}, options);
this.each(function() {
var container = $(this);
var label = container.children('label');
var input = container.children(':radio');
var maxWidth = 0;
if (label.length != 2 || input.length != 2) {
throw new Error("The container must contain two radio buttons and two labels");
}
// move() does the animation associated with
// state changing for the button
function move(direction, speed) {
var amount = direction === 'right' ? halfWidth : -1;
var duration = (direction === 'right' ? halfWidth - handle.position().left : handle.position().left) * speed;
handle.animate({
left: amount
}, duration);
input.eq(direction === 'right' ? 0 : 1).attr('checked', true);
}
// Handles changing by checking current state
function updateState() {
move(handle.hasClass('on') ? 'right' : 'left', settings.slideSpeed);
handle.toggleClass('on');
return false;
}
// Reverts position - think of this as
// the opposite of updateState()
function revert() {
move(handle.hasClass('on') ? 'left' : 'right', settings.revertSpeed);
return false;
}
// Adding classes and hiding input elements
container.addClass('ui-sbutton-container ui-corner-all');
input.addClass('ui-helper-hidden-accessible');
label.addClass('ui-sbutton-label');
// Setting label widths - if none set,
// then loop through all of them...