Timepicker: change get attribute method
[platform/framework/web/web-ui-fw.git] / src / widgets / datetimepicker / js / jquery.mobile.tizen.datetimepicker.js
1 /*global Globalize:false, range:false, regexp:false*/
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) 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: Salvatore Iovene <salvatore.iovene@intel.com>
31  *                      Daehyon Jung <darrenh.jung@samsung.com>
32  */
33
34 /**
35  * datetimepicker is a widget that lets the user select a date and/or a 
36  * time. If you'd prefer use as auto-initialization of form elements, 
37  * use input elements with type=date/time/datetime within form tag
38  * as same as other form elements.
39  * 
40  * HTML Attributes:
41  * 
42  *      data-role: 'datetimepicker'
43  *      data-format: date format string. e.g) "MMM dd yyyy, HH:mm"
44  *      type: 'date', 'datetime', 'time'
45  *      value: pre-set value. only accepts ISO date string. e.g) "2012-05-04", "2012-05-04T01:02:03+09:00" 
46  *      data-date: any date/time string "new Date()" accepts.
47  *
48  * Options:
49  *      type: 'date', 'datetime', 'time'
50  *      format: see data-format in HTML Attributes.
51  *      value: see value in HTML Attributes.
52  *      date: preset value as JavaScript Date Object representation.
53  *
54  * APIs:
55  *      value( datestring )
56  *              : Set date/time to 'datestring'.
57  *      value()
58  *              : Get current selected date/time as W3C DTF style string.
59  *      getValue() - replaced with 'value()'
60  *              : same as value()
61  *      setValue( datestring ) - replaced with 'value(datestring)'
62  *              : same as value( datestring )
63  *      changeTypeFormat( type, format ) - deprecated
64  *              : Change Type and Format options. use datetimepicker( "option", "format" ) instead
65  *
66  * Events:
67  *      date-changed: Raised when date/time was changed.
68  *
69  * Examples:
70  *      <ul data-role="listview">
71  *              <li class="ui-li-3-2-2">
72  *                      <span class="ui-li-text-main">
73  *                              <input type="datetime" name="demo-date" id="demo-date" 
74  *                                      data-format="MMM dd yyyy hh:mm tt"/>
75  *                      </span>
76  *                      <span class="ui-li-text-sub">
77  *                              Date/Time Picker - <span id="selected-date1"><em>(select a date first)</em></span>
78  *                      </span>
79  *              </li>
80  *              <li class="ui-li-3-2-2">
81  *                      <span class="ui-li-text-main">
82  *                              <input type="date" name="demo-date2" id="demo-date2"/>
83  *                      </span>
84  *                      <span class="ui-li-text-sub">
85  *                              Date Picker  - <span id="selected-date2"><em>(select a date first)</em></span>
86  *                      </span>
87  *              </li>
88  *              <li class="ui-li-3-2-2">
89  *                      <span class="ui-li-text-main">
90  *                              <input type="time" name="demo-date3" id="demo-date3"/>
91  *                      </span>
92  *                      <span class="ui-li-text-sub">
93  *                              Time Picker - <span id="selected-date3"><em>(select a date first)</em></span>
94  *                      </span>
95  *              </li>
96  *      </ul>
97  * How to get a return value:
98  * ==========================
99  * Bind to the 'date-changed' event, e.g.:
100  *    $("#myDatetimepicker").bind("date-changed", function(e, date) {
101  *        alert("New date: " + date.toString());
102  *    });
103  */
104
105 /**
106         @class DateTimePicker
107         The picker widgets show a control that you can use to enter date and time values. <br/> To add a date time picker widget to the application, use the following code:
108
109                         <li class="ui-li-dialogue ui-datetime">
110                                 <div class="ui-datetime-text-main">
111                                         <input type="datetime" data-format="MMM dd yyyy hh:mm:ss" name="demo-date" id="demo-date" />
112                                 </div>
113                                 <div class="ui-li-text-sub">Date/Time Picker
114                                         <span id="selected-date1"><em>(select a date first)</em></span>
115                                 </div>
116                         </li>
117 */
118
119
120 ( function ( $, window, undefined ) {
121         $.widget( "tizen.datetimepicker", $.tizen.widgetex, {
122
123                 options: {
124                         type: null, // date, time, datetime applicable
125                         format: null,
126                         date: null,
127                         initSelector: "input[type='date'], input[type='datetime'], input[type='time'], :jqmData(role='datetimepicker')"
128                 },
129
130                 _calendar: function () {
131                         return window.Globalize.culture().calendars.standard;
132                 },
133
134                 _value: {
135                         attr: "data-" + ( $.mobile.ns || "" ) + "date",
136                         signal: "date-changed"
137                 },
138
139                 _daysInMonth: [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
140
141                 _isLeapYear: function ( year ) {
142                         return year % 4 ? 0 : ( year % 100 ? 1 : ( year % 400 ? 0 : 1 ) );
143                 },
144
145                 _makeTwoDigits: function ( val ) {
146                         var ret = val.toString(10);
147                         if ( val < 10 ) {
148                                 ret = "0" + ret;
149                         }
150                         return ret;
151                 },
152
153                 _setType: function ( type ) {
154                         //datetime, date, time
155                         switch (type) {
156                         case 'datetime':
157                         case 'date':
158                         case 'time':
159                                 this.options.type = type;
160                                 break;
161                         default:
162                                 this.options.type = 'datetime';
163                                 break;
164                         }
165
166                         this.element.attr( "data-" + ( $.mobile.ns ? $.mobile.ns + "-" : "" ) + "type", this.options.type );
167                         return this.options.type;
168                 },
169
170                 _setFormat: function ( format ) {
171                         if ( this.options.format != format ) {
172                                 this.options.format = format;
173                         } else {
174                                 return;
175                         }
176
177                         this.ui.children().remove();
178
179                         var token = this._parsePattern( format ),
180                                 div = document.createElement('div'),
181                                 pat,
182                                 tpl,
183                                 period,
184                                 btn,
185                                 obj = this;
186
187                         while ( token.length > 0 ) {
188                                 pat = token.shift();
189                                 tpl = '<span class="ui-datefield-%1" data-pat="' + pat + '">%2</span>';
190                                 switch ( pat ) {
191                                 case 'H': //0 1 2 3 ... 21 22 23
192                                 case 'HH': //00 01 02 ... 21 22 23
193                                 case 'h': //0 1 2 3 ... 11 12
194                                 case 'hh': //00 01 02 ... 11 12
195                                         $(div).append( tpl.replace('%1', 'hour') );
196                                         break;
197                                 case 'mm': //00 01 ... 59
198                                 case 'm': //0 1 2 ... 59
199                                         if ( this.options.type == 'date' ) {
200                                                 $(div).append( tpl.replace('%1', 'month') );
201                                         } else {
202                                                 $(div).append( tpl.replace('%1', 'min') );
203                                         }
204                                         break;
205                                 case 'ss':
206                                 case 's':
207                                         $(div).append( tpl.replace('%1', 'sec') );
208                                         break;
209                                 case 'd': // day of month 5
210                                 case 'dd': // day of month(leading zero) 05
211                                         $(div).append( tpl.replace('%1', 'day') );
212                                         break;
213                                 case 'M': // Month of year 9
214                                 case 'MM': // Month of year(leading zero) 09
215                                 case 'MMM':
216                                 case 'MMMM':
217                                         $(div).append( tpl.replace('%1', 'month') );
218                                         break;
219                                 case 'yy':      // year two digit
220                                 case 'yyyy': // year four digit
221                                         $(div).append( tpl.replace('%1', 'year') );
222                                         break;
223                                 case 't': //AM / PM indicator(first letter) A, P
224                                         // add button
225                                 case 'tt': //AM / PM indicator AM/PM
226                                         // add button
227                                         btn = '<a href="#" class="ui-datefield-period"' +
228                                                 ' data-role="button" data-inline="true">period</a>';
229                                         $(div).append( btn );
230                                         break;
231                                 case 'g':
232                                 case 'gg':
233                                         $(div).append( tpl.replace('%1', 'era').replace('%2', this._calendar().eras.name) );
234                                         break;
235                                 case '\t':
236                                         $(div).append( tpl.replace('%1', 'tab').replace('%2', pat) );
237                                         break;
238                                 default : // string or any non-clickable object
239                                         $(div).append( tpl.replace('%1', 'seperator').replace('%2', pat) );
240                                         break;
241                                 }
242                         }
243
244                         this.ui.append( div );
245                         if ( this.options.date ) {
246                                 this._setDate( this.options.date );
247                         }
248
249                         this.ui.find('.ui-datefield-period').buttonMarkup().bind( 'vclick', function ( e ) {
250                                 obj._switchAmPm( obj );
251                         });
252
253                         this.element.attr( "data-" + ( $.mobile.ns ? $.mobile.ns + "-" : "" ) + "format", this.options.format );
254                         return this.options.format;
255                 },
256
257                 _setDate: function ( newdate ) {
258                         if ( typeof ( newdate ) == "string" ) {
259                                 newdate = new Date( newdate );
260                         }
261
262                         var fields = $('span,a', this.ui),
263                                 type,
264                                 fn,
265                                 $field,
266                                 btn,
267                                 i;
268
269                         function getMonth() {
270                                 return newdate.getMonth() + 1;
271                         }
272
273                         for ( i = 0; i < fields.length; i++ ) {
274                                 $field = $(fields[i]);
275                                 type = $field.attr("class").match(/ui-datefield-([\w]*)/);
276                                 if ( !type ) {
277                                         type = "";
278                                 }
279                                 switch ( type[1] ) {
280                                 case 'hour':
281                                         fn = newdate.getHours;
282                                         break;
283                                 case 'min':
284                                         fn = newdate.getMinutes;
285                                         break;
286                                 case 'sec':
287                                         fn = newdate.getSeconds;
288                                         break;
289                                 case 'year':
290                                         fn = newdate.getFullYear;
291                                         break;
292                                 case 'month':
293                                         fn = getMonth;
294                                         break;
295                                 case 'day':
296                                         fn = newdate.getDate;
297                                         break;
298                                 case 'period':
299                                         fn = newdate.getHours() < 12 ? this._calendar().AM[0] : this._calendar().PM[0];
300                                         btn = $field.find( '.ui-btn-text' );
301                                         if ( btn.length == 0 ) {
302                                                 $field.text(fn);
303                                         } else if ( btn.text() != fn ) {
304                                                 btn.text( fn );
305                                         }
306                                         fn = null;
307                                         break;
308                                 default:
309                                         fn = null;
310                                         break;
311                                 }
312                                 if ( fn ) {
313                                         this._updateField( $field, fn.call( newdate ) );
314                                 }
315                         }
316
317                         this.options.date = newdate;
318
319                         this._setValue( newdate );
320
321                         this.element.attr( "data-" + ( $.mobile.ns ? $.mobile.ns + "-" : "" ) + "date", this.options.date );
322                         return this.options.date;
323                 },
324
325                 destroy: function () {
326                         if ( this.ui ) {
327                                 this.ui.remove();
328                         }
329
330                         if ( this.element ) {
331                                 this.element.show();
332                         }
333                 },
334
335                 value: function ( val ) {
336                         function timeStr( t, obj ) {
337                                 return obj._makeTwoDigits( t.getHours() ) + ':' +
338                                         obj._makeTwoDigits( t.getMinutes() ) + ':' +
339                                         obj._makeTwoDigits( t.getSeconds() );
340                         }
341
342                         function dateStr( d, obj ) {
343                                 return ( ( d.getFullYear() % 10000 ) + 10000 ).toString().substr(1) + '-' +
344                                         obj._makeTwoDigits( d.getMonth() + 1 ) + '-' +
345                                         obj._makeTwoDigits( d.getDate() );
346                         }
347
348                         var rvalue = null;
349                         if ( val ) {
350                                 rvalue = this._setDate( val );
351                         } else {
352                                 switch ( this.options.type ) {
353                                 case 'time':
354                                         rvalue = timeStr( this.options.date, this );
355                                         break;
356                                 case 'date':
357                                         rvalue = dateStr( this.options.date, this );
358                                         break;
359                                 default:
360                                         rvalue = dateStr( this.options.date, this ) + 'T' + timeStr( this.options.date, this );
361                                         break;
362                                 }
363                         }
364                         return rvalue;
365                 },
366
367                 setValue: function ( newdate ) {
368                         console.warn( "setValue was deprecated. use datetimepicker('option', 'date', value) instead." );
369                         return this.value( newdate );
370                 },
371
372                 /**
373                  * return W3C DTF string
374                  */
375                 getValue: function () {
376                         console.warn("getValue() was deprecated. use datetimepicker('value') instead.");
377                         return this.value();
378                 },
379
380                 _updateField: function ( target, value ) {
381                         if ( !target || target.length == 0 ) {
382                                 return;
383                         }
384
385                         if ( value == 0 ) {
386                                 value = "0";
387                         }
388
389                         var pat = target.jqmData( 'pat' ),
390                                 hour,
391                                 text;
392                         switch ( pat ) {
393                         case 'H':
394                         case 'HH':
395                         case 'h':
396                         case 'hh':
397                                 hour = value;
398                                 if ( pat.charAt(0) == 'h' ) {
399                                         if ( hour > 12 ) {
400                                                 hour -= 12;
401                                         } else if ( hour == 0 ) {
402                                                 hour = 12;
403                                         }
404                                 }
405                                 hour = this._makeTwoDigits( hour );
406                                 text = hour;
407                                 break;
408                         case 'm':
409                         case 'M':
410                         case 'd':
411                         case 's':
412                                 text = value;
413                                 break;
414                         case 'mm':
415                         case 'dd':
416                         case 'MM':
417                         case 'ss':
418                                 text = this._makeTwoDigits( value );
419                                 break;
420                         case 'MMM':
421                                 text = this._calendar().months.namesAbbr[ value - 1];
422                                 break;
423                         case 'MMMM':
424                                 text = this._calendar().months.names[ value - 1 ];
425                                 break;
426                         case 'yy':
427                                 text = this._makeTwoDigits( value % 100 );
428                                 break;
429                         case 'yyyy':
430                                 if ( value < 10 ) {
431                                         value = '000' + value;
432                                 } else if ( value < 100 ) {
433                                         value = '00' + value;
434                                 } else if ( value < 1000 ) {
435                                         value = '0' + value;
436                                 }
437                                 text = value;
438                                 break;
439                         }
440
441                         // to avoid reflow where its value isn't out-dated
442                         if ( target.text() != text ) {
443                                 if ( target.hasClass("ui-datefield-selected") ) {
444                                         target.addClass("out");
445
446                                         target.animationComplete( function () {
447                                                 target.text( text );
448                                                 target.addClass("in")
449                                                         .removeClass("out");
450
451                                                 target.animationComplete( function () {
452                                                         target.removeClass("in");
453                                                 });
454                                         });
455                                 } else {
456                                         target.text( text );
457                                 }
458                         }
459                 },
460
461                 _switchAmPm: function ( obj ) {
462                         if ( this._calendar().AM != null ) {
463                                 var date = new Date( this.options.date ),
464                                         text,
465                                         change = 1000 * 60 * 60 * 12;
466                                 if ( date.getHours() > 11 ) {
467                                         change = -change;
468                                 }
469                                 date.setTime( date.getTime() + change );
470                                 this._setDate( date );
471                         }
472                 },
473
474                 _parsePattern: function ( pattern ) {
475                         var regex = /\/|\s|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|f|gg|g|\'[\w\W]*\'$|[\w\W]/g,
476                                 matches,
477                                 i;
478
479                         matches = pattern.match( regex );
480
481                         for ( i = 0; i < matches.length; i++ ) {
482                                 if ( matches[i].charAt(0) == "'" ) {
483                                         matches[i] = matches[i].substr( 1, matches[i].length - 2 );
484                                 }
485                         }
486
487                         return matches;
488                 },
489
490                 changeTypeFormat: function ( type, format ) {
491                         console.warn('changeTypeFormat() was deprecated. use datetimepicker("option", "type"|"format", value) instead');
492                         if ( type ) {
493                                 this._setType( type );
494                         }
495
496                         if ( format ) {
497                                 this._setFormat( format );
498                         }
499                 },
500
501                 _create: function () {
502                         var obj = this;
503
504                         if ( this.element.is( "input" ) ) {
505                                 ( function ( obj ) {
506                                         var type, value, format;
507
508                                         type = obj.element.get(0).getAttribute( "type" );
509                                         obj.options.type = type;
510
511                                         value = obj.element.get(0).getAttribute( "value" );
512                                         if ( value ) {
513                                                 obj.options.date = new Date( value );
514                                         }
515                                 }( this ) );
516                         }
517
518                         if ( !this.options.format ) {
519                                 switch ( this.options.type ) {
520                                 case 'datetime':
521                                         this.options.format = this._calendar().patterns.d + "\t" + this._calendar().patterns.t;
522                                         break;
523                                 case 'date':
524                                         this.options.format = this._calendar().patterns.d;
525                                         break;
526                                 case 'time':
527                                         this.options.format = this._calendar().patterns.t;
528                                         break;
529                                 }
530                         }
531
532                         if ( !this.options.date ) {
533                                 this.options.date = new Date();
534                         }
535
536                         this.element.hide();
537                         this.ui = $('<div class="ui-datefield"></div>');
538                         $(this.element).after( this.ui );
539
540                         this.ui.bind('vclick', function ( e ) {
541                                 obj._showDataSelector( obj, this, e.target );
542                         });
543                 },
544
545                 _populateDataSelector: function ( field, pat ) {
546                         var values,
547                                 numItems,
548                                 current,
549                                 data,
550                                 range = window.range,
551                                 local,
552                                 yearlb,
553                                 yearhb,
554                                 day;
555
556                         switch ( field ) {
557                         case 'hour':
558                                 if ( pat == 'H' || pat == 'HH' ) {
559                                         // twentyfour
560                                         values = range( 0, 23 );
561                                         data = range( 0, 23 );
562                                         current = this.options.date.getHours();
563                                 } else {
564                                         values = range( 1, 12 );
565                                         current = this.options.date.getHours() - 1;//11
566                                         if ( current >= 11 ) {
567                                                 current = current - 12;
568                                                 data = range( 13, 23 );
569                                                 data.push( 12 ); // consider 12:00 am as 00:00
570                                         } else {
571                                                 data = range( 1, 11 );
572                                                 data.push( 0 );
573                                         }
574                                         if ( current < 0 ) {
575                                                 current = 11; // 12:00 or 00:00
576                                         }
577                                 }
578                                 if ( pat.length == 2 ) {
579                                         // two digit
580                                         values = values.map( this._makeTwoDigits );
581                                 }
582                                 numItems = values.length;
583                                 break;
584                         case 'min':
585                         case 'sec':
586                                 values = range( 0, 59 );
587                                 if ( pat.length == 2 ) {
588                                         values = values.map( this._makeTwoDigits );
589                                 }
590                                 data = range( 0, 59 );
591                                 current = ( field == 'min' ? this.options.date.getMinutes() : this.options.date.getSeconds() );
592                                 numItems = values.length;
593                                 break;
594                         case 'year':
595                                 yearlb = 1900;
596                                 yearhb = 2100;
597                                 data = range( yearlb, yearhb );
598                                 current = this.options.date.getFullYear() - yearlb;
599                                 values = range( yearlb, yearhb );
600                                 numItems = values.length;
601                                 break;
602                         case 'month':
603                                 switch ( pat.length ) {
604                                 case 1:
605                                         values = range( 1, 12 );
606                                         break;
607                                 case 2:
608                                         values = range( 1, 12 ).map( this._makeTwoDigits );
609                                         break;
610                                 case 3:
611                                         values = this._calendar().months.namesAbbr.slice();
612                                         break;
613                                 case 4:
614                                         values = this._calendar().months.names.slice();
615                                         break;
616                                 }
617                                 if ( values.length == 13 ) { // @TODO Lunar calendar support
618                                         if ( values[12] == "" ) { // to remove lunar calendar reserved space
619                                                 values.pop();
620                                         }
621                                 }
622                                 data = range( 1, values.length );
623                                 current = this.options.date.getMonth();
624                                 numItems = values.length;
625                                 break;
626                         case 'day':
627                                 day = this._daysInMonth[ this.options.date.getMonth() ];
628                                 if ( day == 28 ) {
629                                         day += this._isLeapYear( this.options.date.getFullYear() );
630                                 }
631                                 values = range( 1, day );
632                                 if ( pat.length == 2 ) {
633                                         values = values.map( this._makeTwoDigits );
634                                 }
635                                 data = range( 1, day );
636                                 current = this.options.date.getDate() - 1;
637                                 numItems = day;
638                                 break;
639                         }
640
641                         return {
642                                 values: values,
643                                 data: data,
644                                 numItems: numItems,
645                                 current: current
646                         };
647
648                 },
649
650                 _showDataSelector: function ( obj, ui, target ) {
651                         target = $(target);
652
653                         var attr = target.attr("class"),
654                                 field = attr ? attr.match(/ui-datefield-([\w]*)/) : undefined,
655                                 pat,
656                                 data,
657                                 values,
658                                 numItems,
659                                 current,
660                                 valuesData,
661                                 html,
662                                 datans,
663                                 $ul,
664                                 $div,
665                                 $ctx,
666                                 $li,
667                                 i,
668                                 newLeft = 10;
669
670                         if ( !attr ) {
671                                 return;
672                         }
673                         if ( !field ) {
674                                 return;
675                         }
676
677                         target.not('.ui-datefield-seperator').addClass('ui-datefield-selected');
678
679                         pat = target.jqmData('pat');
680                         data = obj._populateDataSelector.call( obj, field[1], pat );
681
682                         values = data.values;
683                         numItems = data.numItems;
684                         current = data.current;
685                         valuesData = data.data;
686
687                         if ( values ) {
688                                 datans = "data-" + ($.mobile.ns ? ($.mobile.ns + '-') : "") + 'val="';
689                                 for ( i = 0; i < values.length; i++ ) {
690                                         html += '<li><a class="ui-link" ' + datans + valuesData[i] + '">' + values[i] + '</a></li>';
691                                 }
692
693                                 $ul = $("<ul></ul>");
694                                 $div = $('<div class="ui-datetimepicker-selector" data-transition="fade" data-fade="false"></div>');
695                                 $div.append( $ul ).appendTo( ui );
696                                 $ctx = $div.ctxpopup();
697                                 $ctx.parents('.ui-popupwindow').addClass('ui-datetimepicker');
698                                 $li = $(html);
699                                 $( $li[current] ).addClass("current");
700                                 $div.jqmData( "list", $li );
701                                 $div.circularview();
702                                 // cause ctxpopup forced to subtract 10
703                                 if ( $( window ).width() / 2 < target.offset().left ) {
704                                         newLeft = -10;
705                                 }
706                                 $ctx.popupwindow( 'open',
707                                                 target.offset().left + ( target.width() / 2 ) + newLeft - window.pageXOffset ,
708                                                 target.offset().top + target.height() - window.pageYOffset );
709                                 $div.bind('popupafterclose', function ( e ) {
710                                         if ( obj._reflow ) {
711                                                 $(window).unbind("resize", obj._reflow);
712                                                 obj._reflow = null;
713                                         }
714                                         $div.unbind( 'popupafterclose' );
715                                         $ul.unbind( 'vclick' );
716                                         $(obj).unbind( 'update' );
717                                         $(ui).find('.ui-datefield-selected').removeClass('ui-datefield-selected');
718                                         $ctx.popupwindow( 'destroy' );
719                                         $div.remove();
720                                 });
721
722                                 $(obj).bind( 'update', function ( e, val ) {
723                                         var date = new Date( this.options.date );
724
725                                         switch ( field[1] ) {
726                                         case 'min':
727                                                 date.setMinutes( val );
728                                                 break;
729                                         case 'hour':
730                                                 date.setHours( val );
731                                                 break;
732                                         case 'sec':
733                                                 date.setSeconds( val );
734                                                 break;
735                                         case 'year':
736                                                 date.setFullYear( val );
737                                                 break;
738                                         case 'month':
739                                                 date.setMonth( val - 1 );
740
741                                                 if ( date.getMonth() == val ) {
742                                                         date.setDate( 1 );
743                                                         date.setDate( date.getDate() - 1 );
744                                                 }
745                                                 break;
746                                         case 'day':
747                                                 date.setDate( val );
748                                                 break;
749                                         }
750
751                                         obj._setDate( date );
752                                 });
753
754                                 $ul.bind( 'click', function ( e ) {
755                                         if ( $(e.target).is('a') ) {
756                                                 $ul.find(".current").removeClass("current");
757                                                 $(e.target).parent().addClass('current');
758                                                 var val = $(e.target).jqmData("val");
759                                                 $(obj).trigger( 'update', val ); // close popup, unselect field
760                                         }
761                                 });
762
763                                 $div.circularview( 'centerTo', '.current', 500 );
764                                 $div.bind( 'scrollend' , function ( e ) {
765                                         if ( !obj._reflow ) {
766                                                 obj._reflow = function () {
767                                                         $div.circularview("reflow");
768                                                 };
769                                                 $(window).bind("resize", obj._reflow);
770                                         }
771                                 });
772                         }
773                         return ui;
774                 }
775
776         });
777
778         $(document).bind("pagecreate create", function ( e ) {
779                 $($.tizen.datetimepicker.prototype.options.initSelector, e.target)
780                         .not(":jqmData(role='none'), :jqmData(role='nojs')")
781                         .datetimepicker();
782         });
783
784 } ( jQuery, this ) );