2 * "checkboxradio" plugin
5 (function( $, undefined ) {
7 $.widget( "mobile.checkboxradio", $.mobile.widget, {
10 initSelector: "input[type='checkbox'],input[type='radio']"
15 // NOTE: Windows Phone could not find the label through a selector
16 // filter works though.
17 label = input.closest( "form,fieldset,:jqmData(role='page')" ).find( "label[for='" + input[ 0 ].id + "']"),
18 inputtype = input.attr( "type" ),
19 checkedState = inputtype + "-on",
20 uncheckedState = inputtype + "-off",
21 icon = input.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedState,
22 activeBtn = icon ? "" : " " + $.mobile.activeBtnClass,
23 checkedClass = "ui-" + checkedState + activeBtn,
24 uncheckedClass = "ui-" + uncheckedState,
25 checkedicon = "ui-icon-" + checkedState,
26 uncheckedicon = "ui-icon-" + uncheckedState;
28 if ( inputtype !== "checkbox" && inputtype !== "radio" ) {
32 // Expose for other methods
36 checkedClass: checkedClass,
37 uncheckedClass: uncheckedClass,
38 checkedicon: checkedicon,
39 uncheckedicon: uncheckedicon
42 // If there's no selected theme...
43 if( !this.options.theme ) {
44 this.options.theme = this.element.jqmData( "theme" );
48 theme: this.options.theme,
53 // Wrap the input + label in a div
55 .wrapAll( "<div class='ui-" + inputtype + "'></div>" );
58 vmouseover: function( event ) {
59 if ( $( this ).parent().is( ".ui-disabled" ) ) {
60 event.stopPropagation();
64 vclick: function( event ) {
65 if ( input.is( ":disabled" ) ) {
66 event.preventDefault();
72 input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) );
74 // trigger click handler's bound directly to the input as a substitute for
75 // how label clicks behave normally in the browsers
76 // TODO: it would be nice to let the browser's handle the clicks and pass them
77 // through to the associate input. we can swallow that click at the parent
78 // wrapper element level
79 input.triggerHandler( 'click' );
81 // Input set for common radio buttons will contain all the radio
82 // buttons, but will not for checkboxes. clearing the checked status
83 // of other radios ensures the active button state is applied properly
84 self._getInputSet().not( input ).prop( "checked", false );
94 vmousedown: function() {
101 // Adds checked attribute to checked input when keyboard is used
102 if ( $this.is( ":checked" ) ) {
104 $this.prop( "checked", true);
105 self._getInputSet().not($this).prop( "checked", false );
108 $this.prop( "checked", false );
115 label.addClass( "ui-focus" );
119 label.removeClass( "ui-focus" );
126 _cacheVals: function() {
127 this._getInputSet().each(function() {
130 $this.jqmData( "cacheVal", $this.is( ":checked" ) );
134 //returns either a set of radios with the same name attribute, or a single checkbox
135 _getInputSet: function(){
136 if(this.inputtype == "checkbox") {
140 return this.element.closest( "form,fieldset,:jqmData(role='page')" )
141 .find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.inputtype +"']" );
144 _updateAll: function() {
147 this._getInputSet().each(function() {
150 if ( $this.is( ":checked" ) || self.inputtype === "checkbox" ) {
151 $this.trigger( "change" );
154 .checkboxradio( "refresh" );
157 refresh: function() {
158 var input = this.element,
160 icon = label.find( ".ui-icon" );
162 // input[0].checked expando doesn't always report the proper value
163 // for checked='checked'
164 if ( $( input[ 0 ] ).prop( "checked" ) ) {
166 label.addClass( this.checkedClass ).removeClass( this.uncheckedClass );
167 icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon );
171 label.removeClass( this.checkedClass ).addClass( this.uncheckedClass );
172 icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon );
175 if ( input.is( ":disabled" ) ) {
182 disable: function() {
183 this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" );
187 this.element.prop( "disabled", false ).parent().removeClass( "ui-disabled" );
191 //auto self-init widgets
192 $( document ).bind( "pagecreate create", function( e ){
193 $.mobile.checkboxradio.prototype.enhanceWithin( e.target );