multistate button
demonstrates a jquery plugin and binding to knockout
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js"></script>
<span data-bind="MultistateValue: truthyValue1">click here</span>
<br />
<br />
<span data-bind="MultistateValue: truthyValue2, states: [true, false]">click here too</span>
CSS
span {
padding-left: 4px;
cursor: pointer;
}
.multistate-true {
border-left: 8px solid #0c0;
}
.multistate-false {
border-left: 8px solid Red;
}
.multistate-null {
border-left: 8px solid Blue;
}
CoffeeScript
/*
minimal jquery plugin to provide a multi state check box
states: true, false
put it in a separate file and link to it
*/
(function ( $, undefined ) {
// knockout compatibility bindings for the plugin go here
if ( !!ko && !ko.bindingHandlers.MultistateValue ) {
ko.bindingHandlers.MultistateValue = {
init: function ( element, valueAccessor, allBindingsAccessor, viewModel, bindingContext ) {
// is Multistate already inited on this element?
var msObj = $( element ).data( 'multistate' );
if ( !msObj ) {
var allBindings = allBindingsAccessor();
var states = allBindings.states || [false, true, null];
var ms = $( element ).multistate( {
states: states,
onchange: function ( id ) {
var value = valueAccessor();
// "this" should be bound to the multistate instance on this element
value( this.State() );
}
} );
$( element ).data( 'multistate', ms );
}
},
update: function ( element, valueAccessor, allBindingsAccessor, viewModel, bindingContext ) {
var msObj = $( element ).data( 'multistate' );
var value = valueAccessor();
var valueUnwrapped = ko.unwrap( value );
msObj.State( valueUnwrapped, false );
}
};
}
$.fn.multistate = function ( options ) {
// handle multiple items in the jQuery object
if ( this.length > 1 ) {
this.each( function () { $( this ).multistate( options ) } );
return this;
}
var o = $.extend( {}, $.fn.multistate.defaults, options || {} );
var that = this;
var self = $( this );
var state = o.initstate;
self.addClass( 'multistate-' + state );
function getNextState( origstate ) {
return o.states[( $.inArray( origstate, o.states ) + 1 ) % o.states.length];
}
that.State = function ( newstate, sendCall ) {
if(newstate !== undefined) {
self.removeClass( 'multistate-' + state );
state = newstate;
self.addClass( 'multistate-' + state );
if ( !!o.onchange && !!sendCall )...