Revert "Export"
[framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.1.0 / js / jquery.mobile.forms.checkboxradio.js
1 /*
2 * "checkboxradio" plugin
3 */
4
5 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
6 //>>description: Consistent styling for checkboxes/radio buttons.
7 //>>label: Checkboxes & Radio Buttons
8 //>>group: Forms
9 //>>css: ../css/themes/default/jquery.mobile.theme.css,../css/structure/jquery.mobile.forms.checkboxradio.css
10
11 define( [ "jquery", "./jquery.mobile.core", "./jquery.mobile.widget", "./jquery.mobile.buttonMarkup" ], function( $ ) {
12 //>>excludeEnd("jqmBuildExclude");
13 (function( $, undefined ) {
14
15 $.widget( "mobile.checkboxradio", $.mobile.widget, {
16         options: {
17                 theme: null,
18                 initSelector: "input[type='checkbox'],input[type='radio']"
19         },
20         _create: function() {
21                 var self = this,
22                         input = this.element,
23                         inheritAttr = function( input, dataAttr ) {
24                                 return input.jqmData( dataAttr ) || input.closest( "form,fieldset" ).jqmData( dataAttr )
25                         },
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;
41
42                 if ( inputtype !== "checkbox" && inputtype !== "radio" ) {
43                         return;
44                 }
45
46                 // Expose for other methods
47                 $.extend( this, {
48                         label: label,
49                         inputtype: inputtype,
50                         checkedClass: checkedClass,
51                         uncheckedClass: uncheckedClass,
52                         checkedicon: checkedicon,
53                         uncheckedicon: uncheckedicon
54                 });
55
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" );
59                 }
60
61                 label.buttonMarkup({
62                         theme: this.options.theme,
63                         icon: icon,
64                         shadow: false,
65                         mini: mini,
66                         iconpos: iconpos
67                 });
68
69                 // Wrap the input + label in a div
70                 var wrapper = document.createElement('div');
71                 wrapper.className = 'ui-' + inputtype;
72
73                 input.add( label ).wrapAll( wrapper );
74
75                 label.bind({
76                         vmouseover: function( event ) {
77                                 if ( $( this ).parent().is( ".ui-disabled" ) ) {
78                                         event.stopPropagation();
79                                 }
80                         },
81
82                         vclick: function( event ) {
83                                 if ( input.is( ":disabled" ) ) {
84                                         event.preventDefault();
85                                         return;
86                                 }
87
88                                 self._cacheVals();
89
90                                 input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) );
91
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' );
98
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 );
103
104                                 self._updateAll();
105                                 return false;
106                         }
107                 });
108
109                 input
110                         .bind({
111                                 vmousedown: function() {
112                                         self._cacheVals();
113                                 },
114
115                                 vclick: function() {
116                                         var $this = $(this);
117
118                                         // Adds checked attribute to checked input when keyboard is used
119                                         if ( $this.is( ":checked" ) ) {
120
121                                                 $this.prop( "checked", true);
122                                                 self._getInputSet().not($this).prop( "checked", false );
123                                         } else {
124
125                                                 $this.prop( "checked", false );
126                                         }
127
128                                         self._updateAll();
129                                 },
130
131                                 focus: function() {
132                                         label.addClass( $.mobile.focusClass );
133                                 },
134
135                                 blur: function() {
136                                         label.removeClass( $.mobile.focusClass );
137                                 }
138                         });
139
140                 this.refresh();
141         },
142
143         _cacheVals: function() {
144                 this._getInputSet().each(function() {
145                         $(this).jqmData( "cacheVal", this.checked );
146                 });
147         },
148
149         //returns either a set of radios with the same name attribute, or a single checkbox
150         _getInputSet: function(){
151                 if(this.inputtype === "checkbox") {
152                         return this.element;
153                 }
154
155                 return this.element.closest( "form,fieldset,:jqmData(role='page')" )
156                         .find( "input[name='"+ this.element[0].name +"'][type='"+ this.inputtype +"']" );
157         },
158
159         _updateAll: function() {
160                 var self = this;
161
162                 this._getInputSet().each(function() {
163                         var $this = $(this);
164
165                         if ( this.checked || self.inputtype === "checkbox" ) {
166                                 $this.trigger( "change" );
167                         }
168                 })
169                 .checkboxradio( "refresh" );
170         },
171
172         refresh: function() {
173                 var input = this.element[0],
174                         label = this.label,
175                         icon = label.find( ".ui-icon" );
176
177                 if ( input.checked ) {
178                         label.addClass( this.checkedClass ).removeClass( this.uncheckedClass );
179                         icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon );
180                 } else {
181                         label.removeClass( this.checkedClass ).addClass( this.uncheckedClass );
182                         icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon );
183                 }
184
185                 if ( input.disabled ) {
186                         this.disable();
187                 } else {
188                         this.enable();
189                 }
190         },
191
192         disable: function() {
193                 this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" );
194         },
195
196         enable: function() {
197                 this.element.prop( "disabled", false ).parent().removeClass( "ui-disabled" );
198         }
199 });
200
201 //auto self-init widgets
202 $( document ).bind( "pagecreate create", function( e ){
203         $.mobile.checkboxradio.prototype.enhanceWithin( e.target, true );
204 });
205
206 })( jQuery );
207 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
208 });
209 //>>excludeEnd("jqmBuildExclude");