Tizen 2.0 Release
[platform/framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.2.0 / js / widgets / 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.structure: ../css/structure/jquery.mobile.forms.checkboxradio.css
10 //>>css.theme: ../css/themes/default/jquery.mobile.theme.css
11
12 define( [ "jquery", "../../jquery.mobile.core", "../../jquery.mobile.widget", "../../jquery.mobile.buttonMarkup" ], function( $ ) {
13 //>>excludeEnd("jqmBuildExclude");
14 (function( $, undefined ) {
15
16 $.widget( "mobile.checkboxradio", $.mobile.widget, {
17         options: {
18                 theme: null,
19                 initSelector: "input[type='checkbox'],input[type='radio']"
20         },
21         _create: function() {
22                 var self = this,
23                         input = this.element,
24                         inheritAttr = function( input, dataAttr ) {
25                                 return input.jqmData( dataAttr ) || input.closest( "form, fieldset" ).jqmData( dataAttr );
26                         },
27                         // NOTE: Windows Phone could not find the label through a selector
28                         // filter works though.
29                         parentLabel = $( input ).closest( "label" ),
30                         label = parentLabel.length ? parentLabel : $( input ).closest( "form, fieldset, :jqmData(role='page'), :jqmData(role='dialog')" ).find( "label" ).filter( "[for='" + input[0].id + "']" ).first(),
31                         inputtype = input[0].type,
32                         mini = inheritAttr( input, "mini" ),
33                         checkedState = inputtype + "-on",
34                         uncheckedState = inputtype + "-off",
35                         icon = input.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedState,
36                         iconpos = inheritAttr( input, "iconpos" ),
37                         activeBtn = icon ? "" : " " + $.mobile.activeBtnClass,
38                         checkedClass = "ui-" + checkedState + activeBtn,
39                         uncheckedClass = "ui-" + uncheckedState,
40                         checkedicon = "ui-icon-" + checkedState,
41                         uncheckedicon = "ui-icon-" + uncheckedState;
42
43                 if ( inputtype !== "checkbox" && inputtype !== "radio" ) {
44                         return;
45                 }
46
47                 // Expose for other methods
48                 $.extend( this, {
49                         label: label,
50                         inputtype: inputtype,
51                         checkedClass: checkedClass,
52                         uncheckedClass: uncheckedClass,
53                         checkedicon: checkedicon,
54                         uncheckedicon: uncheckedicon
55                 });
56
57                 // If there's no selected theme check the data attr
58                 if ( !this.options.theme ) {
59                         this.options.theme = $.mobile.getInheritedTheme( this.element, "c" );
60                 }
61
62                 label.buttonMarkup({
63                         theme: this.options.theme,
64                         icon: icon,
65                         shadow: false,
66                         mini: mini,
67                         iconpos: iconpos
68                 });
69
70                 // Wrap the input + label in a div
71                 var wrapper = document.createElement('div');
72                 wrapper.className = 'ui-' + inputtype;
73
74                 input.add( label ).wrapAll( wrapper );
75
76                 label.bind({
77                         vmouseover: function( event ) {
78                                 if ( $( this ).parent().is( ".ui-disabled" ) ) {
79                                         event.stopPropagation();
80                                 }
81                         },
82
83                         vclick: function( event ) {
84                                 if ( input.is( ":disabled" ) ) {
85                                         event.preventDefault();
86                                         return;
87                                 }
88
89                                 self._cacheVals();
90
91                                 input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) );
92
93                                 // trigger click handler's bound directly to the input as a substitute for
94                                 // how label clicks behave normally in the browsers
95                                 // TODO: it would be nice to let the browser's handle the clicks and pass them
96                                 //       through to the associate input. we can swallow that click at the parent
97                                 //       wrapper element level
98                                 input.triggerHandler( 'click' );
99
100                                 // Input set for common radio buttons will contain all the radio
101                                 // buttons, but will not for checkboxes. clearing the checked status
102                                 // of other radios ensures the active button state is applied properly
103                                 self._getInputSet().not( input ).prop( "checked", false );
104
105                                 self._updateAll();
106                                 return false;
107                         }
108                 });
109
110                 input
111                         .bind({
112                                 vmousedown: function() {
113                                         self._cacheVals();
114                                 },
115
116                                 vclick: function() {
117                                         var $this = $( this );
118
119                                         // Adds checked attribute to checked input when keyboard is used
120                                         if ( $this.is( ":checked" ) ) {
121
122                                                 $this.prop( "checked", true);
123                                                 self._getInputSet().not( $this ).prop( "checked", false );
124                                         } else {
125
126                                                 $this.prop( "checked", false );
127                                         }
128
129                                         self._updateAll();
130                                 },
131
132                                 focus: function() {
133                                         label.addClass( $.mobile.focusClass );
134                                 },
135
136                                 blur: function() {
137                                         label.removeClass( $.mobile.focusClass );
138                                 }
139                         });
140
141                 this.refresh();
142         },
143
144         _cacheVals: function() {
145                 this._getInputSet().each(function() {
146                         $( this ).jqmData( "cacheVal", this.checked );
147                 });
148         },
149
150         //returns either a set of radios with the same name attribute, or a single checkbox
151         _getInputSet: function() {
152                 if ( this.inputtype === "checkbox" ) {
153                         return this.element;
154                 }
155
156                 return this.element.closest( "form, fieldset, :jqmData(role='page'), :jqmData(role='dialog')" )
157                         .find( "input[name='" + this.element[0].name + "'][type='" + this.inputtype + "']" );
158         },
159
160         _updateAll: function() {
161                 var self = this;
162
163                 this._getInputSet().each(function() {
164                         var $this = $( this );
165
166                         if ( this.checked || self.inputtype === "checkbox" ) {
167                                 $this.trigger( "change" );
168                         }
169                 })
170                 .checkboxradio( "refresh" );
171         },
172
173         refresh: function() {
174                 var input = this.element[0],
175                         label = this.label,
176                         icon = label.find( ".ui-icon" );
177
178                 if ( input.checked ) {
179                         label.addClass( this.checkedClass ).removeClass( this.uncheckedClass );
180                         icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon );
181                 } else {
182                         label.removeClass( this.checkedClass ).addClass( this.uncheckedClass );
183                         icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon );
184                 }
185
186                 if ( input.disabled ) {
187                         this.disable();
188                 } else {
189                         this.enable();
190                 }
191         },
192
193         disable: function() {
194                 this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" );
195         },
196
197         enable: function() {
198                 this.element.prop( "disabled", false ).parent().removeClass( "ui-disabled" );
199         }
200 });
201
202 //auto self-init widgets
203 $( document ).bind( "pagecreate create", function( e ) {
204         $.mobile.checkboxradio.prototype.enhanceWithin( e.target, true );
205 });
206
207 })( jQuery );
208 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
209 });
210 //>>excludeEnd("jqmBuildExclude");