[TemporaryStorage] add files required for SDK build
[samples/web/TemporaryStorage.git] / tizen-web-ui-fw / latest / js / src / widgets / jquery.mobile.tizen.slider.js
1
2 /*
3  * jQuery Mobile Widget @VERSION
4  *
5  * This software is licensed under the MIT licence (as defined by the OSI at
6  * http://www.opensource.org/licenses/mit-license.php)
7  *
8  * ***************************************************************************
9  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
10  * Copyright (c) 2011 by Intel Corporation Ltd.
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included in
20  * all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  * ***************************************************************************
30  *
31  * Authors: Max Waterman <max.waterman@intel.com>
32  * Authors: Minkyu Kang <mk7.kang@samsung.com>
33  */
34
35 /**
36  * tizenslider modifies the JQuery Mobile slider and is created in the same way.
37  *
38  * See the JQuery Mobile slider widget for more information :
39  *     http://jquerymobile.com/demos/1.0a4.1/docs/forms/forms-slider.html
40  *
41  * The JQuery Mobile slider option:
42  *     theme: specify the theme using the 'data-theme' attribute
43  *
44  * Options:
45  *     theme: string; the theme to use if none is specified using the 'data-theme' attribute
46  *            default: 'c'
47  *     popup: boolean; controls whether the popup is displayed or not
48  *                   specify if the popup is enabled using the 'data-popup' attribute
49  *                   set from javascript using .tizenslider('option','popup',newValue)
50  *
51  * Events:
52  *     changed: triggers when the value is changed (rather than when the handle is moved)
53  *
54  * Examples:
55  *
56  *     <a href="#" id="popupEnabler" data-role="button" data-inline="true">Enable popup</a>
57  *     <a href="#" id="popupDisabler" data-role="button" data-inline="true">Disable popup</a>
58  *     <div data-role="fieldcontain">
59  *         <input id="mySlider" data-theme='a' data-popup='false' type="range" name="slider" value="7" min="0" max="9" />
60  *     </div>
61  *     <div data-role="fieldcontain">
62  *         <input id="mySlider2" type="range" name="slider" value="77" min="0" max="777" />
63  *     </div>
64  *
65  *     // disable popup from javascript
66  *     $('#mySlider').tizenslider('option','popup',false);
67  *
68  *     // from buttons
69  *     $('#popupEnabler').bind('vclick', function() {
70  *         $('#mySlider').tizenslider('option','popup',true);
71  *     });
72  *     $('#popupDisabler').bind('vclick', function() {
73  *         $('#mySlider').tizenslider('option','popup',false);
74  *     });
75  */
76
77 /**
78         @class Slider
79         The slider widget shows a control on the screen that you can use to change values by dragging a handle on a horizontal scale. Sliders can be used in Tizen as described in the jQueryMobile documentation for sliders.
80
81         To add a slider widget to the application, use the following code:
82
83                 <input data-popup='false' type="range" name="slider" value="5" min="0" max="10" data-icon="text" data-text-left="Min" data-text-right="Max" />
84
85         The slider can define callbacks for events as described in the jQueryMobile documentation for slider events.
86         You can use methods with the slider as described in the jQueryMobile documentation for slider methods.
87 */
88 /**
89         @property {String} data-icon
90         Defines the icon style for the slider ends. The icon options are bright, volume, and text.
91         The default value is text.
92 */
93 /**
94         @property {Boolean} data-popup
95         Enables or disables a pop-up showing the current value while the handle is dragged.
96         The default value is true.
97 */
98 /**
99         @property {String} data-text-left
100         Defines the text displayed on the left side of the slider.
101         The data-icon option must be set to text.
102 */
103 /**
104         @property {String} data-text-right
105         Defines the text displayed on the right side of the slider.
106         The data-icon option must be set to text.
107 */
108
109 (function ($, window, undefined) {
110         $.widget("tizen.tizenslider", $.mobile.widget, {
111                 options: {
112                         popup: true
113                 },
114
115                 popup: null,
116                 handle: null,
117                 handleText: null,
118
119                 _create: function () {
120                         this.currentValue = null;
121                         this.popupVisible = false;
122
123                         var self = this,
124                                 inputElement = $( this.element ),
125                                 slider,
126                                 handle_press,
127                                 popupEnabledAttr,
128                                 icon,
129                                 text_right,
130                                 text_left,
131                                 text_length,
132                                 elem_left,
133                                 elem_right,
134                                 margin_left,
135                                 margin_right;
136
137                         // apply jqm slider
138                         inputElement.slider();
139
140                         // hide the slider input element proper
141                         inputElement.hide();
142
143                         self.popup = $('<div class="ui-slider-popup"></div>');
144
145                         // set the popup according to the html attribute
146                         popupEnabledAttr = inputElement.jqmData('popup');
147                         if ( popupEnabledAttr !== undefined ) {
148                                 self.options.popup = ( popupEnabledAttr == true );
149                         }
150
151                         // get the actual slider added by jqm
152                         slider = inputElement.next('.ui-slider');
153
154                         icon = inputElement.attr('data-icon');
155
156                         // wrap the background
157                         slider.wrap('<div class="ui-slider-container"></div>');
158
159                         // get the handle
160                         self.handle = slider.find('.ui-slider-handle');
161
162                         // remove the rounded corners from the slider and its children
163                         slider.removeClass('ui-btn-corner-all');
164                         slider.find('*').removeClass('ui-btn-corner-all');
165
166                         // add icon
167                         switch ( icon ) {
168                         case 'bright':
169                         case 'volume':
170                                 elem_left = $('<div class="ui-slider-left-' + icon + '"></div>');
171                                 elem_right = $('<div class="ui-slider-right-' + icon + '"></div>');
172
173                                 slider.before( elem_left );
174                                 slider.after( elem_right );
175
176                                 margin_left = elem_left.width() + 16;
177                                 margin_right = elem_right.width() + 16;
178                                 break;
179
180                         case 'text':
181                                 text_left = ( inputElement.attr('data-text-left') === undefined ) ? '' :
182                                                 inputElement.attr('data-text-left').substring( 0, 3 );
183                                 text_right = ( inputElement.attr('data-text-right') === undefined ) ? '' :
184                                                 inputElement.attr('data-text-right').substring( 0, 3 );
185
186                                 text_length = Math.max( text_left.length, text_right.length ) + 1;
187
188                                 margin_left = text_length + "rem";
189                                 margin_right = text_length + "rem";
190
191                                 elem_left = $('<div class="ui-slider-left-text" style="left:' +
192                                         -( text_length ) + 'rem; width:' + text_length + 'rem;">' +
193                                         '<span style="position:relative;top:0.4em;">' +
194                                         text_left +
195                                         '</span></div>');
196                                 elem_right = $('<div class="ui-slider-right-text" style="right:' +
197                                         -( text_length ) + 'rem; width:' + text_length + 'rem;">' +
198                                         '<span style="position:relative;top:0.4em;">' +
199                                         text_right +
200                                         '</span></div>');
201
202                                 slider.before( elem_left );
203                                 slider.after( elem_right );
204                                 break;
205                         }
206
207                         if ( icon ) {
208                                 slider.parent('.ui-slider-container').css({
209                                         "margin-left": margin_left,
210                                         "margin-right": margin_right
211                                 });
212                         }
213
214                         // handle press
215                         slider.append($('<div class="ui-slider-handle-press"></div>'));
216                         self.handle_press = slider.find('.ui-slider-handle-press');
217                         self.handle_press.css('display', 'none');
218
219                         // add a popup element (hidden initially)
220                         slider.parents(".ui-page").append( self.popup );
221                         self.popup.hide();
222
223                         // get the element where value can be displayed
224                         self.handleText = slider.find('.ui-btn-text');
225
226                         // set initial value
227                         self.updateSlider();
228
229                         // bind to changes in the slider's value to update handle text
230                         this.element.on('change', function () {
231                                 self.updateSlider();
232                                 self.showPopup();
233                         });
234                         this.element.on( 'slidestart', function( event ) {
235                                 self.updateSlider();
236                                 self.showPopup();
237                         });
238
239                         // bind clicks on the handle to show the popup
240                         self.handle.on('vmousedown', function () {
241                                 self.showPopup();
242                         });
243
244                         // watch events on the document to turn off the slider popup
245                         slider.add( document ).on('vmouseup', function () {
246                                 self.hidePopup();
247                         });
248                 },
249
250                 _handle_press_show: function () {
251                         this.handle_press.css('display', '');
252                 },
253
254                 _handle_press_hide: function () {
255                         this.handle_press.css('display', 'none');
256                 },
257
258                 // position the popup
259                 positionPopup: function () {
260                         var dstOffset = this.handle.offset();
261
262                         this.popup.offset({
263                                 left: dstOffset.left + ( this.handle.width() - this.popup.width() ) / 2,
264                                 top: dstOffset.top - this.popup.height()
265                         });
266
267                         this.handle_press.offset({
268                                 left: dstOffset.left,
269                                 top: dstOffset.top
270                         });
271                 },
272
273                 // show value on the handle and in popup
274                 updateSlider: function () {
275                         var font_size,
276                                 font_length,
277                                 font_top,
278                                 padding_size,
279                                 newValue,
280                                 get_value_length = function ( v ) {
281                                         var val = Math.abs( v ),
282                                                 len;
283
284                                         if ( val > 999 ) {
285                                                 len = 4;
286                                         } else if ( val > 99 ) {
287                                                 len = 3;
288                                         } else if ( val > 9 ) {
289                                                 len = 2;
290                                         } else {
291                                                 len = 1;
292                                         }
293
294                                         if ( v < 0 ) {
295                                                 len++;
296                                         }
297
298                                         return len;
299                                 };
300
301                         // remove the title attribute from the handle (which is
302                         // responsible for the annoying tooltip); NB we have
303                         // to do it here as the jqm slider sets it every time
304                         // the slider's value changes :(
305                         this.handle.removeAttr('title');
306
307                         newValue = this.element.val();
308
309                         font_length = get_value_length( newValue );
310
311                         if ( this.popupVisible ) {
312                                 this.positionPopup();
313
314                                 switch ( font_length ) {
315                                 case 1:
316                                 case 2:
317                                         font_size = '1.5rem';
318                                         padding_size = '0.15rem';
319                                         break;
320                                 case 3:
321                                         font_size = '1rem';
322                                         padding_size = '0.5rem';
323                                         break;
324                                 default:
325                                         font_size = '0.8rem';
326                                         padding_size = '0.5rem';
327                                         break;
328                                 }
329
330                                 this.popup.css({
331                                         "font-size": font_size,
332                                         "padding-top": padding_size
333                                 });
334                         }
335
336                         if ( newValue === this.currentValue ) {
337                                 return;
338                         }
339
340                         switch ( font_length ) {
341                         case 1:
342                                 font_size = '0.95rem';
343                                 font_top = '0';
344                                 break;
345                         case 2:
346                                 font_size = '0.85rem';
347                                 font_top = '-0.01rem';
348                                 break;
349                         case 3:
350                                 font_size = '0.65rem';
351                                 font_top = '-0.05rem';
352                                 break;
353                         default:
354                                 font_size = '0.45rem';
355                                 font_top = '-0.15rem';
356                                 break;
357                         }
358
359                         if ( font_size != this.handleText.css('font-size') ) {
360                                 this.handleText.css({
361                                         'font-size': font_size,
362                                         'top': font_top
363                                 });
364                         }
365
366                         this.currentValue = newValue;
367                         this.handleText.text( newValue );
368                         this.popup.html( newValue );
369
370                         this.element.trigger( 'update', newValue );
371                 },
372
373                 // show the popup
374                 showPopup: function () {
375                         if ( !this.options.popup || this.popupVisible ) {
376                                 return;
377                         }
378
379                         this.popup.show();
380                         this.popupVisible = true;
381                         this._handle_press_show();
382                 },
383
384                 // hide the popup
385                 hidePopup: function () {
386                         if ( !this.options.popup || !this.popupVisible ) {
387                                 return;
388                         }
389
390                         this.popup.hide();
391                         this.popupVisible = false;
392                         this._handle_press_hide();
393                 },
394
395                 _setOption: function (key, value) {
396                         var needToChange = ( value !== this.options[key] );
397
398                         if ( !needToChange ) {
399                                 return;
400                         }
401
402                         switch ( key ) {
403                         case 'popup':
404                                 this.options.popup = value;
405
406                                 if ( this.options.popup) {
407                                         this.updateSlider();
408                                 } else {
409                                         this.hidePopup();
410                                 }
411
412                                 break;
413                         }
414                 }
415         });
416
417         // stop jqm from initialising sliders
418         $( document ).on( "pagebeforecreate", function ( e ) {
419                 if ( $.data( window, "jqmSliderInitSelector" ) === undefined ) {
420                         $.data( window, "jqmSliderInitSelector",
421                                 $.mobile.slider.prototype.options.initSelector );
422                         $.mobile.slider.prototype.options.initSelector = null;
423                 }
424         });
425
426         // initialise sliders with our own slider
427         $( document ).on( "pagecreate create", function ( e ) {
428                 var jqmSliderInitSelector = $.data( window, "jqmSliderInitSelector" );
429                 $( e.target ).find(jqmSliderInitSelector).each(function () {
430                         var $this = $( this );
431                         if ( $this.is("select") ) {
432                                 $this.slider();
433                         } else {
434                                 $this.tizenslider();
435                         }
436                 });
437         });
438
439 }( jQuery, this ));
440