6290fe45f64798c1dbd36697619b7a534753247d
[platform/framework/web/web-ui-fw.git] / src / widgets / slider / js / jquery.mobile.tizen.slider.js
1 /*
2  * jQuery Mobile Widget @VERSION
3  *
4  * This software is licensed under the MIT licence (as defined by the OSI at
5  * http://www.opensource.org/licenses/mit-license.php)
6  *
7  * ***************************************************************************
8  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
9  * Copyright (c) 2011 by Intel Corporation Ltd.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  * ***************************************************************************
29  *
30  * Authors: Max Waterman <max.waterman@intel.com>
31  * Authors: Minkyu Kang <mk7.kang@samsung.com>
32  */
33
34 /**
35  * tizenslider modifies the JQuery Mobile slider and is created in the same way.
36  *
37  * See the JQuery Mobile slider widget for more information :
38  *     http://jquerymobile.com/demos/1.0a4.1/docs/forms/forms-slider.html
39  *
40  * The JQuery Mobile slider option:
41  *     theme: specify the theme using the 'data-theme' attribute
42  *
43  * Options:
44  *     theme: string; the theme to use if none is specified using the 'data-theme' attribute
45  *            default: 'c'
46  *     popup: boolean; controls whether the popup is displayed or not
47  *                   specify if the popup is enabled using the 'data-popup' attribute
48  *                   set from javascript using .tizenslider('option','popup',newValue)
49  *
50  * Events:
51  *     changed: triggers when the value is changed (rather than when the handle is moved)
52  *
53  * Examples:
54  *
55  *     <a href="#" id="popupEnabler" data-role="button" data-inline="true">Enable popup</a>
56  *     <a href="#" id="popupDisabler" data-role="button" data-inline="true">Disable popup</a>
57  *     <div data-role="fieldcontain">
58  *         <input id="mySlider" data-theme='a' data-popup='false' type="range" name="slider" value="7" min="0" max="9" />
59  *     </div>
60  *     <div data-role="fieldcontain">
61  *         <input id="mySlider2" type="range" name="slider" value="77" min="0" max="777" />
62  *     </div>
63  *
64  *     // disable popup from javascript
65  *     $('#mySlider').tizenslider('option','popup',false);
66  *
67  *     // from buttons
68  *     $('#popupEnabler').bind('vclick', function() {
69  *         $('#mySlider').tizenslider('option','popup',true);
70  *     });
71  *     $('#popupDisabler').bind('vclick', function() {
72  *         $('#mySlider').tizenslider('option','popup',false);
73  *     });
74  */
75
76 (function ($, window, undefined) {
77         $.widget("tizen.tizenslider", $.mobile.widget, {
78                 options: {
79                         popup: true
80                 },
81
82                 popup: null,
83                 handle: null,
84                 handleText: null,
85
86                 _create: function () {
87                         this.currentValue = null;
88                         this.popupVisible = false;
89
90                         var self = this,
91                                 inputElement = $( this.element ),
92                                 slider,
93                                 slider_bar,
94                                 handle_press,
95                                 popupEnabledAttr,
96                                 icon;
97
98                         // apply jqm slider
99                         inputElement.slider();
100
101                         // hide the slider input element proper
102                         inputElement.hide();
103
104                         self.popup = $('<div class="ui-slider-popup"></div>');
105
106                         // set the popup according to the html attribute
107                         popupEnabledAttr = inputElement.jqmData('popup');
108                         if ( popupEnabledAttr !== undefined ) {
109                                 self.options.popup = ( popupEnabledAttr === 'true' );
110                         }
111
112                         // get the actual slider added by jqm
113                         slider = inputElement.next('.ui-slider');
114
115                         icon = inputElement.attr('data-icon');
116
117                         // wrap the background
118                         if ( icon === undefined ) {
119                                 slider.wrap('<div class="ui-slider-bg"></div>');
120                         } else {
121                                 slider.wrap('<div class="ui-slider-icon-bg"></div>');
122                         }
123
124                         // get the handle
125                         self.handle = slider.find('.ui-slider-handle');
126
127                         // remove the rounded corners from the slider and its children
128                         slider.removeClass('ui-btn-corner-all');
129                         slider.find('*').removeClass('ui-btn-corner-all');
130
131                         // add icon
132
133                         switch ( icon ) {
134                         case 'bright':
135                         case 'volume':
136                                 slider.before( $('<div class="ui-slider-left-' +
137                                                         icon + '"></div>') );
138                                 slider.after( $('<div class="ui-slider-right-' +
139                                                         icon + '"></div>') );
140                                 break;
141
142                         case 'text':
143                                 slider.before( $('<div class="ui-slider-left-text">' +
144                                         '<span style="position:relative;top:0.4em;">' +
145                                         inputElement.attr('data-text-left').substring( 0, 3) +
146                                         '</span></div>') );
147                                 slider.after( $('<div class="ui-slider-right-text">' +
148                                         '<span style="position:relative;top:0.4em;">' +
149                                         inputElement.attr('data-text-right').substring( 0, 3) +
150                                         '</span></div>') );
151                                 break;
152                         }
153
154                         // slider bar
155                         slider.append($('<div class="ui-slider-bar"></div>'));
156                         self.slider_bar = slider.find('.ui-slider-bar');
157
158                         // handle press
159                         slider.append($('<div class="ui-slider-handle-press"></div>'));
160                         self.handle_press = slider.find('.ui-slider-handle-press');
161                         self.handle_press.css('display', 'none');
162
163                         // add a popup element (hidden initially)
164                         slider.before( self.popup );
165                         self.popup.hide();
166
167                         // get the element where value can be displayed
168                         self.handleText = slider.find('.ui-btn-text');
169
170                         // set initial value
171                         self.updateSlider();
172
173                         // bind to changes in the slider's value to update handle text
174                         this.element.bind('change', function () {
175                                 self.updateSlider();
176                         });
177
178                         // bind clicks on the handle to show the popup
179                         self.handle.bind('vmousedown', function () {
180                                 self.showPopup();
181                         });
182
183                         // watch events on the document to turn off the slider popup
184                         slider.add( document ).bind('vmouseup', function () {
185                                 self.hidePopup();
186                         });
187                 },
188
189                 _handle_press_show: function () {
190                         this.handle_press.css('display', '');
191                 },
192
193                 _handle_press_hide: function () {
194                         this.handle_press.css('display', 'none');
195                 },
196
197                 // position the popup
198                 positionPopup: function () {
199                         var dstOffset = this.handle.offset();
200
201                         this.popup.offset({
202                                 left: dstOffset.left + ( this.handle.width() - this.popup.width() ) / 2,
203                                 top: dstOffset.top  - this.popup.outerHeight() + 15
204                         });
205
206                         this.handle_press.offset({
207                                 left: dstOffset.left,
208                                 top: dstOffset.top
209                         });
210                 },
211
212                 // show value on the handle and in popup
213                 updateSlider: function () {
214                         var font_size,
215                                 newValue;
216
217                         if ( this.popupVisible ) {
218                                 this.positionPopup();
219                         }
220
221                         // remove the title attribute from the handle (which is
222                         // responsible for the annoying tooltip); NB we have
223                         // to do it here as the jqm slider sets it every time
224                         // the slider's value changes :(
225                         this.handle.removeAttr('title');
226
227                         this.slider_bar.width( this.handle.css('left') );
228
229                         newValue = this.element.val();
230
231                         if ( newValue === this.currentValue ) {
232                                 return;
233                         }
234
235                         if ( newValue > 999 ) {
236                                 font_size = '0.7em';
237                         } else if ( newValue > 99 ) {
238                                 font_size = '0.8em';
239                         } else if ( newValue > 9 ) {
240                                 font_size = '0.9em';
241                         } else {
242                                 font_size = '1em';
243                         }
244
245                         if ( font_size != this.handleText.css('font-size') ) {
246                                 this.handleText.css( 'font-size', font_size );
247                         }
248
249                         this.currentValue = newValue;
250                         this.handleText.text( newValue );
251                         this.popup.html( newValue );
252
253                         this.element.trigger( 'update', newValue );
254                 },
255
256                 // show the popup
257                 showPopup: function () {
258                         if ( !this.options.popup || this.popupVisible ) {
259                                 return;
260                         }
261
262                         this.popup.show();
263                         this.popupVisible = true;
264                         this._handle_press_show();
265                 },
266
267                 // hide the popup
268                 hidePopup: function () {
269                         if ( !this.options.popup || !this.popupVisible ) {
270                                 return;
271                         }
272
273                         this.popup.hide();
274                         this.popupVisible = false;
275                         this._handle_press_hide();
276                 },
277
278                 _setOption: function (key, value) {
279                         var needToChange = ( value !== this.options[key] );
280
281                         if ( !needToChange ) {
282                                 return;
283                         }
284
285                         switch ( key ) {
286                         case 'popup':
287                                 this.options.popup = value;
288
289                                 if ( this.options.popup) {
290                                         this.updateSlider();
291                                 } else {
292                                         this.hidePopup();
293                                 }
294
295                                 break;
296                         }
297                 }
298         });
299
300         // stop jqm from initialising sliders
301         $( document ).bind( "pagebeforecreate", function ( e ) {
302                 if ( $.data( window, "jqmSliderInitSelector" ) === undefined ) {
303                         $.data( window, "jqmSliderInitSelector",
304                                 $.mobile.slider.prototype.options.initSelector );
305                         $.mobile.slider.prototype.options.initSelector = null;
306                 }
307         });
308
309         // initialise sliders with our own slider
310         $( document ).bind( "pagecreate", function ( e ) {
311                 var jqmSliderInitSelector = $.data( window, "jqmSliderInitSelector" );
312                 $( e.target ).find(jqmSliderInitSelector).not('select').tizenslider();
313                 $( e.target ).find(jqmSliderInitSelector).filter('select').slider();
314         });
315
316 }( jQuery, this ));