2 * "checkboxradio" plugin
5 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
6 //>>description: Consistent styling for checkboxes/radio buttons.
7 //>>label: Checkboxes & Radio Buttons
9 //>>css: ../css/themes/default/jquery.mobile.theme.css,../css/structure/jquery.mobile.forms.checkboxradio.css
11 define( [ "jquery", "./jquery.mobile.core", "./jquery.mobile.widget", "./jquery.mobile.buttonMarkup" ], function( $ ) {
12 //>>excludeEnd("jqmBuildExclude");
13 (function( $, undefined ) {
15 $.widget( "mobile.checkboxradio", $.mobile.widget, {
18 initSelector: "input[type='checkbox'],input[type='radio']"
23 inheritAttr = function( input, dataAttr ) {
24 return input.jqmData( dataAttr ) || input.closest( "form,fieldset" ).jqmData( dataAttr )
26 // NOTE: Windows Phone could not find the label through a selector
27 // filter works though.
28 parentLabel = $( input ).closest( "label" ),
29 label = parentLabel.length ? parentLabel : $( input ).closest( "form,fieldset,:jqmData(role='page'),:jqmData(role='dialog')" ).find( "label" ).filter( "[for='" + input[0].id + "']" ),
30 inputtype = input[0].type,
31 mini = inheritAttr( input, "mini" ),
32 checkedState = inputtype + "-on",
33 uncheckedState = inputtype + "-off",
34 icon = input.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedState,
35 iconpos = inheritAttr( input, "iconpos" ),
36 activeBtn = icon ? "" : " " + $.mobile.activeBtnClass,
37 checkedClass = "ui-" + checkedState + activeBtn,
38 uncheckedClass = "ui-" + uncheckedState,
39 checkedicon = "ui-icon-" + checkedState,
40 uncheckedicon = "ui-icon-" + uncheckedState;
42 if ( inputtype !== "checkbox" && inputtype !== "radio" ) {
46 // Expose for other methods
50 checkedClass: checkedClass,
51 uncheckedClass: uncheckedClass,
52 checkedicon: checkedicon,
53 uncheckedicon: uncheckedicon
56 // If there's no selected theme check the data attr
57 if( !this.options.theme ) {
58 this.options.theme = $.mobile.getInheritedTheme( this.element, "c" );
62 theme: this.options.theme,
69 // Wrap the input + label in a div
70 var wrapper = document.createElement('div');
71 wrapper.className = 'ui-' + inputtype;
73 input.add( label ).wrapAll( wrapper );
76 vmouseover: function( event ) {
77 if ( $( this ).parent().is( ".ui-disabled" ) ) {
78 event.stopPropagation();
82 vclick: function( event ) {
83 if ( input.is( ":disabled" ) ) {
84 event.preventDefault();
90 input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) );
92 // trigger click handler's bound directly to the input as a substitute for
93 // how label clicks behave normally in the browsers
94 // TODO: it would be nice to let the browser's handle the clicks and pass them
95 // through to the associate input. we can swallow that click at the parent
96 // wrapper element level
97 input.triggerHandler( 'click' );
99 // Input set for common radio buttons will contain all the radio
100 // buttons, but will not for checkboxes. clearing the checked status
101 // of other radios ensures the active button state is applied properly
102 self._getInputSet().not( input ).prop( "checked", false );
111 vmousedown: function() {
118 // Adds checked attribute to checked input when keyboard is used
119 if ( $this.is( ":checked" ) ) {
121 $this.prop( "checked", true);
122 self._getInputSet().not($this).prop( "checked", false );
125 $this.prop( "checked", false );
132 label.addClass( $.mobile.focusClass );
136 label.removeClass( $.mobile.focusClass );
143 _cacheVals: function() {
144 this._getInputSet().each(function() {
145 $(this).jqmData( "cacheVal", this.checked );
149 //returns either a set of radios with the same name attribute, or a single checkbox
150 _getInputSet: function(){
151 if(this.inputtype === "checkbox") {
155 return this.element.closest( "form,fieldset,:jqmData(role='page')" )
156 .find( "input[name='"+ this.element[0].name +"'][type='"+ this.inputtype +"']" );
159 _updateAll: function() {
162 this._getInputSet().each(function() {
165 if ( this.checked || self.inputtype === "checkbox" ) {
166 $this.trigger( "change" );
169 .checkboxradio( "refresh" );
172 refresh: function() {
173 var input = this.element[0],
175 icon = label.find( ".ui-icon" );
177 if ( input.checked ) {
178 label.addClass( this.checkedClass ).removeClass( this.uncheckedClass );
179 icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon );
181 label.removeClass( this.checkedClass ).addClass( this.uncheckedClass );
182 icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon );
185 if ( input.disabled ) {
192 disable: function() {
193 this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" );
197 this.element.prop( "disabled", false ).parent().removeClass( "ui-disabled" );
201 //auto self-init widgets
202 $( document ).bind( "pagecreate create", function( e ){
203 $.mobile.checkboxradio.prototype.enhanceWithin( e.target, true );
207 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
209 //>>excludeEnd("jqmBuildExclude");