persian_datepicker_js 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 126be5b345c4fa29c08b23848f3cacb06363ccc5
4
+ data.tar.gz: 63622a12e57d8d592df3c2ede134b4e619640272
5
+ SHA512:
6
+ metadata.gz: 74f126f17cb2f072af3767f5388a3b175b66919485dc959c152f7eac97d534353965f46a74980b4f37445148322582d1338443ad0d7834ff66b7826bec069533
7
+ data.tar.gz: 5883970914a19724f9c3ac105aadb2f5416e62bd265ce7dc38473252437ce5a32f7a0b0c18fed21c0fe27ae3c636bff67f8366602d816267ed20e08c7e01149b
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in persian_datepicker_js.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Pouya Gharib Pour
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,42 @@
1
+ # PersianDatepickerJs
2
+
3
+ A gem for adding PersianDatepicker(0.4.5) JS library to your Rails project.
4
+
5
+ This gem requires that you have [PersianDate](https://github.com/babakhani/PersianDate) installed. You could use [persian_date_js](https://rubygems.org/gems/persian_date_js) gem.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'persian_datepicker_js'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install persian_datepicker_js
22
+
23
+ Then add the following line to your **application.js** file:
24
+
25
+ ```javascript
26
+ //= require persian_datepicker_js_main
27
+ ```
28
+
29
+ Then add the following line to your **application.css** file:
30
+
31
+ ```sass
32
+ *= require persian_datepicker_js_main
33
+ ```
34
+
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork it ( https://github.com/psparabara/persian_datepicker_js/fork )
39
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
40
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
41
+ 4. Push to the branch (`git push origin my-new-feature`)
42
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,4027 @@
1
+ /*
2
+ persian-datepicker - v0.4.5
3
+ Author: reza babakhani
4
+ http://babakhani.github.io/PersianWebToolkit/datepicker
5
+ */
6
+ ( function () {(function ($) {
7
+ $.fn.persianDatepicker = $.fn.pDatepicker = function (options) {
8
+ var args = Array.prototype.slice.call(arguments), output = this;
9
+ if (!this) {
10
+ $.error("Invalid selector");
11
+ }
12
+ $(this).each(function () {
13
+ // encapsulation Args
14
+ var emptyArr = new Array, tempArg = args.concat(emptyArr), dp = $(this).data("datepicker");
15
+ if (dp && typeof tempArg[0] == "string") {
16
+ var funcName = tempArg[0], funcArgs = tempArg.splice(0, 1);
17
+ output = dp[funcName](tempArg[0]);
18
+ } else {
19
+ this.pDatePicker = new Datepicker(this, options);
20
+ }
21
+ });
22
+ return output;
23
+ };
24
+ })(jQuery);
25
+ var ClassConfig = {
26
+
27
+
28
+ /**
29
+ * @memberOf ClassDatepicker.ClassConfig
30
+ * @description if true all digit convert to persian digit.
31
+ * @type {boolean}
32
+ * @default true
33
+ */
34
+ persianDigit: true,
35
+
36
+
37
+ /**
38
+ * @memberOf ClassDatepicker.ClassConfig
39
+ * @description Acceptable value : day,month,year
40
+ * @property viewMode
41
+ * @type {string}
42
+ * @default day
43
+ */
44
+ viewMode: false,
45
+
46
+
47
+ /**
48
+ * @memberOf ClassDatepicker.ClassConfig
49
+ * @description [x,y] , define a position of datepicker relative to input element.
50
+ * @property position
51
+ * @type {string|Array}
52
+ * @default auto
53
+ */
54
+ position: "auto",
55
+
56
+
57
+ /**
58
+ * @memberOf ClassDatepicker.ClassConfig
59
+ * @description If true picker close When Select day
60
+ * @property autoClose
61
+ * @type {boolean}
62
+ * @default false
63
+ */
64
+ autoClose: false,
65
+
66
+
67
+ /**
68
+ * @memberOf ClassDatepicker.ClassConfig
69
+ * @description the date format, combination of d, dd, m, mm, yy, yyy.
70
+ * {@link http://babakhani.github.io/PersianWebToolkit/doc/persiandate/0.1.8/#/displaying/format/}
71
+ * @desc format
72
+ * @type {boolean}
73
+ * @default false
74
+ */
75
+ format: false,
76
+
77
+
78
+ /**
79
+ * @memberOf ClassDatepicker.ClassConfig
80
+ * @desc observer
81
+ * @type {boolean}
82
+ * @default false
83
+ */
84
+ observer: false,
85
+
86
+
87
+ /**
88
+ * @memberOf ClassDatepicker.ClassConfig
89
+ * @desc inputDelay
90
+ * @type {number}
91
+ * @default 800
92
+ */
93
+ inputDelay: 800,
94
+
95
+ /**
96
+ * @memberOf ClassDatepicker.ClassConfig
97
+ * @desc format value of input
98
+ * @param unixDate
99
+ * @returns {*}
100
+ */
101
+ formatter: function (unixDate) {
102
+ var self = this;
103
+ var pdate = new persianDate(unixDate);
104
+ pdate.formatPersian = false;
105
+ return pdate.format(self.format);
106
+ },
107
+
108
+
109
+ /**
110
+ * @memberOf ClassDatepicker.ClassConfig
111
+ * @description An input element that is to be updated with the selected date from the datepicker. Use the altFormat option to change the format of the date within this field. Leave as blank for no alternate field. acceptable value: : '#elementId','.element-class'
112
+ * @desc altField
113
+ * @type {boolean}
114
+ * @default false
115
+ */
116
+ altField: false,
117
+
118
+
119
+ /**
120
+ * @memberOf ClassDatepicker.ClassConfig
121
+ * @description the date format, combination of d, dd, m, mm, yy, yyy.
122
+ * {@link http://babakhani.github.io/PersianWebToolkit/doc/persiandate/0.1.8/#/displaying/format/}
123
+ * @desc altField
124
+ * @type {string}
125
+ * @default unix
126
+ */
127
+ altFormat: 'unix',
128
+
129
+
130
+ /**
131
+ * @memberOf ClassDatepicker.ClassConfig
132
+ * @desc format value of 'altField' input
133
+ * @param unixDate
134
+ * @returns {*}
135
+ */
136
+ altFieldFormatter: function (unixDate) {
137
+ var self = this;
138
+ var thisAltFormat = self.altFormat.toLowerCase();
139
+ if (thisAltFormat === "gregorian" | thisAltFormat === "g") {
140
+ return new Date(unixDate);
141
+ }
142
+ if (thisAltFormat === "unix" | thisAltFormat === "u") {
143
+ return unixDate;
144
+ }
145
+ else {
146
+ return new persianDate(unixDate).format(self.altFormat);
147
+ }
148
+ },
149
+
150
+
151
+ /**
152
+ * @memberOf ClassDatepicker.ClassConfig
153
+ * @desc Open the date picker.
154
+ * @method
155
+ * @returns {ClassConfig}
156
+ */
157
+ show: function () {
158
+ this.view.fixPosition(this);
159
+ this.element.main.show();
160
+ this.onShow(this);
161
+ this._viewed = true;
162
+ return this;
163
+ },
164
+
165
+
166
+ /**
167
+ * @memberOf ClassDatepicker.ClassConfig
168
+ * @desc Hide the date picker
169
+ * @method
170
+ * @returns {ClassConfig}
171
+ */
172
+ hide: function () {
173
+ if (this._viewed) {
174
+ this.element.main.hide();
175
+ this.onHide(this);
176
+ this._viewed = false;
177
+ }
178
+ return this;
179
+ },
180
+
181
+ /**
182
+ * @memberOf ClassDatepicker.ClassConfig
183
+ * @desc Removes the datepicker functionality completely.
184
+ * @method
185
+ * @param self
186
+ */
187
+ destroy: function () {
188
+ this.inputElem.removeClass(self.cssClass);
189
+ this.elmenet.main.remove();
190
+ },
191
+
192
+
193
+ /**
194
+ * @memberOf ClassDatepicker.ClassConfig
195
+ * @desc A function that takes current datepicker instance. It is called just before the datepicker is displayed.
196
+ * @event
197
+ * @param self
198
+ */
199
+ onShow: function (self) {
200
+ },
201
+
202
+
203
+ /**
204
+ * @memberOf ClassDatepicker.ClassConfig
205
+ * @desc A function that takes current datepicker instance. It is called just before the datepicker Hide.
206
+ * @event
207
+ * @param self
208
+ */
209
+ onHide: function (self) {
210
+ },
211
+
212
+
213
+ /**
214
+ * @memberOf ClassDatepicker.ClassConfig
215
+ * @desc A function that takes current datepicker unixDate. It is called When Day Select.
216
+ * @event
217
+ * @param unixDate
218
+ */
219
+ onSelect: function (unixDate) {
220
+ return this;
221
+ },
222
+
223
+ /**
224
+ * @see ClassNavigator
225
+ * @memberOf ClassDatepicker.ClassConfig
226
+ * @desc navigator config object
227
+ * @property navigator
228
+ * @type {object}
229
+ * @default true
230
+ */
231
+ navigator: {
232
+ /**
233
+ * @desc Enable or Disable dayPicker
234
+ */
235
+ enabled: true,
236
+
237
+
238
+ /**
239
+ * @desc navigator text config object
240
+ */
241
+ text: {
242
+ /**
243
+ * @desc text of next btn
244
+ */
245
+ btnNextText: "<",
246
+
247
+
248
+ /**
249
+ * @desc text of prev btn
250
+ */
251
+ btnPrevText: ">"
252
+ },
253
+
254
+
255
+ /**
256
+ * @desc Trigger When Next button clicked
257
+ * @event
258
+ * @param navigator
259
+ */
260
+ onNext: function (navigator) {
261
+ //log("navigator next ");
262
+ },
263
+
264
+
265
+ /**
266
+ * @desc Trigger When Prev button clicked
267
+ * @event
268
+ * @param navigator
269
+ */
270
+ onPrev: function (navigator) {
271
+ //log("navigator prev ");
272
+ },
273
+
274
+
275
+ /**
276
+ * @desc Trigger When Switch view button clicked
277
+ * @event
278
+ * @param navigator
279
+ */
280
+ onSwitch: function (state) {
281
+ // console.log("navigator switch ");
282
+ }
283
+ },
284
+
285
+ /**
286
+ * @see ClassToolbox
287
+ * @memberOf ClassDatepicker.ClassConfig
288
+ * @desc toolbox config object
289
+ * @property toolbox
290
+ * @type {object}
291
+ * @default true
292
+ * @deprecated 0.2.3
293
+ */
294
+ toolbox: {
295
+ enabled: true,
296
+ text: {
297
+ btnToday: "امروز"
298
+ },
299
+ onToday: function (toolbox) {
300
+ //log("toolbox today btn");
301
+ }
302
+ },
303
+
304
+
305
+ /**
306
+ * @see ClassTimePicker
307
+ * @memberOf ClassDatepicker.ClassConfig
308
+ * @desc timepicker config object
309
+ * @property timePicker
310
+ * @type {object}
311
+ */
312
+ timePicker: {
313
+ enabled: false,
314
+ showSeconds: true,
315
+ showMeridian: true,
316
+
317
+ secondStep: 1,
318
+ minuteStep: 1,
319
+ hourStep: 1,
320
+
321
+ scrollEnabled: true,
322
+ /**
323
+ * @deprecated 0.3.5
324
+ */
325
+ changeOnScroll: true
326
+ },
327
+
328
+ /**
329
+ * @see ClassDayPicker
330
+ * @memberOf ClassDatepicker.ClassConfig
331
+ * @desc dayPicker config object
332
+ * @property dayPicker
333
+ * @type {object}
334
+ */
335
+ dayPicker: {
336
+ enabled: true,
337
+ scrollEnabled: true,
338
+ titleFormat: 'YYYY MMMM',
339
+ titleFormatter: function (year, month) {
340
+ if (this.datepicker.persianDigit == false) {
341
+ window.formatPersian = false;
342
+ }
343
+ var titleStr = new persianDate([year, month]).format(this.titleFormat);
344
+ window.formatPersian = true;
345
+ return titleStr
346
+ },
347
+ onSelect: function (selectedDayUnix) {
348
+ //log("daypicker month day :" + selectedDayUnix);
349
+ }
350
+
351
+ },
352
+
353
+ /**
354
+ * @see ClassMonthPicker
355
+ * @memberOf ClassDatepicker.ClassConfig
356
+ * @desc monthPicker config object
357
+ * @property monthPicker
358
+ * @type {object}
359
+ */
360
+ monthPicker: {
361
+ enabled: true,
362
+ scrollEnabled: true,
363
+ titleFormat: 'YYYY',
364
+ titleFormatter: function (unix) {
365
+ if (this.datepicker.persianDigit == false) {
366
+ window.formatPersian = false;
367
+ }
368
+ var titleStr = new persianDate(unix).format(this.titleFormat);
369
+ window.formatPersian = true;
370
+ return titleStr;
371
+
372
+ },
373
+ onSelect: function (monthIndex) {
374
+ //log("daypicker select day :" + monthIndex);
375
+ }
376
+ },
377
+
378
+
379
+ /**
380
+ * @see ClassYearPicker
381
+ * @memberOf ClassDatepicker.ClassConfig
382
+ * @desc yearPicker config object
383
+ * @property yearPicker
384
+ * @type {object}
385
+ */
386
+ yearPicker: {
387
+ enabled: true,
388
+ scrollEnabled: true,
389
+ titleFormat: 'YYYY',
390
+ titleFormatter: function (year) {
391
+ var remaining = parseInt(year / 12) * 12;
392
+ return remaining + "-" + (remaining + 11);
393
+ },
394
+ onSelect: function (monthIndex) {
395
+ //log("daypicker select Year :" + monthIndex);
396
+ }
397
+ },
398
+
399
+
400
+ /**
401
+ * @memberOf ClassDatepicker.ClassConfig
402
+ * @desc if true all pickers hide and just shpw timepicker
403
+ * @property justSelectOnDate
404
+ * @type {boolean}
405
+ */
406
+ onlyTimePicker: false,
407
+
408
+
409
+ /**
410
+ * @memberOf ClassDatepicker.ClassConfig
411
+ * @desc if true date select just by click on day in month grid
412
+ * @property justSelectOnDate
413
+ * @type {boolean}
414
+ */
415
+ justSelectOnDate: true,
416
+
417
+
418
+ /**
419
+ * @memberOf ClassDatepicker.ClassConfig
420
+ * @desc set min date on datepicker
421
+ * @property minDate
422
+ * @type {boolean}
423
+ */
424
+ minDate: false,
425
+
426
+
427
+ /**
428
+ * @memberOf ClassDatepicker.ClassConfig
429
+ * @desc set max date on datepicker
430
+ * @property maxDate
431
+ * @type {boolean}
432
+ */
433
+ maxDate: false,
434
+
435
+
436
+ /**
437
+ * @memberOf ClassDatepicker.ClassConfig
438
+ * @desc check date avalibility
439
+ * @property unix
440
+ * @type {function}
441
+ */
442
+ checkDate: function (unix) {
443
+ return true;
444
+ },
445
+
446
+
447
+ /**
448
+ * @memberOf ClassDatepicker.ClassConfig
449
+ * @desc check month avalibility
450
+ * @property month index
451
+ * @type {function}
452
+ */
453
+ checkMonth: function (month) {
454
+ return true;
455
+ },
456
+
457
+
458
+ /**
459
+ * @memberOf ClassDatepicker.ClassConfig
460
+ * @desc check year avalibility
461
+ * @property year
462
+ * @type {function}
463
+ */
464
+ checkYear: function (year) {
465
+ return true;
466
+ }
467
+
468
+
469
+ }
470
+ var ClassDateRange = {
471
+ /**
472
+ * @property monthRange
473
+ */
474
+ monthRange: {
475
+ 1: {
476
+ name: {
477
+ fa: "فروردین"
478
+ },
479
+ abbr: {
480
+ fa: "فرو"
481
+ }
482
+ },
483
+ 2: {
484
+ name: {
485
+ fa: "اردیبهشت"
486
+ },
487
+ abbr: {
488
+ fa: "ارد"
489
+ }
490
+ },
491
+ 3: {
492
+ name: {
493
+ fa: "خرداد"
494
+ },
495
+ abbr: {
496
+ fa: "خرد"
497
+ }
498
+ },
499
+ 4: {
500
+ name: {
501
+ fa: "تیر"
502
+ },
503
+ abbr: {
504
+ fa: "تیر"
505
+ }
506
+ },
507
+ 5: {
508
+ name: {
509
+ fa: "مرداد"
510
+ },
511
+ abbr: {
512
+ fa: "مرد"
513
+ }
514
+ },
515
+ 6: {
516
+ name: {
517
+ fa: "شهریور"
518
+ },
519
+ abbr: {
520
+ fa: "شهر"
521
+ }
522
+ },
523
+ 7: {
524
+ name: {
525
+ fa: "مهر"
526
+ },
527
+ abbr: {
528
+ fa: "مهر"
529
+ }
530
+ },
531
+ 8: {
532
+ name: {
533
+ fa: "آبان"
534
+ },
535
+ abbr: {
536
+ fa: "آبا"
537
+ }
538
+
539
+ },
540
+ 9: {
541
+ name: {
542
+ fa: "آذر"
543
+ },
544
+ abbr: {
545
+ fa: "آذر"
546
+ }
547
+ },
548
+ 10: {
549
+ name: {
550
+ fa: "دی"
551
+ },
552
+ abbr: {
553
+ fa: "دی"
554
+ }
555
+ },
556
+ 11: {
557
+ name: {
558
+ fa: "بهمن"
559
+ },
560
+ abbr: {
561
+ fa: "بهم"
562
+ }
563
+ },
564
+ 12: {
565
+ name: {
566
+ fa: "اسفند"
567
+ },
568
+ abbr: {
569
+ fa: "اسف"
570
+ }
571
+ }
572
+ },
573
+
574
+
575
+ /**
576
+ * @property weekRange
577
+ */
578
+ weekRange: {
579
+ 0: {
580
+ name: {
581
+ fa: "شنبه"
582
+ },
583
+ abbr: {
584
+ fa: "ش"
585
+ }
586
+ },
587
+ 1: {
588
+ name: {
589
+ fa: "یکشنبه"
590
+ },
591
+ abbr: {
592
+ fa: "ی"
593
+ }
594
+ },
595
+ 2: {
596
+ name: {
597
+ fa: "دوشنبه"
598
+ },
599
+ abbr: {
600
+ fa: "د"
601
+ }
602
+ },
603
+ 3: {
604
+ name: {
605
+ fa: "سه شنبه"
606
+ },
607
+ abbr: {
608
+ fa: "س"
609
+ }
610
+ },
611
+ 4: {
612
+ name: {
613
+ fa: "چهار شنبه"
614
+ },
615
+ abbr: {
616
+ fa: "چ"
617
+ }
618
+ },
619
+ 5: {
620
+ name: {
621
+ fa: "پنج شنبه"
622
+ },
623
+ abbr: {
624
+ fa: "پ"
625
+ }
626
+ },
627
+ 6: {
628
+ name: {
629
+ fa: "جمعه"
630
+ },
631
+ abbr: {
632
+ fa: "ج"
633
+ }
634
+ }
635
+ },
636
+
637
+
638
+ /**
639
+ * @property persianDaysName
640
+ */
641
+ persianDaysName: ["اورمزد", "بهمن", "اوردیبهشت", "شهریور", "سپندارمذ", "خورداد", "امرداد", "دی به آذز", "آذز", "آبان", "خورشید", "ماه", "تیر", "گوش", "دی به مهر", "مهر", "سروش", "رشن", "فروردین", "بهرام", "رام", "باد", "دی به دین", "دین", "ارد", "اشتاد", "آسمان", "زامیاد", "مانتره سپند", "انارام", "زیادی"]
642
+ };
643
+
644
+ var TEMPLATE = {
645
+ /**
646
+ * @desc datepicker
647
+ */
648
+ datepciker: "<div class='{{css.datePickerPlotArea}}' >" + //
649
+ "<div class='{{css.navigator}}' ></div>" +//
650
+ " <div class='{{css.dayView}}' ></div>" + //
651
+ "<div class='{{css.monthView}}' ></div>" + //
652
+ "<div class='{{css.yearView}}' ></div>" + //
653
+ "<div class='{{css.timeView}}' ></div>" + //
654
+ "<div class='{{css.toolbox}}' ></div>" + //
655
+ "</div>",
656
+
657
+
658
+ /**
659
+ * @desc navigator
660
+ */
661
+ navigator: "<div class='{{css.datpickerHeader}}' >" + //
662
+ "<div class='{{css.btnNext}}' >{{btnNextText}}</div>" + //
663
+ "<div class='{{css.btnSwitch}}' >{{btnSwitchText}}</div>" + //
664
+ "<div class='{{css.btnPrev}}' >{{btnPrevText}}</div>" + //
665
+ "</div>",
666
+
667
+
668
+ /**
669
+ * @desc timepicker
670
+ */
671
+ timepicker: "<div class='hour time-segment' data-time-key='hour' >" + //
672
+ "<div class='up-btn' >&#9650;</div>" + //
673
+ "<input type='text' placeholder='hour' class='hour-input' />" + //
674
+ "<div class='down-btn' >&#9660;</div>" + //
675
+ "</div>" + //
676
+ "<div class='divider' >:</div>" + //
677
+ "<div class='minute time-segment' data-time-key='minute' >" + //
678
+ "<div class='up-btn' >&#9650;</div>" + //
679
+ "<input type='text' placeholder='minute' class='minute-input' />" + //
680
+ "<div class='down-btn' >&#9660;</div>" + //
681
+ "</div>" + //
682
+ "<div class='divider second-divider' >:</div>" + //
683
+ "<div class='second time-segment' data-time-key='second' >" + //
684
+ "<div class='up-btn' >&#9650;</div>" + //
685
+ "<input type='text' placeholder='second' class='second-input' />" + //
686
+ "<div class='down-btn' >&#9660;</div>" + //
687
+ "</div>" + //
688
+ "<div class='divider meridian-divider' ></div>" + //
689
+ "<div class='divider meridian-divider' ></div>" + //
690
+ "<div class='meridian time-segment' data-time-key='meridian' >" + //
691
+ "<div class='up-btn' >&#9650;</div>" + //
692
+ "<input type='text' placeholder='meridian&' class='meridian-input' />" + //
693
+ "<div class='down-btn' >&#9660;</div>" + //
694
+ "</div>",
695
+
696
+ /**
697
+ * @desc Month Grid
698
+ */
699
+ monthGrid: "<div class='{{css.main}}' >" + //
700
+ "<div class='{{css.header}}' >" + //
701
+ "<div class='{{css.headerTitle}}' ></div>" + //
702
+ "<div class='{{css.headerRow}}' ></div>" + //
703
+ "</div>" + //
704
+ "<table cellspacing='0' class='{{css.daysTable}}' ><tbody><tr><td /><td/><td/><td/><td/><td/><td/></tr><tr><td/><td/><td/><td/><td/><td/><td/></tr><tr><td/><td/><td/><td/><td/><td/><td/></tr><tr><td/><td/><td/><td/><td/><td/><td/></tr><tr><td/><td/><td/><td/><td/><td/><td/></tr><tr><td/><td/><td/><td/><td/><td/><td/></tr></tbody></table>" + //
705
+ "</div>"
706
+ }
707
+ 'use strict';
708
+ /**
709
+ * @class ClassBase
710
+ * @abstract
711
+ * @type {{init: init, publishInDic: publishInDic, callOfDict: callOfDict, isSameDay: isSameDay, isValidGreguranDate: isValidGreguranDate, validatePersianDateString: validatePersianDateString, fullHeight: fullHeight, attachEvent: attachEvent, dettachEvent: dettachEvent, clearEvent: clearEvent, raiseEvent: raiseEvent, events: {init: null}}}
712
+ */
713
+ var ClassBase = {
714
+ /**
715
+ * @desc initilize {@link ClassBase}
716
+ * @private
717
+ */
718
+ init: function () {
719
+ this.isInstance = true;
720
+ this.raiseEvent('init');
721
+ },
722
+
723
+
724
+ /**
725
+ *
726
+ * @param {Array} objectList
727
+ * @param {string} methodName
728
+ * @returns {*}
729
+ */
730
+ publishInDic: function (objectList, methodName) {
731
+ $.each(objectList, function (key, item) {
732
+ item[methodName]();
733
+ });
734
+ return objectList;
735
+ },
736
+
737
+
738
+ /**
739
+ *
740
+ * @param {Array} objectList
741
+ * @param {string} key
742
+ * @param {string} methodName
743
+ */
744
+ callOfDict: function (objectList, key, methodName) {
745
+ },
746
+
747
+
748
+ /**
749
+ *
750
+ * @param {Numer} unix1
751
+ * @param {Numer} unix2
752
+ * @returns {pDate|boolean}
753
+ */
754
+ isSameDay: function (unix1, unix2) {
755
+ var d1 = new pDate(unix1);
756
+ var d2 = new pDate(unix2);
757
+ return d1 && d2 &&
758
+ d1.year() === d2.year() &&
759
+ d1.month() === d2.month() &&
760
+ d1.date() === d2.date();
761
+ },
762
+
763
+
764
+ /**
765
+ * @param {string} inputDate
766
+ * @returns {*|boolean}
767
+ */
768
+ isValidGreguranDate: function (inputDate) {
769
+ return inputDate &&
770
+ new Date(inputDate) != "Invalid Date" &&
771
+ new Date(inputDate) != "undefined";
772
+ },
773
+
774
+
775
+ /**
776
+ *
777
+ * @param {string} pasted
778
+ * @returns {*}
779
+ */
780
+ validatePersianDateString: function (pasted) {
781
+ var newDate = new Date(pasted);
782
+ var inputArray = pasted.split("/");
783
+ if (inputArray.length === 3) {
784
+ var trueYear = inputArray[0].toString().length <= 4 && inputArray[0].toString().length >= 1;
785
+ var trueMonth = inputArray[1].toString().length <= 2 && inputArray[1].toString().length >= 1;
786
+ var trueDay = inputArray[2].toString().length <= 2 && inputArray[2].toString().length >= 1;
787
+ }
788
+ $.each(inputArray, function (index, key) {
789
+ inputArray[index] = parseInt(key);
790
+ });
791
+ if (trueYear && trueMonth && trueDay && newDate !== "Invalid Date") {
792
+ return inputArray;
793
+ } else {
794
+ return null;
795
+ }
796
+ },
797
+
798
+
799
+ /**
800
+ *
801
+ * @param {object} element
802
+ * @returns {*}
803
+ */
804
+ fullHeight: function (element) {
805
+ return $(element).height() + parseInt($(element).css("padding-top")) + parseInt($(element).css("padding-bottom")) + parseInt($(element).css("borderTopWidth")) + parseInt($(element).css("borderBottomWidth"));
806
+ },
807
+
808
+
809
+ /**
810
+ *
811
+ * @param {string} eventName
812
+ * @param {Function} func
813
+ * @returns {Class_Base}
814
+ */
815
+ attachEvent: function (eventName, func) {
816
+ if (!this.events[eventName]) {
817
+ this.events[eventName] = [];
818
+ }
819
+ var f;
820
+ for (f in this.events[eventName]) {
821
+ if (this.events[eventName][f].toString() == func.toString()) {
822
+ $.error("The function {0} was already added to event's chain.".format(func.toString));
823
+ }
824
+ }
825
+ this.events[eventName].push(func)
826
+ return this;
827
+ },
828
+
829
+
830
+ /**
831
+ *
832
+ * @param {string} eventName
833
+ * @param {Function} func
834
+ * @returns {Class_Base}
835
+ */
836
+ dettachEvent: function (eventName, func) {
837
+ if (!this.events[eventName]) {
838
+ $.error("The event's chain is empty.");
839
+ }
840
+ var f;
841
+ for (f in this.events[eventName]) {
842
+ if (this.events[eventName][f].toString() == func.toString()) {
843
+ delete this.events[eventName][f];
844
+ }
845
+ }
846
+ return this;
847
+ },
848
+
849
+
850
+ /**
851
+ * @param {string} eventName
852
+ * @returns {Class_Base}
853
+ */
854
+ clearEvent: function (eventName) {
855
+ this.events[eventName] = null;
856
+ return this;
857
+ },
858
+
859
+
860
+ /**
861
+ * @param eventName
862
+ * @param args
863
+ * @returns {Class_Base}
864
+ */
865
+ raiseEvent: function (eventName, args) {
866
+ if (!eventName || !this.events) {
867
+ return;
868
+ }
869
+ if (args) {
870
+ } else {
871
+ args = [];
872
+ }
873
+ var currentObject = this.events[eventName];
874
+ if (!currentObject) {
875
+ return;
876
+ } else if (typeof currentObject === 'function') {
877
+ currentObject.apply(this, args);
878
+ } else {
879
+ var e;
880
+ for (e in currentObject) {
881
+ currentObject[e].apply(this, args);
882
+ }
883
+ }
884
+ return this;
885
+ }
886
+ };
887
+
888
+
889
+ /**
890
+ * @class ClassSprite
891
+ * @abstract
892
+ * @type {{defaultView: string, events: {init: init, render: null}, views: {default: {render: render}}, element: {main: null}, createElementByClass: createElementByClass, render: render, tmpl: {}}}
893
+ */
894
+ var ClassSprite = {
895
+ /**
896
+ * @desc defaultView
897
+ */
898
+ defaultView: "default",
899
+
900
+
901
+ /**
902
+ * @desc events
903
+ */
904
+ events: {
905
+ init: function () {
906
+ this.render();
907
+ },
908
+ render: null
909
+ },
910
+
911
+
912
+ /**
913
+ * @desc views
914
+ */
915
+ views: {
916
+ 'default': {
917
+ render: function () {
918
+ }
919
+ }
920
+ },
921
+
922
+
923
+ /**
924
+ * @desc element
925
+ */
926
+ element: {
927
+ main: null// Root Element Of Sprite
928
+ },
929
+
930
+
931
+ /**
932
+ * @desc createElementByClass
933
+ * @param {string} className string of class
934
+ * @returns {*}
935
+ */
936
+ createElementByClass: function (className) {
937
+ return this.element.find('.' + className);
938
+ },
939
+
940
+
941
+ /**
942
+ * @desc render
943
+ * @param {string} viewName
944
+ * @returns {*}
945
+ */
946
+ render: function (viewName) {
947
+ if (!viewName) {
948
+ viewName = 'default';
949
+ }
950
+ this.raiseEvent('render');
951
+ this.view = this.views[viewName];
952
+ return this.view.render(this);
953
+ }
954
+ };
955
+
956
+
957
+ var ClassCompat = {
958
+ /**
959
+ * @memberOf ClassDatepicker.ClassCompat
960
+ * @returns {ClassDatepicker}
961
+ */
962
+ compatConfig: function () {
963
+ if (this.viewMode === false) {
964
+ if (this.yearPicker.enabled) {
965
+ this.viewMode = 'year';
966
+ }
967
+ if (this.monthPicker.enabled) {
968
+ this.viewMode = 'month';
969
+ }
970
+ if (this.dayPicker.enabled) {
971
+ this.viewMode = 'day';
972
+ } else {
973
+ this.justSelectOnDate = false;
974
+ }
975
+ }
976
+ if (this.minDate | this.maxDate) {
977
+ this.state.setFilterDate('unix', this.minDate, this.maxDate);
978
+ this.state._filetredDate = true;
979
+ } else {
980
+ this.state._filetredDate = false;
981
+ }
982
+ return this;
983
+ }
984
+ };
985
+ 'use strict';
986
+ /**
987
+ * Extend javascript Object
988
+ * @type {Function}
989
+ */
990
+ Object.keys = Object.keys || (function () {
991
+ var hasOwnProperty = Object.prototype.hasOwnProperty, hasDontEnumBug = !{
992
+ toString: null
993
+ }.propertyIsEnumerable("toString"), DontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'], DontEnumsLength = DontEnums.length;
994
+
995
+ return function (o) {
996
+ if (typeof o !== "object" && typeof o !== "function" || o === null)
997
+ throw new TypeError("Object.keys called on a non-object");
998
+
999
+ var result = [];
1000
+ for (var name in o) {
1001
+ if (hasOwnProperty.call(o, name))
1002
+ result.push(name);
1003
+ }
1004
+
1005
+ if (hasDontEnumBug) {
1006
+ for (var i = 0; i < DontEnumsLength; i++) {
1007
+ if (hasOwnProperty.call(o, DontEnums[i]))
1008
+ result.push(DontEnums[i]);
1009
+ }
1010
+ }
1011
+ return result;
1012
+ };
1013
+ })();
1014
+
1015
+
1016
+ /**
1017
+ * Extend javascript Event
1018
+ * @type {{setup: setup, teardown: teardown, handler: handler, delayedHandler: delayedHandler, triggerIfChanged: triggerIfChanged, saveLastValue: saveLastValue}}
1019
+ */
1020
+ $.event.special.textchange = {
1021
+ setup: function (data, namespaces) {
1022
+ $.event.special.textchange.saveLastValue(this);
1023
+ $(this).bind('keyup.textchange', $.event.special.textchange.handler);
1024
+ $(this).bind('cut.textchange paste.textchange input.textchange', $.event.special.textchange.delayedHandler);
1025
+ },
1026
+ teardown: function (namespaces) {
1027
+ $(this).unbind('.textchange');
1028
+ },
1029
+ handler: function (event) {
1030
+ $.event.special.textchange.triggerIfChanged($(this));
1031
+ },
1032
+ delayedHandler: function (event) {
1033
+ var element = $(this);
1034
+ setTimeout(function () {
1035
+ $.event.special.textchange.triggerIfChanged(element);
1036
+ }, 25);
1037
+ },
1038
+ triggerIfChanged: function (element) {
1039
+ var current = element[0].contentEditable === 'true' ? element.html() : element.val();
1040
+ if (current !== element.data('lastValue')) {
1041
+ element.trigger('textchange', element.data('lastValue'));
1042
+
1043
+ // element.data('lastValue', current);
1044
+ }
1045
+ },
1046
+ saveLastValue: function (element) {
1047
+ $(element).data('lastValue', element.contentEditable === 'true' ? $(element).html() : $(element).val());
1048
+ }
1049
+ };
1050
+ $.event.special.hastext = {
1051
+
1052
+ setup: function (data, namespaces) {
1053
+ $(this).bind('textchange', $.event.special.hastext.handler);
1054
+ },
1055
+
1056
+ teardown: function (namespaces) {
1057
+ $(this).unbind('textchange', $.event.special.hastext.handler);
1058
+ },
1059
+
1060
+ handler: function (event, lastValue) {
1061
+ if ((lastValue === '') && lastValue !== $(this).val()) {
1062
+ $(this).trigger('hastext');
1063
+ }
1064
+ }
1065
+ };
1066
+
1067
+ $.event.special.notext = {
1068
+
1069
+ setup: function (data, namespaces) {
1070
+ $(this).bind('textchange', $.event.special.notext.handler);
1071
+ },
1072
+
1073
+ teardown: function (namespaces) {
1074
+ $(this).unbind('textchange', $.event.special.notext.handler);
1075
+ },
1076
+
1077
+ handler: function (event, lastValue) {
1078
+ if ($(this).val() === '' && $(this).val() !== lastValue) {
1079
+ $(this).trigger('notext');
1080
+ }
1081
+ }
1082
+ };
1083
+ // Enhance val() so that this plugin is aware of programmatic changes to
1084
+ // text using val().
1085
+ var origValFn = $.fn.val;
1086
+ $.fn.val = function () {
1087
+ var returnValue = origValFn.apply(this, arguments);
1088
+ if (arguments.length) {
1089
+ this.each(function () {
1090
+ $.event.special.textchange.triggerIfChanged($(this));
1091
+ });
1092
+ }
1093
+ return returnValue;
1094
+ };
1095
+
1096
+
1097
+ /**
1098
+ * Micro Mustcahe Template
1099
+ * @param input
1100
+ * @param dict
1101
+ * @returns {*|jQuery|HTMLElement}
1102
+ */
1103
+ $.tmplMustache = function (input, dict) {
1104
+ // Micro Mustache Template engine
1105
+ String.prototype.format = function string_format(arrayInput) {
1106
+ function replacer(key) {
1107
+ var keyArr = key.slice(2, -2).split("."), firstKey = keyArr[0], SecondKey = keyArr[1];
1108
+ if (arrayInput[firstKey] instanceof Object) {
1109
+ return arrayInput[firstKey][SecondKey];
1110
+ } else {
1111
+ return arrayInput[firstKey];
1112
+ }
1113
+ }
1114
+
1115
+ return this.replace(/{{\s*[\w\.]+\s*}}/g, replacer);
1116
+ };
1117
+ return $(input.format(dict));
1118
+ };
1119
+
1120
+
1121
+ /**
1122
+ * Extend String Proto with toPersianDigit & toEnglishDigit
1123
+ * @param a
1124
+ * @returns {string}
1125
+ */
1126
+ String.prototype.toPersianDigit = function (a) {
1127
+ return this.replace(/\d+/g, function (digit) {
1128
+ var enDigitArr = [], peDigitArr = [];
1129
+ for (var i = 0; i < digit.length; i++) {
1130
+ enDigitArr.push(digit.charCodeAt(i));
1131
+ }
1132
+ for (var j = 0; j < enDigitArr.length; j++) {
1133
+ peDigitArr.push(String.fromCharCode(enDigitArr[j] + ((!!a && a == true) ? 1584 : 1728)));
1134
+ }
1135
+ return peDigitArr.join('');
1136
+ });
1137
+ };
1138
+
1139
+
1140
+ /**
1141
+ *
1142
+ * @param a
1143
+ * @returns {string}
1144
+ */
1145
+ String.prototype.toEngilshDigit = function (a) {
1146
+ return this.replace(/\d+/g, function (digit) {
1147
+ var enDigitArr = [], peDigitArr = [];
1148
+ for (var i = 0; i < digit.length; i++) {
1149
+ enDigitArr.push(digit.charCodeAt(i));
1150
+ }
1151
+ for (var j = 0; j < enDigitArr.length; j++) {
1152
+ peDigitArr.push(String.fromCharCode(enDigitArr[j] - ((!!a && a == true) ? 1584 : 1728)));
1153
+ }
1154
+ return enDigitArr.join('');
1155
+ });
1156
+ };
1157
+
1158
+
1159
+ /**
1160
+ * Helper Methuds
1161
+ * @param callback
1162
+ * @param ms
1163
+ */
1164
+ var delay = function (callback, ms) {
1165
+ clearTimeout(window.datepickerTimer);
1166
+ window.datepickerTimer = setTimeout(callback, ms);
1167
+ };
1168
+
1169
+
1170
+ /**
1171
+ *
1172
+ * @param input
1173
+ */
1174
+ var log = function (input) {
1175
+ console.log(input);
1176
+ };
1177
+
1178
+
1179
+ /**
1180
+ *
1181
+ * @param e
1182
+ * @returns {Array}
1183
+ */
1184
+ var range = function (e) {
1185
+ var r = [];
1186
+ var i = 0;
1187
+ while (i <= e - 1) {
1188
+ r.push(i);
1189
+ i++;
1190
+ }
1191
+ return r;
1192
+ };
1193
+
1194
+
1195
+ /**
1196
+ *
1197
+ * @param self
1198
+ * @param baseClasses
1199
+ * @returns {*}
1200
+ */
1201
+ var inherit = function (self, baseClasses) {
1202
+ var copyObject = function (o) {
1203
+ return $.extend(true, {}, o);
1204
+ }
1205
+ var args = [true, self, copyObject(ClassBase)];
1206
+ var events = [];
1207
+ for (var index in baseClasses) {
1208
+ var cls = copyObject(baseClasses[index]);
1209
+ if (!cls) {
1210
+ continue;
1211
+ }
1212
+ if (cls['events'] && Object.keys(cls['events']).length > 0) {
1213
+ events.push(cls['events']);
1214
+ }
1215
+ cls.events = {};
1216
+ args.push(cls);
1217
+ }
1218
+ $.extend.apply(self, args);
1219
+ for (var index in events) {
1220
+ var eventsObject = events[index];
1221
+ var eventKeys = Object.keys(eventsObject)
1222
+ for (var keyIndex in eventKeys) {
1223
+ var key = eventKeys[keyIndex]
1224
+ var val = eventsObject[key];
1225
+ if (key && val) {
1226
+ self.attachEvent(key, val);
1227
+ }
1228
+ }
1229
+ }
1230
+ self.init();
1231
+ return self;
1232
+ }
1233
+
1234
+
1235
+ /**
1236
+ *
1237
+ * @param ua
1238
+ * @returns {{browser: (*|string), version: (*|string)}}
1239
+ */
1240
+ jQuery.uaMatch = function (ua) {
1241
+ ua = ua.toLowerCase();
1242
+
1243
+ var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
1244
+ /(webkit)[ \/]([\w.]+)/.exec(ua) ||
1245
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
1246
+ /(msie) ([\w.]+)/.exec(ua) ||
1247
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
1248
+ [];
1249
+
1250
+ return {
1251
+ browser: match[ 1 ] || "",
1252
+ version: match[ 2 ] || "0"
1253
+ };
1254
+ };
1255
+
1256
+
1257
+ // cDon't clobber any existing jQuery.browser in case it's different
1258
+ if (!jQuery.browser) {
1259
+ var matched = jQuery.uaMatch(window.navigator.userAgent);
1260
+ var browser = {};
1261
+
1262
+ if (matched.browser) {
1263
+ browser[ matched.browser ] = true;
1264
+ browser.version = matched.version;
1265
+ }
1266
+
1267
+ // Chrome is Webkit, but Webkit is also Safari.
1268
+ if (browser.chrome) {
1269
+ browser.webkit = true;
1270
+ } else if (browser.webkit) {
1271
+ browser.safari = true;
1272
+ }
1273
+
1274
+ jQuery.browser = browser;
1275
+ }
1276
+ var ClassMonthGrid = {
1277
+ /**
1278
+ * @memberOf ClassDayPicker.ClassMonthGrid
1279
+ * @desc state
1280
+ * @prop year
1281
+ * @prop month
1282
+ * @prop date
1283
+ * @prop firstWeekDayOfMonth
1284
+ * @prop daysCount
1285
+ */
1286
+ state: {
1287
+ year: null,
1288
+ month: null,
1289
+ date: null,
1290
+ firstWeekDayOfMonth: null,
1291
+ daysCount: null
1292
+ },
1293
+
1294
+
1295
+ /**
1296
+ * @memberOf ClassDayPicker.ClassMonthGrid
1297
+ * @desc perisnaDigit
1298
+ */
1299
+ persianDigit: true,
1300
+
1301
+
1302
+ /**
1303
+ * @memberOf ClassDayPicker.ClassMonthGrid
1304
+ * @desc _formatDigit
1305
+ * @param digit
1306
+ * @returns {*}
1307
+ * @private
1308
+ */
1309
+ _formatDigit: function (digit) {
1310
+ if (this.persianDigit) {
1311
+ return digit.toString().toPersianDigit();
1312
+ }
1313
+ else {
1314
+ return digit;
1315
+ }
1316
+ },
1317
+
1318
+
1319
+ /**
1320
+ * @memberOf ClassDayPicker.ClassMonthGrid
1321
+ * @desc evenets
1322
+ * @prop init
1323
+ * @prop render
1324
+ * @prop reRender
1325
+ * @prop selectDay
1326
+ */
1327
+ events: {
1328
+ init: function () {
1329
+ },
1330
+ render: function () {
1331
+ this.state.month = this.month;
1332
+ this.state.year = this.year;
1333
+ },
1334
+ reRender: function () {
1335
+ this._markToday();
1336
+ },
1337
+ selectDay: function (x) {
1338
+ }
1339
+ },
1340
+
1341
+
1342
+ /**
1343
+ * @memberOf ClassDayPicker.ClassMonthGrid
1344
+ * @desc _markToday
1345
+ * @returns {Class_MonthGrid}
1346
+ * @private
1347
+ */
1348
+ _markToday: function () {
1349
+ var self = this;
1350
+ var todate = new persianDate();
1351
+ $(self.element).removeClass(self.cssClass.today);
1352
+ $.each(self.daysList, function (index, value) {
1353
+ var htmlItemDay = $(this).data().day;
1354
+ var htmlItemMonth = $(this).data().month;
1355
+ var htmlItemYear = $(this).data().year;
1356
+ if (htmlItemDay == todate.date() && htmlItemMonth == todate.month() && htmlItemYear == todate.year()) {
1357
+ $(this).addClass(self.cssClass.today);
1358
+ $(self.element).addClass(self.cssClass.today);
1359
+ }
1360
+ });
1361
+ return this;
1362
+ },
1363
+
1364
+
1365
+ /**
1366
+ * @memberOf ClassDayPicker.ClassMonthGrid
1367
+ * @desc _updateState
1368
+ * @returns {Class_MonthGrid}
1369
+ * @private
1370
+ * @todo : must remove
1371
+ */
1372
+ _updateState: function () {
1373
+ var self = this;
1374
+ var t = new persianDate();
1375
+ self.daysCount = t.daysInMonth(self.state.year, self.state.month);
1376
+ self.firstWeekDayOfMonth = t.getFirstWeekDayOfMonth(self.state.year, self.state.month);
1377
+ return this;
1378
+ },
1379
+
1380
+
1381
+ /**
1382
+ * @memberOf ClassDayPicker.ClassMonthGrid
1383
+ * @desc selectDate
1384
+ * @param unixDate
1385
+ * @returns {Class_MonthGrid}
1386
+ */
1387
+ selectDate: function (unixDate) {
1388
+ var self = this, reRenderFlag;
1389
+ var sDate = new persianDate(unixDate);
1390
+ if (self.state.year == sDate.year() && self.state.month == sDate.month()) {
1391
+ reRenderFlag = false;
1392
+ } else {
1393
+ reRenderFlag = true;
1394
+ }
1395
+ self.state.year = sDate.year();
1396
+ self.state.month = sDate.month();
1397
+ self.state.date = sDate.date();
1398
+ if (reRenderFlag) {
1399
+ self.view.renderDays(self);
1400
+ }
1401
+ self.markSelectedDate(unixDate);
1402
+ return this;
1403
+ },
1404
+
1405
+
1406
+ /**
1407
+ * @memberOf ClassDayPicker.ClassMonthGrid
1408
+ * @desc markSelectedDate
1409
+ * @param unixDate
1410
+ */
1411
+ markSelectedDate: function (unixDate) {
1412
+ var self = this;
1413
+ $.each(self.daysList, function (index, value) {
1414
+ var viewItemUnix = parseInt($(value).attr("unixDate"));
1415
+ if (self.isSameDay(viewItemUnix, unixDate)) {
1416
+ $(this).addClass(self.cssClass.selected);
1417
+ } else {
1418
+ $(this).removeClass(self.cssClass.selected);
1419
+ }
1420
+ });
1421
+ },
1422
+
1423
+
1424
+ /**
1425
+ * @memberOf ClassDayPicker.ClassMonthGrid
1426
+ * @desc updateAs
1427
+ * @param year
1428
+ * @param month
1429
+ * @returns {Class_MonthGrid}
1430
+ */
1431
+ updateAs: function (year, month) {
1432
+ var self = this;
1433
+ self.state.year = year;
1434
+ self.state.month = month;
1435
+ self.view.renderDays(self);
1436
+ return this;
1437
+ },
1438
+
1439
+
1440
+ /**
1441
+ * @memberOf ClassDayPicker.ClassMonthGrid
1442
+ * @desc goToNextMonth
1443
+ * @returns {boolean}
1444
+ */
1445
+ goToNextMonth: function () {
1446
+ var self = this;
1447
+ if (self.state.month === 12) {
1448
+ self.state.month = 1;
1449
+ self.state.viewYear += 1;
1450
+ } else {
1451
+ self.state.month += 1;
1452
+ }
1453
+ self.updateAs(self.state.year, self.state.month)
1454
+ return false;
1455
+ },
1456
+
1457
+
1458
+ /**
1459
+ * @memberOf ClassDayPicker.ClassMonthGrid
1460
+ * @desc goTOPrevMonth
1461
+ */
1462
+ goToPrevMonth: function () {
1463
+ },
1464
+
1465
+
1466
+ /**
1467
+ * @memberOf ClassDayPicker.ClassMonthGrid
1468
+ * @desc goToYear
1469
+ * @param year
1470
+ */
1471
+ goToYear: function (year) {
1472
+ this.updateAs(year, this.state.month);
1473
+ },
1474
+
1475
+
1476
+ /**
1477
+ * @memberOf ClassDayPicker.ClassMonthGrid
1478
+ * @desc applyStory
1479
+ */
1480
+ applyStory: function () {
1481
+ //this.view.applyStory(this);
1482
+ }
1483
+ };
1484
+ MonthGrid = function (options) {
1485
+ // Change !!
1486
+ //this.pcal = options.parent.pcal;
1487
+ inherit(this, [ClassSprite, ViewsMonthGrid, ClassDateRange, ClassMonthGrid, options]);
1488
+ return this;
1489
+ }
1490
+
1491
+ 'use strict';
1492
+ /**
1493
+ * @desc Instantiate in {@link ClassMonthGrid}
1494
+ * @class ViewsMonthGrid
1495
+ * @memberOf ClassMonthGrid
1496
+ * @type {{cssClass: {main: string, header: string, headerTitle: string, headerRow: string, headerRowCell: string, daysTable: string, currentMonth: string, today: string, selected: string}, views: {default: {render: render, renderDays: renderDays}}}}
1497
+ */
1498
+ var ViewsMonthGrid = {
1499
+ /**
1500
+ * @memberOf ClassMonthGrid.ViewsMonthGrid
1501
+ * @desc cssClass {string}
1502
+ * @prop main {string}
1503
+ * @prop header {string}
1504
+ * @prop headerTitle {string}
1505
+ * @prop headerRow {string}
1506
+ * @prop headerRowCell {string}
1507
+ * @prop daysTable {string}
1508
+ * @prop currentMonth {string}
1509
+ * @prop today {string}
1510
+ * @prop selected {string}
1511
+ * @prop disbaled {string}
1512
+ */
1513
+ cssClass: {
1514
+ main: "month-grid-box",
1515
+ header: "header",
1516
+ headerTitle: "title",
1517
+ headerRow: "header-row",
1518
+ headerRowCell: "header-row-cell",
1519
+ daysTable: "table-days",
1520
+ currentMonth: "current-month",
1521
+ today: "today",
1522
+ selected: 'selected',
1523
+ disbaled: 'disabled'
1524
+ },
1525
+
1526
+
1527
+ /**
1528
+ * @memberOf ClassMonthGrid.ViewsMonthGrid
1529
+ * @desc views
1530
+ */
1531
+ views: {
1532
+ "default": {
1533
+ /**
1534
+ *
1535
+ * @param self
1536
+ */
1537
+ render: function (self) {
1538
+ self.viewData = {
1539
+ css: self.cssClass
1540
+ };
1541
+ self.element = $.tmplMustache(TEMPLATE.monthGrid, self.viewData).appendTo(self.container);
1542
+ self.header = self.createElementByClass(self.cssClass.header);
1543
+ self.headerRow = self.createElementByClass(self.cssClass.headerRow);
1544
+ var weekDay;
1545
+ for (weekDay in self.weekRange) {
1546
+ $("<div/>").text(self.weekRange[weekDay].abbr.fa).addClass(self.cssClass.headerRowCell).appendTo(self.headerRow)[0];
1547
+ }
1548
+ ;
1549
+ self.daysBox = self.createElementByClass(self.cssClass.daysTable);
1550
+ this.renderDays(self);
1551
+ },
1552
+ /**
1553
+ *
1554
+ * @param self
1555
+ */
1556
+ renderDays: function (self) {
1557
+ self._updateState();
1558
+ self.daysList = [];
1559
+ var addSpan = function (day, month, year, cssClass) {
1560
+ var dayPartUnixTime = new persianDate([year, month, day]).valueOf();
1561
+ var span = $("<span/>")
1562
+ .text(self._formatDigit(day))
1563
+ .attr("unixDate", dayPartUnixTime)
1564
+ .data({ day: day, month: month, year: year, unixDate: dayPartUnixTime})
1565
+ .addClass(cssClass)
1566
+ .appendTo($(this))[0];
1567
+ self.daysList.push(span);
1568
+ }
1569
+ var t = new persianDate();
1570
+ self.daysCount = t.daysInMonth(self.state.year, self.state.month);
1571
+ self.firstWeekDayOfMonth = t.getFirstWeekDayOfMonth(self.state.year, self.state.month);
1572
+ var currentMonthIndex = 1;
1573
+ var nextMonthIndex = 1;
1574
+ $(self.daysBox).find("td").each(function (index) {
1575
+ $(this).empty();
1576
+ if (self.firstWeekDayOfMonth > 1 && index + 1 < self.firstWeekDayOfMonth) {
1577
+ if (self.state.month === 1) {
1578
+ var prevMonth = 12;
1579
+ var prevYear = parseInt(self.state.year) - 1;
1580
+ } else {
1581
+ var prevMonth = parseInt(self.state.month) - 1;
1582
+ var prevYear = parseInt(self.state.year);
1583
+ }
1584
+ var prevMonthDaysCount = t.daysInMonth(prevYear, prevMonth);
1585
+ var day = parseInt((prevMonthDaysCount - self.firstWeekDayOfMonth) + (index + 2));
1586
+ addSpan.apply(this, [day, prevMonth, prevYear, "other-month"])
1587
+ } else if (index + 2 === (currentMonthIndex + self.firstWeekDayOfMonth) && currentMonthIndex <= self.daysCount) {
1588
+ var day = currentMonthIndex;
1589
+ addSpan.apply(this, [day, parseInt(self.state.month), parseInt(self.state.year)])
1590
+ currentMonthIndex++;
1591
+ } else {
1592
+
1593
+ if (self.state.month === 12) {
1594
+ var nextMonth = 1;
1595
+ var nextYear = parseInt(self.state.year) + 1;
1596
+ } else {
1597
+ var nextMonth = parseInt(self.state.month) + 1;
1598
+ var nextYear = self.state.year;
1599
+ }
1600
+ var day = nextMonthIndex;
1601
+ addSpan.apply(this, [day, nextMonth, nextYear, "other-month"]);
1602
+ nextMonthIndex += 1;
1603
+ }
1604
+ var thisUnix = $(this).children("span").data("unixDate");
1605
+
1606
+
1607
+ if (self.datepicker.state._filetredDate) {
1608
+ if (self.minDate && self.maxDate) {
1609
+ if (thisUnix >= self.minDate && thisUnix <= self.maxDate) {
1610
+ $(this).addClass(self.cssClass.disbaled);
1611
+ } else {
1612
+ $(this).removeClass(self.cssClass.disbaled);
1613
+ }
1614
+ } else if (self.minDate) {
1615
+ if (thisUnix >= self.minDate) {
1616
+ $(this).addClass(self.cssClass.disbaled);
1617
+ }
1618
+ } else if (self.maxDate) {
1619
+ if (thisUnix <= self.maxDate) {
1620
+ $(this).removeClass(self.cssClass.disbaled);
1621
+ }
1622
+ }
1623
+ } else {
1624
+ if (self.datepicker.checkDate(thisUnix)) {
1625
+ $(this).removeClass(self.cssClass.disbaled);
1626
+ } else {
1627
+ $(this).addClass(self.cssClass.disbaled);
1628
+ }
1629
+ }
1630
+
1631
+
1632
+ });
1633
+ $(self.daysBox).find("td").not('.disabled').children("span").click(function () {
1634
+ var $thisUnixDate = $(this).data("unixDate");
1635
+ self.raiseEvent("selectDay", [$thisUnixDate]);
1636
+ return false;
1637
+ });
1638
+ $(self.daysBox).find('td.disabled').children("span").click(function () {
1639
+ return false;
1640
+ });
1641
+ self.raiseEvent("reRender");
1642
+ }
1643
+ }
1644
+ }
1645
+ };
1646
+ 'use strict';
1647
+ /**
1648
+ * @desc Instantiate in {@link ClassDatepicker}
1649
+ * @class ViewsDatePicker
1650
+ * @memberOf ClassDatepicker
1651
+ * @type {{cssClass: {datePickerPlotArea: string, yearView: string, monthView: string, dayView: string, timeView: string, navigator: string, toolbox: string}, container: {}, views: {default: {render: render, fixPosition: fixPosition}}}}
1652
+ */
1653
+ var ViewsDatePicker = {
1654
+ /**
1655
+ * @memberOf ClassDatepicker.ViewsDatePicker
1656
+ * @desc cssClass {string}
1657
+ * @prop datePickerPlotArea {string}
1658
+ * @prop yearView {string}
1659
+ * @prop monthView {string}
1660
+ * @prop dayView {string}
1661
+ * @prop timeView {string}
1662
+ * @prop navigator {string}
1663
+ * @prop toolbox {string}
1664
+ */
1665
+ cssClass: {
1666
+ datePickerPlotArea: "datepicker-plot-area",
1667
+ yearView: "datepicker-year-view",
1668
+ monthView: "datepicker-month-view",
1669
+ dayView: "datepicker-day-view",
1670
+ timeView: "datepicker-time-view",
1671
+ navigator: "navigator",
1672
+ toolbox: "toolbox "
1673
+ },
1674
+
1675
+
1676
+ /**
1677
+ * @memberOf ClassDatepicker.ViewsDatePicker
1678
+ * @desc conatiner
1679
+ */
1680
+ container: {},
1681
+
1682
+
1683
+ /**
1684
+ * @memberOf ClassDatepicker.ViewsDatePicker
1685
+ * @desc views
1686
+ * @prop default {object}
1687
+ */
1688
+ views: {
1689
+
1690
+
1691
+ /**
1692
+ * @memberOf ClassDatepicker.ViewsDatePicker.views
1693
+ * @prop render {function}
1694
+ * @prop fixPosition {function}
1695
+ */
1696
+ "default": {
1697
+ /**
1698
+ *
1699
+ * @param self
1700
+ * @returns {ViewsDatePicker}
1701
+ */
1702
+ render: function (self) {
1703
+ var viewData = {
1704
+ css: self.cssClass
1705
+ };
1706
+
1707
+ self.element = {};
1708
+ /**
1709
+ * @memberOf ViewsDatePicker
1710
+ */
1711
+ self.element.main = $.tmplMustache(TEMPLATE.datepciker, viewData).appendTo(self.$container);
1712
+
1713
+ if (!self._inlineView) {
1714
+ self.element.main.hide();
1715
+ }
1716
+ else {
1717
+ self.element.main.addClass('datepicker-plot-area-inline-view');
1718
+ self.element.main.show();
1719
+ }
1720
+
1721
+ self.view.fixPosition(self);
1722
+
1723
+ self.container.navigator = $(self.element.main).children('.' + self.cssClass.navigator);
1724
+ self.container.dayView = $(self.element.main).children('.' + self.cssClass.dayView);
1725
+ self.container.monthView = $(self.element.main).children('.' + self.cssClass.monthView);
1726
+ self.container.yearView = $(self.element.main).children('.' + self.cssClass.yearView);
1727
+ self.container.timeView = $(self.element.main).children('.' + self.cssClass.timeView);
1728
+ self.container.toolbox = $(self.element.main).children('.' + self.cssClass.toolbox);
1729
+
1730
+ if (self.navigator.enabled && self.onlyTimePicker == false) {
1731
+ self.navigator = new Navigator($.extend(true, self.navigator, {datepicker: self}), self.container.navigator);
1732
+ } else {
1733
+ self.container.navigator.remove();
1734
+ self.navigator = false;
1735
+ }
1736
+
1737
+ if (self.toolbox.enabled && self.onlyTimePicker === false) {
1738
+ self.toolbox = new Toolbox($.extend(true, self.toolbox, {datepicker: self}), self.container.toolbox);
1739
+ } else {
1740
+ self.container.toolbox.remove();
1741
+ self.toolbox = false;
1742
+ }
1743
+ if (self.dayPicker.enabled && self.onlyTimePicker === false) {
1744
+ self.dayPicker = new Daypicker($.extend(true, self.dayPicker, {datepicker: self}), self.container.dayView);
1745
+ self._pickers.day = self.dayPicker;
1746
+ } else {
1747
+ self.container.dayView.hide();
1748
+ self.dayPicker = false;
1749
+ }
1750
+ if (self.monthPicker.enabled && self.onlyTimePicker === false) {
1751
+ self.monthPicker = new MonthPicker($.extend(true, self.monthPicker, {datepicker: self}), self.container.monthView);
1752
+ self._pickers.month = self.monthPicker;
1753
+ } else {
1754
+ self.monthPicker = false;
1755
+ self.container.monthView.hide();
1756
+ }
1757
+ if (self.yearPicker.enabled && self.onlyTimePicker === false) {
1758
+ self.yearPicker = new YearPicker($.extend(true, self.yearPicker, {datepicker: self}), self.container.yearView);
1759
+ self._pickers.year = self.yearPicker;
1760
+ }
1761
+ else {
1762
+ self.yearPicker = false;
1763
+ self.container.yearView.hide();
1764
+ }
1765
+ if (self.timePicker.enabled | self.onlyTimePicker === true) {
1766
+ self.timePicker = new TimePicker($.extend(true, self.timePicker, {datepicker: self}), self.container.timeView);
1767
+ }
1768
+ else {
1769
+ self.container.timeView.hide();
1770
+ }
1771
+
1772
+ self.changeView(self.viewMode);
1773
+ self._syncWithImportData(self.state.unixDate);
1774
+ return this;
1775
+ },
1776
+
1777
+
1778
+ /**
1779
+ *
1780
+ * @param self
1781
+ * @returns {ViewsDatePicker}
1782
+ */
1783
+ fixPosition: function (self) {
1784
+ if (!self._inlineView) {
1785
+ var inputX = self.inputElem.offset().top;
1786
+ var inputY = self.inputElem.offset().left;
1787
+ if (self.position === "auto") {
1788
+ var inputHeight = self.fullHeight(self.inputElem);
1789
+ self.element.main.css({
1790
+ top: (inputX + inputHeight) + 'px',
1791
+ left: inputY + 'px'
1792
+ });
1793
+ } else {
1794
+ self.element.main.css({
1795
+ top: (inputX + self.position[0]) + 'px',
1796
+ left: (inputY + self.position[1]) + 'px'
1797
+ });
1798
+ }
1799
+ }
1800
+ return this;
1801
+ }
1802
+ }
1803
+ }
1804
+ };
1805
+ var ClassDatepicker = {
1806
+ /**
1807
+ *
1808
+ * @desc list of picker obejcts like dayPicker,monthPicker,yearPicker
1809
+ * @private
1810
+ */
1811
+ _pickers: {},
1812
+
1813
+
1814
+ /**
1815
+ * @desc save current visibility state of plugin
1816
+ * @private
1817
+ */
1818
+ _viewed: false,
1819
+
1820
+
1821
+ /**
1822
+ * @desc if plugin selector detect as a div or any element exsept inpout set as true
1823
+ * @private
1824
+ */
1825
+ _inlineView: false,
1826
+
1827
+
1828
+ /**
1829
+ * @desc define next state of {@link ClassDatepicker._pickers}
1830
+ * @param {string} action . Acceptable Value : 'day','month',year
1831
+ * @returns {*}
1832
+ * @private
1833
+ */
1834
+ _getNextState: function (action) {
1835
+ var currentState = this.currentView;
1836
+ var nextState = this.currentView;
1837
+ if (action === 'next') {
1838
+ if (currentState === 'month' && this.dayPicker) {
1839
+ nextState = 'day';
1840
+ }
1841
+ if (currentState === 'year') {
1842
+ if (this.monthPicker) {
1843
+ nextState = 'month';
1844
+ } else {
1845
+ if (this.dayPicker) {
1846
+ nextState = 'day';
1847
+ }
1848
+ }
1849
+ }
1850
+ }
1851
+ else if (action === 'prev') {
1852
+ if (currentState === 'month' && this.yearPicker) {
1853
+ nextState = 'year';
1854
+ }
1855
+ if (currentState === 'day') {
1856
+ if (this.monthPicker) {
1857
+ nextState = 'month';
1858
+ } else {
1859
+ if (this.yearPicker) {
1860
+ nextState = 'year';
1861
+ }
1862
+ }
1863
+ }
1864
+ }
1865
+ return this._checkNextStateAvalibility(nextState);
1866
+ },
1867
+
1868
+
1869
+ /**
1870
+ * @desc check next state is available in {@link ClassDatepicker._pickers}
1871
+ * @param {string} state Accepptable Value: 'day','month','year'
1872
+ * @returns {*}
1873
+ * @private
1874
+ */
1875
+ _checkNextStateAvalibility: function (state) {
1876
+ if (!this._pickers[state]) {
1877
+ this.element.main.hide();
1878
+ return false;
1879
+ $.error(state + "Picker Set as {enabled:false} and dos not exist!! Set viewMode to Enabled view Check Configuration");
1880
+ }
1881
+ return state;
1882
+ },
1883
+
1884
+
1885
+ /**
1886
+ * @desc update {@link ClassNavigator} object switch text
1887
+ * @param switchStr
1888
+ * @public
1889
+ * @returns {ClassDatepicker}
1890
+ */
1891
+ updateNavigator: function (switchStr) {
1892
+ if (this.navigator) {
1893
+ this.navigator.updateSwitchBtn(this._formatDigit(switchStr));
1894
+ }
1895
+ return this;
1896
+ },
1897
+
1898
+
1899
+ /**
1900
+ * @desc update {@link ClassNavigator} relaion state
1901
+ * @param switchStr
1902
+ * @public
1903
+ * @returns {ClassDatepicker}
1904
+ */
1905
+ switchNavigatorRelation: function (newState) {
1906
+ if (this.navigator) {
1907
+ this.navigator.switchRelation(newState);
1908
+ }
1909
+ return this;
1910
+ },
1911
+
1912
+
1913
+ /**
1914
+ * @desc change {@link _pickers} visibility
1915
+ * @param state
1916
+ * @param action
1917
+ * @returns {ClassDatepicker}
1918
+ */
1919
+ changeView: function (state, action) {
1920
+ var self = this;
1921
+ var newState;
1922
+ if (!action) {
1923
+ newState = this._checkNextStateAvalibility(state);
1924
+ } else {
1925
+ newState = this._getNextState(action);
1926
+ }
1927
+ if (newState) {
1928
+ self.publishInDic(self._pickers, 'hide');
1929
+ self._pickers[newState].show();
1930
+ self.switchNavigatorRelation(newState);
1931
+ self.currentView = newState;
1932
+ }
1933
+ return this;
1934
+ },
1935
+
1936
+
1937
+ /**
1938
+ * @desc used in {@link ClassDatepicker._attachEvents}
1939
+ * @private
1940
+ */
1941
+ _flagSelfManipulate: true,
1942
+
1943
+
1944
+ /**
1945
+ * @desc only called by {@link ClassTimepicker}
1946
+ * @param key
1947
+ * @param val
1948
+ * @event
1949
+ */
1950
+ selectTime: function (key, val) {
1951
+ this.state.setTime(key, val);
1952
+ this._updateInputElement();
1953
+ this.onSelect(key, this);
1954
+ },
1955
+
1956
+
1957
+ /**
1958
+ * @desc only called by {@link ClassDaypicker}
1959
+ * @param key
1960
+ * @param unixDate
1961
+ * @returns {ClassDatepicker}
1962
+ * @event
1963
+ */
1964
+ selectDate: function (unixDate) {
1965
+ var self = this;
1966
+ self.state.setSelected('unix', unixDate);
1967
+ this.state.syncViewWithelected();
1968
+ switch (self.currentView) {
1969
+ case ('month'):
1970
+ self.monthPicker.selectMonth();
1971
+ break;
1972
+ case ('year'):
1973
+ self.yearPicker.selectYear();
1974
+ break;
1975
+ case ('day'):
1976
+ self.dayPicker.selectDay();
1977
+ break;
1978
+ }
1979
+ self._updateInputElement();
1980
+ self.onSelect(unixDate, this);
1981
+ if (self.autoClose) {
1982
+ self.element.main.hide();
1983
+ }
1984
+ return this;
1985
+ },
1986
+
1987
+
1988
+ /**
1989
+ * @desc only called by {@link ClassDaypicker}
1990
+ * @param key
1991
+ * @param unixDate
1992
+ * @returns {ClassDatepicker}
1993
+ * @event
1994
+ */
1995
+ selectDateTime: function (unixDate) {
1996
+ var self = this;
1997
+ self.state.setSelectedDateTime('unix', unixDate);
1998
+ this.state.syncViewWithelected();
1999
+ switch (self.currentView) {
2000
+ case ('month'):
2001
+ self.monthPicker.selectMonth();
2002
+ break
2003
+ case ('year'):
2004
+ self.yearPicker.selectYear();
2005
+ break
2006
+ case ('day'):
2007
+ self.dayPicker.selectDay();
2008
+ break
2009
+ }
2010
+ self._updateInputElement();
2011
+ self.onSelect(unixDate, this);
2012
+ if (self.autoClose) {
2013
+ self.element.main.hide();
2014
+ }
2015
+ return this;
2016
+ },
2017
+
2018
+
2019
+ /**
2020
+ * @desc only called by {@link ClassMonthPicker}
2021
+ * @param monthNum
2022
+ * @returns {ClassDatepicker}
2023
+ */
2024
+ selectMonth: function (monthNum) {
2025
+ var self = this;
2026
+ if (this.justSelectOnDate) {
2027
+ self.state.setView('month', monthNum);
2028
+ } else {
2029
+ self.state.setSelected('month', monthNum);
2030
+ self.state.setSelected('year', self.state.view.year);
2031
+ self.state.syncViewWithelected();
2032
+ }
2033
+ self._updateInputElement();
2034
+ self.changeView(self.currentView, 'next');
2035
+ return this;
2036
+ },
2037
+
2038
+
2039
+ /**
2040
+ * @desc only called by {@link ClassYearPicker}
2041
+ * @param yearNum
2042
+ * @returns {ClassDatepicker}
2043
+ */
2044
+ selectYear: function (yearNum) {
2045
+ var self = this;
2046
+ if (this.justSelectOnDate) {
2047
+ self.state.setView('year', yearNum);
2048
+ } else {
2049
+ self.state.setSelected('year', yearNum);
2050
+ self.state.syncViewWithelected();
2051
+ }
2052
+ self._updateInputElement();
2053
+ self.changeView(self.currentView, 'next');
2054
+ return this;
2055
+ },
2056
+
2057
+
2058
+ /**
2059
+ * @desc check {@link ClassDatepicker.persianDigit} and if set true all digit convert to persian
2060
+ * @param digit
2061
+ * @returns {*}
2062
+ * @private
2063
+ */
2064
+ _formatDigit: function (digit) {
2065
+ if (this.persianDigit && digit) {
2066
+ return digit.toString().toPersianDigit();
2067
+ }
2068
+ else {
2069
+ return digit;
2070
+ }
2071
+ },
2072
+
2073
+
2074
+ /**
2075
+ * @desc use in {@link ClassDatepicker._attachEvents}
2076
+ * @param pasted
2077
+ * @returns {ClassDatepicker}
2078
+ * @private
2079
+ */
2080
+ _syncWithImportData: function (pasted) {
2081
+ if (pasted) {
2082
+ var self = this;
2083
+ if (jQuery.isNumeric(pasted)) {
2084
+ var newPersainDate = new persianDate(pasted);
2085
+ self.state.setSelected('unix', newPersainDate);
2086
+ self._updateInputElement();
2087
+ } else {
2088
+ var persianDateArray = self.validatePersianDateString(pasted);
2089
+ if (persianDateArray != null) {
2090
+ delay(function () {
2091
+
2092
+ var newPersainDate = new persianDate(persianDateArray);
2093
+ self.selectDate(newPersainDate.valueOf());
2094
+ }, self.inputDelay)
2095
+ }
2096
+ }
2097
+ }
2098
+ return this;
2099
+ },
2100
+
2101
+
2102
+ /**
2103
+ * @desc Attach all dom events to rendered element.
2104
+ * @returns {ClassDatepicker}
2105
+ * @private
2106
+ */
2107
+ _attachEvents: function () {
2108
+ var self = this;
2109
+ $(window).resize(function () {
2110
+ self.view.fixPosition(self);
2111
+ });
2112
+ if (self.observer) {
2113
+ ///////////////// Manipulate by Copy And paste
2114
+ self.inputElem.bind('paste', function (e) {
2115
+ delay(function () {
2116
+ self._syncWithImportData(e.target.value);
2117
+ }, 60);
2118
+ });
2119
+ ///////////////// Manipulate by alt changes
2120
+ $(self.altField).bind("change", function () {
2121
+ if (!self._flagSelfManipulate) {
2122
+ var newDate = new Date($(this).val());
2123
+ if (newDate !== "Invalid Date") {
2124
+ var newPersainDate = new persianDate(newDate);
2125
+ self.selectDate(newPersainDate.valueOf());
2126
+ }
2127
+ }
2128
+ });
2129
+ ///////////////// Manipulate by keyboard
2130
+ var ctrlDown = false;
2131
+ var ctrlKey = [17, 91], vKey = 86, cKey = 67;
2132
+ $(document).keydown(function (e) {
2133
+ if ($.inArray(e.keyCode, ctrlKey) > 0)
2134
+ ctrlDown = true;
2135
+ }).keyup(function (e) {
2136
+ if ($.inArray(e.keyCode, ctrlKey) > 0)
2137
+ ctrlDown = false;
2138
+ });
2139
+ self.inputElem.bind("keyup", function (e) {
2140
+ var $self = $(this);
2141
+ if (!self._flagSelfManipulate) {
2142
+ var trueKey = false;
2143
+ if (e.keyCode === 8 || e.keyCode < 105 && e.keyCode > 96 || e.keyCode < 58 && e.keyCode > 47 || (ctrlDown && (e.keyCode == vKey || $.inArray(e.keyCode, ctrlKey) > 0 ))) {
2144
+ trueKey = true;
2145
+ }
2146
+ if (trueKey) {
2147
+ self._syncWithImportData($self.val());
2148
+ }
2149
+ }
2150
+ });
2151
+ }
2152
+
2153
+ self.inputElem.focus(function () {
2154
+ self.show();
2155
+ });
2156
+ self.inputElem.click(function (e) {
2157
+ e.stopPropagation();
2158
+ return false;
2159
+ });
2160
+ self.inputElem.blur(function () {
2161
+ if (!$.browser.msie) {
2162
+ self.hide();
2163
+ }
2164
+ });
2165
+ $(document).not(".datepicker-plot-area,.datepicker-plot-area > *").click(function (e) {
2166
+ self.inputElem.blur();
2167
+ self.hide();
2168
+
2169
+ });
2170
+ $(self.element.main).mousedown(function (e) {
2171
+ e.stopPropagation();
2172
+ return false;
2173
+ });
2174
+ return this;
2175
+ },
2176
+
2177
+
2178
+ /**
2179
+ * @desc update input and altField input elemet value
2180
+ * @returns {ClassDatepicker}
2181
+ * @private
2182
+ */
2183
+ _updateInputElement: function () {
2184
+ var self = this;
2185
+ self._flagSelfManipulate = true;
2186
+ // Update Alt Field
2187
+ self.altField.val(self.altFieldFormatter(self.state.selected.unixDate)).trigger('change');
2188
+ ;
2189
+ // Update Display Field
2190
+ self.inputElem.val(self.formatter(self.state.selected.unixDate)).trigger('change');
2191
+ ;
2192
+ self._flagSelfManipulate = false;
2193
+ return self;
2194
+ },
2195
+
2196
+
2197
+ /**
2198
+ * @desc bootstrap method of {@link ClassDatepicker}
2199
+ * @returns {ClassDatepicker}
2200
+ * @private
2201
+ */
2202
+ _defineOnInitState: function () {
2203
+ if ($(this.$container)[0].nodeName == 'INPUT') {
2204
+ var garegurianDate = new Date(this.inputElem.val()).valueOf();
2205
+ this.$container = $('body');
2206
+ }
2207
+ else {
2208
+ var garegurianDate = new Date($(this.$container).data('date')).valueOf();
2209
+ this._inlineView = true;
2210
+ }
2211
+ if (garegurianDate && garegurianDate != 'undefined') {
2212
+ this.state.unixDate = garegurianDate;
2213
+ }
2214
+ else {
2215
+ this.state.unixDate = new Date().valueOf();
2216
+ }
2217
+ this.altField = $(this.altField);
2218
+ this.state.setSelectedDateTime('unix', this.state.unixDate);
2219
+ this.state.setTime('unix', this.state.unixDate);
2220
+ this.state.setView('unix', this.state.unixDate);
2221
+ return this;
2222
+ },
2223
+
2224
+
2225
+ /**
2226
+ * @desc set time of timepicker
2227
+ */
2228
+ setTime: function () {
2229
+ this.timePicker.setTime(this.state.selected.unixDate);
2230
+ },
2231
+
2232
+
2233
+ /**
2234
+ * @desc set date of datepicker
2235
+ */
2236
+ setDate: function (p) {
2237
+ var date = new persianDate(p);
2238
+ this.selectDateTime(date.valueOf())
2239
+ this.setTime();
2240
+ return this;
2241
+ },
2242
+
2243
+
2244
+ /**
2245
+ * @desc initilize {@link ClassDatepicker}
2246
+ * @returns {ClassDatepicker}
2247
+ */
2248
+ init: function () {
2249
+ var self = this;
2250
+ this.state = new State({datepicker: self});
2251
+ this.compatConfig();
2252
+ this._defineOnInitState();
2253
+ this._updateInputElement();
2254
+ this.view = this.views['default'];
2255
+ this.view.render(this);
2256
+ this.inputElem.data("datepicker", this);
2257
+ this.inputElem.addClass(self.cssClass);
2258
+ this._attachEvents();
2259
+ return this;
2260
+ }
2261
+ };
2262
+
2263
+ var Datepicker = function (mainElem, options) {
2264
+ return inherit(this, [ClassSprite, ClassCompat, ClassDatepicker, ViewsDatePicker, ClassConfig, options, {
2265
+ $container: mainElem,
2266
+ inputElem: $(mainElem)
2267
+ }]);
2268
+ };
2269
+
2270
+
2271
+ 'use strict';
2272
+ /**
2273
+ * @desc Instantiate in {@link ClassDatepicker}
2274
+ * @class
2275
+ * @type {{cssClass: {datpickerHeader: string, btnNext: string, btnSwitch: string, btnPrev: string}, relation: string, switchRelation: switchRelation, updateSwitchBtn: updateSwitchBtn, _next: _next, _prev: _prev, _switch: _switch, _render: _render, _attachEvents: _attachEvents, init: init}}
2276
+ */
2277
+ var ClassNavigator = {
2278
+ /**
2279
+ * @desc enabled
2280
+ * @type {Function}
2281
+ */
2282
+ enabled: true,
2283
+
2284
+ /**
2285
+ * @desc text
2286
+ */
2287
+ text: {
2288
+ btnNextText: "<",
2289
+ btnPrevText: ">"
2290
+ },
2291
+
2292
+ /**
2293
+ * @desc cssClass
2294
+ */
2295
+ cssClass: {
2296
+ datpickerHeader: "datepicker-header",
2297
+ btnNext: "btn-next",
2298
+ btnSwitch: "btn-switch",
2299
+ btnPrev: "btn-prev"
2300
+ },
2301
+
2302
+
2303
+ /**
2304
+ * @desc Defnine wich picker related to navigator
2305
+ * @desc relation
2306
+ */
2307
+ relation: "day",
2308
+
2309
+
2310
+ /**
2311
+ * @desc switchRelation
2312
+ * @param string
2313
+ * @returns {ClassNavigator}
2314
+ */
2315
+ switchRelation: function (string) {
2316
+ this.relation = string;
2317
+ this.onSwitch(string);
2318
+ return this;
2319
+ },
2320
+
2321
+
2322
+ /**
2323
+ * @desc updateSwitchBtn
2324
+ * @param val
2325
+ * @returns {ClassNavigator}
2326
+ */
2327
+ updateSwitchBtn: function (val) {
2328
+ $(this.element).children('.' + this.cssClass.btnSwitch).text(val);
2329
+ return this;
2330
+ },
2331
+
2332
+
2333
+ /**
2334
+ * @desc _next
2335
+ * @returns {ClassNavigator}
2336
+ * @private
2337
+ */
2338
+ _next: function () {
2339
+ this.datepicker[this.relation + 'Picker'].next();
2340
+ this.onNext(this);
2341
+ return this;
2342
+ },
2343
+
2344
+
2345
+ /**
2346
+ * @desc _prev
2347
+ * @returns {ClassNavigator}
2348
+ * @private
2349
+ */
2350
+ _prev: function () {
2351
+ this.datepicker[this.relation + 'Picker'].prev();
2352
+ this.onPrev(this);
2353
+ return this;
2354
+ },
2355
+
2356
+ /**
2357
+ * @desc _switch
2358
+ * @returns {ClassNavigator}
2359
+ * @private
2360
+ */
2361
+ _switch: function () {
2362
+ this.datepicker.changeView(this.relation, 'prev');
2363
+ return this;
2364
+ },
2365
+
2366
+
2367
+ /**
2368
+ * @desc _render
2369
+ * @private
2370
+ */
2371
+ _render: function () {
2372
+ var self = this;
2373
+ self.viewData = {
2374
+ css: self.cssClass,
2375
+ btnNextText: self.text.btnNextText,
2376
+ btnPrevText: self.text.btnPrevText
2377
+ };
2378
+ self.element = $.tmplMustache(TEMPLATE.navigator, self.viewData).appendTo(self.$container);
2379
+ },
2380
+
2381
+
2382
+ /**
2383
+ * @desc _attachEvents
2384
+ * @private
2385
+ */
2386
+ _attachEvents: function () {
2387
+ var self = this;
2388
+ self.element.children("." + self.cssClass.btnPrev).click(function () {
2389
+ self._prev();
2390
+ return false;
2391
+ });
2392
+ self.element.children("." + self.cssClass.btnNext).click(function () {
2393
+ self._next();
2394
+ return false;
2395
+ });
2396
+ self.element.children("." + self.cssClass.btnSwitch).click(function () {
2397
+ self._switch();
2398
+ return false;
2399
+ });
2400
+ },
2401
+
2402
+
2403
+ /**
2404
+ * @desc init
2405
+ * @returns {ClassNavigator}
2406
+ */
2407
+ init: function () {
2408
+ var self = this;
2409
+ self._render();
2410
+ self._attachEvents();
2411
+ return this;
2412
+ }
2413
+ };
2414
+ var Navigator = function (options, container) {
2415
+ return inherit(this, [ClassSprite, ClassNavigator, options, {
2416
+ $container: container
2417
+ }]);
2418
+ };
2419
+
2420
+ 'use strict';
2421
+ /**
2422
+ * @desc Instantiate in {@link ClassDatepicker}
2423
+ * @class ClassDayPicker
2424
+ * @type {{next: next, prev: prev, updateView: updateView, _updateView: _updateView, selectDay: selectDay, _updateNavigator: _updateNavigator, hide: hide, show: show, _updateSelectedDay: _updateSelectedDay, _render: _render, init: init}}
2425
+ */
2426
+ var ClassDayPicker = {
2427
+ /**
2428
+ * @desc next
2429
+ * @desc Go to next Month-day view
2430
+ * @public
2431
+ * @returns {ClassDaypicker}
2432
+ */
2433
+ next: function () {
2434
+ var self = this;
2435
+ if (self.datepicker.state.view.month === 12) {
2436
+ self.datepicker.state.setView('month', 1);
2437
+ self.datepicker.state.setView('year', parseInt(self.datepicker.state.view.year) + 1);
2438
+ } else {
2439
+ self.datepicker.state.setView('month', parseInt(self.datepicker.state.view.month) + 1);
2440
+ }
2441
+ self._updateView();
2442
+ return this;
2443
+ },
2444
+
2445
+
2446
+ /**
2447
+ * @desc prev
2448
+ * @desc Go to previews Month-day view
2449
+ * @public
2450
+ * @returns {ClassDaypicker}
2451
+ */
2452
+ prev: function () {
2453
+ var self = this;
2454
+ if (self.datepicker.state.view.month === 1) {
2455
+ self.datepicker.state.setView('month', 12);
2456
+ self.datepicker.state.setView('year', parseInt(self.datepicker.state.view.year) - 1);
2457
+ } else {
2458
+ self.datepicker.state.setView('month', parseInt(self.datepicker.state.view.month) - 1);
2459
+ }
2460
+ self._updateView();
2461
+ return this;
2462
+ },
2463
+
2464
+
2465
+ /**
2466
+ * @desc updateView
2467
+ * @public
2468
+ * @returns {ClassDaypicker}
2469
+ */
2470
+ updateView: function () {
2471
+ this._updateView();
2472
+ return this;
2473
+ },
2474
+
2475
+
2476
+ /**
2477
+ * @desc _updateView
2478
+ * @returns {ClassDaypicker}
2479
+ * @private
2480
+ */
2481
+ _updateView: function () {
2482
+ var self = this;
2483
+ self.mGrid.updateAs(self.datepicker.state.view.year, self.datepicker.state.view.month);
2484
+ self._updateNavigator(self.datepicker.state.view.year, self.datepicker.state.view.month);
2485
+ this._updateSelectedDay(self.datepicker.state.selected.unixDate);
2486
+ return this;
2487
+ },
2488
+
2489
+
2490
+ /**
2491
+ * @desc selectDay
2492
+ * @public
2493
+ * @returns {ClassDaypicker}
2494
+ */
2495
+ selectDay: function () {
2496
+ var self = this;
2497
+ self.mGrid.updateAs(self.datepicker.state.selected.year, self.datepicker.state.selected.month);
2498
+ self._updateNavigator(self.datepicker.state.selected.year, self.datepicker.state.selected.month);
2499
+ this._updateSelectedDay(self.datepicker.state.selected.unixDate);
2500
+ this._updateView();
2501
+ return this;
2502
+ },
2503
+
2504
+
2505
+ /**
2506
+ * @desc _updateNavigator
2507
+ * @param year
2508
+ * @param month
2509
+ * @private
2510
+ */
2511
+ _updateNavigator: function (year, month) {
2512
+ var self = this;
2513
+ var pdateStr = this.titleFormatter(year, month);
2514
+
2515
+ self.datepicker.updateNavigator(pdateStr);
2516
+ return this;
2517
+ },
2518
+
2519
+
2520
+ /**
2521
+ * @desc hide
2522
+ * @public
2523
+ * @returns {ClassDaypicker}
2524
+ */
2525
+ hide: function () {
2526
+ this.container.hide();
2527
+ return this;
2528
+ },
2529
+
2530
+
2531
+ /**
2532
+ * @desc show
2533
+ * @public
2534
+ * @returns {ClassDaypicker}
2535
+ */
2536
+ show: function () {
2537
+ this.container.show();
2538
+ this._updateView();
2539
+ return this;
2540
+ },
2541
+
2542
+
2543
+ /**
2544
+ * @desc _updateSelectedDay
2545
+ * @param unix
2546
+ * @returns {ClassDaypicker}
2547
+ * @private
2548
+ */
2549
+ _updateSelectedDay: function (unix) {
2550
+ this.mGrid.markSelectedDate(unix);
2551
+ return this;
2552
+ },
2553
+
2554
+ /**
2555
+ * @desc _attachEvents
2556
+ * @private
2557
+ */
2558
+ _attachEvents: function () {
2559
+ var self = this;
2560
+ if (this.scrollEnabled) {
2561
+ $(this.container).mousewheel(function (event) {
2562
+
2563
+ if (event.deltaY > 0) {
2564
+ self.next();
2565
+ } else {
2566
+ self.prev();
2567
+ }
2568
+
2569
+ });
2570
+ $(this.container).bind('mousewheel DOMMouseScroll', function (e) {
2571
+ var scrollTo = null;
2572
+
2573
+ if (e.type == 'mousewheel') {
2574
+ scrollTo = (e.originalEvent.wheelDelta * -1);
2575
+ }
2576
+ else if (e.type == 'DOMMouseScroll') {
2577
+ scrollTo = 40 * e.originalEvent.detail;
2578
+ }
2579
+ if (scrollTo) {
2580
+ e.preventDefault();
2581
+ $(this).scrollTop(scrollTo + $(this).scrollTop());
2582
+ }
2583
+ });
2584
+ }
2585
+ return this;
2586
+ },
2587
+
2588
+
2589
+ /**
2590
+ * @desc _render
2591
+ * @private
2592
+ */
2593
+ _render: function () {
2594
+ var self = this;
2595
+ this.mGrid = new MonthGrid({
2596
+ container: self.container,
2597
+ persianDigit: self.datepicker.persianDigit,
2598
+ month: self.datepicker.state.selected.month,
2599
+ year: self.datepicker.state.selected.year,
2600
+ minDate: self.datepicker.state.filterDate.start.unixDate,
2601
+ maxDate: self.datepicker.state.filterDate.end.unixDate,
2602
+ datepicker: self.datepicker
2603
+ });
2604
+ this.mGrid.attachEvent("selectDay", function (x) {
2605
+ self.datepicker.selectDate( x);
2606
+ self.onSelect(x);
2607
+ self.mGrid.selectDate(self.datepicker.state.selected.unixDate);
2608
+ });
2609
+ this._updateSelectedDay(self.datepicker.state.selected.unixDate);
2610
+ },
2611
+
2612
+
2613
+ /**
2614
+ * @desc init
2615
+ * @private
2616
+ * @returns {Class_Daypicker}
2617
+ */
2618
+ init: function () {
2619
+ var self = this;
2620
+ this._render()
2621
+ this._attachEvents();
2622
+ this._updateNavigator(self.datepicker.state.selected.year, self.datepicker.state.selected.month);
2623
+ return this;
2624
+ }
2625
+ };
2626
+ var Daypicker = function (options, container) {
2627
+ return inherit(this, [ClassSprite, ClassDayPicker, options, {
2628
+ container: container
2629
+ }]);
2630
+ };
2631
+
2632
+ 'use strict';
2633
+ /**
2634
+ * @desc Instantiate in {@link ClassDatepicker}
2635
+ * @class ClassMonthPicker
2636
+ * @type {{cssClass: {selectedMonth: string, monthItem: string}, monthRange: (ClassDateRange.monthRange|*), _updateNavigator: _updateNavigator, hide: hide, show: show, selectMonth: selectMonth, defineSelectedMonth: defineSelectedMonth, next: next, prev: prev, updateView: updateView, _render: _render, init: init}}
2637
+ */
2638
+ var ClassMonthPicker = {
2639
+ /**
2640
+ * @desc cssClass
2641
+ */
2642
+ cssClass: {
2643
+ selectedMonth: "selected",
2644
+ monthItem: "month-item",
2645
+ disbaleItem: "month-item-disable"
2646
+ },
2647
+
2648
+ /**
2649
+ * @desc monthRange
2650
+ */
2651
+ monthRange: ClassDateRange.monthRange,
2652
+
2653
+
2654
+ /**
2655
+ * @desc _updateNavigator
2656
+ * @private
2657
+ */
2658
+ _updateNavigator: function () {
2659
+ var self = this;
2660
+ self.datepicker.updateNavigator(this.titleFormatter(self.datepicker.state.view.unixDate));
2661
+ return this;
2662
+ },
2663
+
2664
+
2665
+ /**
2666
+ * @desc hide
2667
+ * @returns {Class_MonthPicker}
2668
+ */
2669
+ hide: function () {
2670
+ this.container.hide();
2671
+ return this;
2672
+ },
2673
+
2674
+
2675
+ /**
2676
+ * @desc show
2677
+ * @returns {Class_MonthPicker}
2678
+ */
2679
+ show: function () {
2680
+ this.container.show();
2681
+ this._updateNavigator();
2682
+ this._render();
2683
+ return this;
2684
+ },
2685
+
2686
+
2687
+ /**
2688
+ * @desc selectMonth
2689
+ */
2690
+ selectMonth: function () {
2691
+ this.defineSelectedMonth();
2692
+ this._updateNavigator();
2693
+ },
2694
+
2695
+
2696
+ /**
2697
+ * @desc defineSelectedMonth
2698
+ * @returns {Class_MonthPicker}
2699
+ */
2700
+ defineSelectedMonth: function () {
2701
+ var self = this;
2702
+ self.container.children('.' + self.cssClass.monthItem).removeClass(self.cssClass.selectedMonth);
2703
+ if (self.datepicker.state.view.year === self.datepicker.state.selected.year) {
2704
+ self.container.children(".month" + self.datepicker.state.selected.month).addClass(self.cssClass.selectedMonth);
2705
+ }
2706
+ return this;
2707
+ },
2708
+
2709
+
2710
+ /**
2711
+ * @desc next
2712
+ * @returns {Class_MonthPicker}
2713
+ */
2714
+ next: function () {
2715
+ var self = this;
2716
+ self.datepicker.state.setView('year', self.datepicker.state.view.year + 1);
2717
+ self.updateView();
2718
+ self._render();
2719
+
2720
+ return this;
2721
+ },
2722
+
2723
+
2724
+ /**
2725
+ * @desc prev
2726
+ * @returns {Class_MonthPicker}
2727
+ */
2728
+ prev: function () {
2729
+ var self = this;
2730
+ self.datepicker.state.setView('year', self.datepicker.state.view.year - 1);
2731
+ self.updateView();
2732
+ self._render();
2733
+ return this;
2734
+ },
2735
+
2736
+
2737
+ /**
2738
+ * @desc updateView
2739
+ * @returns {Class_MonthPicker}
2740
+ */
2741
+ updateView: function () {
2742
+ this.defineSelectedMonth();
2743
+ this._updateNavigator();
2744
+ return this;
2745
+ },
2746
+
2747
+
2748
+ /**
2749
+ * @desc _checkMonthAccess
2750
+ * @param month
2751
+ * @returns {boolean}
2752
+ * @private
2753
+ */
2754
+ _checkMonthAccess: function (month) {
2755
+ if (this.datepicker.state._filetredDate) {
2756
+ var y = this.datepicker.state.view.year;
2757
+ var monthUnix = new pDate([y, month]).unix() * 1000;
2758
+ if (monthUnix >= this.datepicker.state.filterDate.start.unixDate &&
2759
+ monthUnix <= this.datepicker.state.filterDate.end.unixDate
2760
+ ) {
2761
+ return true;
2762
+ } else {
2763
+ return false;
2764
+ }
2765
+ }
2766
+ else {
2767
+ return this.datepicker.checkMonth(month);
2768
+ }
2769
+ },
2770
+
2771
+
2772
+ /**
2773
+ * @desc _attachEvents
2774
+ * @returns {ClassMonthPicker}
2775
+ * @private
2776
+ */
2777
+ _attachEvents: function () {
2778
+ var self = this;
2779
+ if (this.scrollEnabled) {
2780
+ $(this.container).mousewheel(function (event) {
2781
+
2782
+ if (event.deltaY > 0) {
2783
+ self.next();
2784
+ } else {
2785
+ self.prev();
2786
+ }
2787
+ });
2788
+ $(this.container).bind('mousewheel DOMMouseScroll', function (e) {
2789
+ var scrollTo = null;
2790
+
2791
+ if (e.type == 'mousewheel') {
2792
+ scrollTo = (e.originalEvent.wheelDelta * -1);
2793
+ }
2794
+ else if (e.type == 'DOMMouseScroll') {
2795
+ scrollTo = 40 * e.originalEvent.detail;
2796
+ }
2797
+ if (scrollTo) {
2798
+ e.preventDefault();
2799
+ $(this).scrollTop(scrollTo + $(this).scrollTop());
2800
+ }
2801
+ });
2802
+ }
2803
+ return this;
2804
+ },
2805
+
2806
+ /**
2807
+ * @desc _render
2808
+ * @returns {Class_MonthPicker}
2809
+ * @private
2810
+ */
2811
+ _render: function () {
2812
+ var self = this, m;
2813
+ self.container.empty();
2814
+ for (m in this.monthRange) {
2815
+ var monthItem = $("<div/>").data({
2816
+ monthIndex: m
2817
+ }).addClass("month" + m)
2818
+ .addClass(self.cssClass.monthItem)
2819
+ .text(self.monthRange[m].name.fa)
2820
+ .appendTo(self.container);
2821
+
2822
+ if (self._checkMonthAccess(m)) {
2823
+ monthItem.click(function () {
2824
+ self.onSelect($(this).data().monthIndex);
2825
+ self.datepicker.selectMonth(parseInt($(this).data().monthIndex));
2826
+ return false;
2827
+ });
2828
+ } else {
2829
+ monthItem.addClass(self.cssClass.disbaleItem);
2830
+ monthItem.click(function () {
2831
+ return false;
2832
+ });
2833
+ }
2834
+ }
2835
+ ;
2836
+ this.defineSelectedMonth();
2837
+ return this;
2838
+ },
2839
+
2840
+ /**
2841
+ * @desc init
2842
+ * @returns {ClassMonthPicker}
2843
+ */
2844
+ init: function () {
2845
+ this._render();
2846
+ this._attachEvents();
2847
+ return this;
2848
+ }
2849
+ };
2850
+
2851
+ var MonthPicker = function (options, container) {
2852
+ return inherit(this, [ClassSprite, ClassMonthPicker, options, {
2853
+ container: container
2854
+ }]);
2855
+ };
2856
+
2857
+ 'use strict';
2858
+ /**
2859
+ * @desc Instantiate in {@link ClassDatepicker}
2860
+ * @class ClassYearPicker
2861
+ * @instance
2862
+ * @type {{cssClass: {selectedYear: string, yearItem: string}, events: {select: select}, _updateNavigator: _updateNavigator, hide: hide, show: show, next: next, prev: prev, selectYear: selectYear, updateView: updateView, _render: _render, init: init}}
2863
+ */
2864
+ var ClassYearPicker = {
2865
+ /**
2866
+ * cssClass
2867
+ */
2868
+ cssClass: {
2869
+ selectedYear: "selected",
2870
+ yearItem: "year-item",
2871
+ disbaleItem: "year-item-disable"
2872
+ },
2873
+
2874
+
2875
+ /**
2876
+ * events
2877
+ */
2878
+ events: {
2879
+ select: function () {
2880
+ }
2881
+ },
2882
+
2883
+
2884
+ /**
2885
+ *
2886
+ * @private
2887
+ */
2888
+ _updateNavigator: function () {
2889
+ var self = this;
2890
+ var year = self.datepicker.state.view.year;
2891
+ self.datepicker.updateNavigator(self.titleFormatter(year));
2892
+ return this;
2893
+ },
2894
+
2895
+ /**
2896
+ * @public
2897
+ * @returns {Class_YearPicker}
2898
+ */
2899
+ hide: function () {
2900
+ this.container.hide();
2901
+ return this;
2902
+ },
2903
+
2904
+
2905
+ /**
2906
+ * @public
2907
+ * @returns {Class_YearPicker}
2908
+ */
2909
+ show: function () {
2910
+ this.container.show();
2911
+ this.updateView();
2912
+ return this;
2913
+ },
2914
+
2915
+
2916
+ /**
2917
+ * @public
2918
+ * @returns {Class_YearPicker}
2919
+ */
2920
+ next: function () {
2921
+ var self = this;
2922
+ self.datepicker.state.view.year += 12;
2923
+ self._render().updateView();
2924
+ return this;
2925
+ },
2926
+
2927
+
2928
+ /**
2929
+ * @public
2930
+ * @returns {Class_YearPicker}
2931
+ */
2932
+ prev: function () {
2933
+ var self = this;
2934
+ self.datepicker.state.view.year -= 12;
2935
+ self._render().updateView();
2936
+ return this;
2937
+ },
2938
+
2939
+
2940
+ /**
2941
+ * @public
2942
+ */
2943
+ selectYear: function () {
2944
+ this.updateView();
2945
+ },
2946
+
2947
+
2948
+ /**
2949
+ * @public
2950
+ * @returns {Class_YearPicker}
2951
+ */
2952
+ updateView: function () {
2953
+ var self = this;
2954
+ self._render();
2955
+ self.container.children("." + self.cssClass.yearItem).each(function () {
2956
+ $(this).removeClass(self.cssClass.selectedYear);
2957
+
2958
+ if ($(this).data().year === self.datepicker.state.selected.year) {
2959
+ $(this).addClass(self.cssClass.selectedYear);
2960
+ }
2961
+ });
2962
+ self._updateNavigator();
2963
+ return this;
2964
+ },
2965
+
2966
+
2967
+ /**
2968
+ *
2969
+ * @param y
2970
+ * @returns {boolean}
2971
+ * @private
2972
+ */
2973
+ _checkYearAccess: function (y) {
2974
+ if (this.datepicker.state._filetredDate) {
2975
+ var startYear = this.datepicker.state.filterDate.start.year;
2976
+ var endYear = this.datepicker.state.filterDate.end.year;
2977
+ if (startYear <= y & y <= endYear) {
2978
+ return true;
2979
+ } else {
2980
+ return false;
2981
+ }
2982
+ }else {
2983
+ return this.datepicker.checkYear(y);
2984
+ }
2985
+ },
2986
+
2987
+
2988
+ /**
2989
+ *
2990
+ * @returns {ClassMonthPicker}
2991
+ * @private
2992
+ */
2993
+ _attachEvents: function () {
2994
+ var self = this;
2995
+ if (this.scrollEnabled) {
2996
+ $(this.container).mousewheel(function (event) {
2997
+
2998
+ if (event.deltaY > 0) {
2999
+ self.next();
3000
+ } else {
3001
+ self.prev();
3002
+ }
3003
+
3004
+ });
3005
+ $(this.container).bind('mousewheel DOMMouseScroll', function (e) {
3006
+ var scrollTo = null;
3007
+
3008
+ if (e.type == 'mousewheel') {
3009
+ scrollTo = (e.originalEvent.wheelDelta * -1);
3010
+ }
3011
+ else if (e.type == 'DOMMouseScroll') {
3012
+ scrollTo = 40 * e.originalEvent.detail;
3013
+ }
3014
+ if (scrollTo) {
3015
+ e.preventDefault();
3016
+ $(this).scrollTop(scrollTo + $(this).scrollTop());
3017
+ }
3018
+ });
3019
+ }
3020
+ return this;
3021
+ },
3022
+
3023
+ /**
3024
+ *
3025
+ * @returns {Class_YearPicker}
3026
+ * @private
3027
+ */
3028
+ _render: function () {
3029
+ var self = this;
3030
+ var yearItem
3031
+ , year = self.datepicker.state.view.year
3032
+ , remaining = parseInt(year / 12) * 12;
3033
+ self.container.children("." + self.cssClass.yearItem).remove();
3034
+ var i;
3035
+ for (i in range(12)) {
3036
+ yearItem = $("<div/>")
3037
+ .addClass(self.cssClass.yearItem)
3038
+ .data({year: (remaining + parseInt(i))})
3039
+ .text(self.datepicker._formatDigit(remaining + parseInt(i)))
3040
+ .appendTo(self.container);
3041
+ if (year === remaining + parseInt(i)) {
3042
+ yearItem.addClass(self.cssClass.selectedYear);
3043
+ }
3044
+ if (self._checkYearAccess(remaining + parseInt(i))) {
3045
+ yearItem.click(function () {
3046
+ var y = $(this).data().year;
3047
+ self.datepicker.selectYear(parseInt(y));
3048
+ self.onSelect(y);
3049
+ return false;
3050
+ });
3051
+ } else {
3052
+ yearItem.addClass(self.cssClass.disbaleItem);
3053
+ yearItem.click(function () {
3054
+ return false;
3055
+ });
3056
+
3057
+ }
3058
+ }
3059
+ return this;
3060
+ },
3061
+
3062
+ /**
3063
+ * @private
3064
+ */
3065
+ init: function () {
3066
+ this._render();
3067
+ this._attachEvents();
3068
+ return this;
3069
+ }
3070
+ };
3071
+
3072
+
3073
+ var YearPicker = function (options, container) {
3074
+ return inherit(this, [ClassSprite, ClassYearPicker, options, {
3075
+ container: container
3076
+ }]);
3077
+ };
3078
+
3079
+ 'use strict';
3080
+ /**
3081
+ * @desc {@link ClassDatepicker}
3082
+ * @class ClassToolbox
3083
+ * @type {{cssClass: {btnToday: string}, _goToday: _goToday, _render: _render, init: init}}
3084
+ */
3085
+ var ClassToolbox = {
3086
+ /**
3087
+ * Text
3088
+ */
3089
+ text: {
3090
+ btnToday: "امروز"
3091
+ },
3092
+
3093
+
3094
+ /**
3095
+ * enabled
3096
+ */
3097
+ enabled: true,
3098
+
3099
+ /**
3100
+ * cssClass
3101
+ */
3102
+ cssClass: {
3103
+ btnToday: "btn-today"
3104
+ },
3105
+
3106
+
3107
+ /**
3108
+ *
3109
+ * @private
3110
+ */
3111
+ _goToday: function () {
3112
+ var self = this;
3113
+ var todayUnix = new Date().valueOf();
3114
+ self.datepicker.selectDate(todayUnix);
3115
+ this.onToday(this);
3116
+ return this;
3117
+ },
3118
+
3119
+
3120
+ /**
3121
+ *
3122
+ * @returns {Class_Toolbox}
3123
+ * @private
3124
+ */
3125
+ _render: function () {
3126
+ var self = this;
3127
+ this.todayBtn = $("<div></div>")
3128
+ .text(self.text.btnToday)
3129
+ .addClass(self.cssClass.btnToday).click(function () {
3130
+ self._goToday();
3131
+ return false;
3132
+ }).appendTo(this.$container);
3133
+ return this;
3134
+ },
3135
+
3136
+
3137
+ /**
3138
+ *
3139
+ * @returns {Class_Toolbox}
3140
+ */
3141
+ init: function () {
3142
+ return this._render();
3143
+ }
3144
+ };
3145
+
3146
+
3147
+ var Toolbox = function (options, container) {
3148
+ return inherit(this, [ClassSprite, ClassToolbox, options, {
3149
+ $container: container
3150
+ }]);
3151
+ };
3152
+
3153
+ 'use strict';
3154
+ /**
3155
+ * @desc Instantiate in {@link ClassDatepicker}
3156
+ * @class ClassTimePicker
3157
+ * @type {{showSeconds: boolean, showMeridian: boolean, minuteStep: number, cssClss: {timepicker: string}, show: show, hide: hide, _render: _render, _currentMeridian: null, convert24hTo12: convert24hTo12, convert12hTo24: convert12hTo24, _updateTime: _updateTime, _updateMeridian: _updateMeridian, _toggleMeridian: _toggleMeridian, _movehour: _movehour, _moveminute: _moveminute, _movesecond: _movesecond, _movemeridian: _movemeridian, _updateState: _updateState, _attachEvent: _attachEvent, _bootstrap: _bootstrap, init: init}}
3158
+ */
3159
+ var ClassTimePicker = {
3160
+ /**
3161
+ * @property secondStep
3162
+ */
3163
+ secondStep: 1,
3164
+
3165
+
3166
+ /**
3167
+ * @property minuteStep
3168
+ */
3169
+ minuteStep: 1,
3170
+
3171
+ /**
3172
+ * @property hourStep
3173
+ */
3174
+ hourStep: 1,
3175
+
3176
+ /**
3177
+ * @property cssClass
3178
+ */
3179
+ cssClss: {
3180
+ timepicker: "viewModel"
3181
+ },
3182
+
3183
+
3184
+ /**
3185
+ * @property show
3186
+ * @returns {Class_Timepicker}
3187
+ */
3188
+ show: function () {
3189
+ 'use strict';
3190
+ this.container.show();
3191
+ return this;
3192
+ },
3193
+
3194
+
3195
+ /**
3196
+ * @property hide
3197
+ * @returns {Class_Timepicker}
3198
+ */
3199
+ hide: function () {
3200
+ 'use strict';
3201
+ this.container.hide();
3202
+ return this;
3203
+ },
3204
+
3205
+
3206
+ /**
3207
+ * @property _render
3208
+ * @returns {Class_Timepicker}
3209
+ * @private
3210
+ */
3211
+ _render: function () {
3212
+ var self = this;
3213
+ var viewModel = {
3214
+ css: self.cssClass
3215
+ };
3216
+ $.tmplMustache(TEMPLATE.timepicker, viewModel).appendTo(this.container);
3217
+ return this;
3218
+ },
3219
+
3220
+
3221
+ /**
3222
+ * @property _currentMeridian
3223
+ */
3224
+ _currentMeridian: null,
3225
+
3226
+
3227
+ /**
3228
+ * @property convert24hTo12
3229
+ * @param hour
3230
+ */
3231
+ convert24hTo12: function (hour) {
3232
+ var output = hour, meridian = 'AM';
3233
+ if (hour >= 12) {
3234
+ output = hour - 12;
3235
+ meridian = "PM";
3236
+ }
3237
+ if (hour === 0) {
3238
+ output = 12;
3239
+ }
3240
+ return [output, meridian];
3241
+ },
3242
+
3243
+
3244
+ /**
3245
+ * @property convert12hTo24
3246
+ * @param hour
3247
+ * @returns {*}
3248
+ */
3249
+ convert12hTo24: function (hour) {
3250
+ var output = hour;
3251
+ if (this._currentMeridian === "PM" && hour < 12) {
3252
+ output = hour + 12;
3253
+ }
3254
+ if (this._currentMeridian === "AM" && hour === 12) {
3255
+ output = hour - 12;
3256
+ }
3257
+ return output;
3258
+ },
3259
+
3260
+
3261
+ /**
3262
+ * @property _updateTime
3263
+ * @param state
3264
+ * @returns {Class_Timepicker}
3265
+ * @private
3266
+ */
3267
+ _updateTime: function (state) {
3268
+ var timeStateObject = state.selected;
3269
+ var hourArray = this.convert24hTo12(timeStateObject['hour']);
3270
+ this.hourInput.val(timeStateObject['hour']);
3271
+ this.minuteInput.val(timeStateObject['minute']);
3272
+ this.secondInput.val(timeStateObject['second']);
3273
+ this.meridianInput.val(timeStateObject.dateObj.format('a'))
3274
+ this._currentMeridian = hourArray[1];
3275
+ this.meridianInput.attr({'data-meridian-mode': this._currentMeridian});
3276
+ return this;
3277
+ },
3278
+
3279
+
3280
+ /**
3281
+ * @property _updateMeridian
3282
+ * @param state
3283
+ * @returns {Class_Timepicker}
3284
+ * @private
3285
+ */
3286
+ _updateMeridian: function (state) {
3287
+ var timeStateObject = state.selected;
3288
+ this.meridianInput.val(timeStateObject.dateObj.format('a'))
3289
+ return this;
3290
+ },
3291
+
3292
+
3293
+ /**
3294
+ *
3295
+ * @returns {Class_Timepicker}
3296
+ * @private
3297
+ */
3298
+ _toggleMeridian: function () {
3299
+ if (this._currentMeridian === 'AM') {
3300
+ this._currentMeridian = 'PM';
3301
+ this.meridianInput.val('PM');
3302
+ } else if (this._currentMeridian === 'PM') {
3303
+ this._currentMeridian = 'AM';
3304
+ this.meridianInput.val('AM');
3305
+ }
3306
+ return this;
3307
+ },
3308
+
3309
+
3310
+ /**
3311
+ *
3312
+ * @param mode
3313
+ * @returns {Class_Timepicker}
3314
+ * @private
3315
+ */
3316
+ _movehour: function (mode) {
3317
+ var currentVal = parseInt(this.hourInput.val());
3318
+ if (mode === 'up') {
3319
+ if (currentVal >= 12) {
3320
+ currentVal = this.hourStep;
3321
+ } else {
3322
+ currentVal += this.hourStep;
3323
+ }
3324
+ } else {
3325
+ if (currentVal <= 1) {
3326
+ currentVal = 12;
3327
+ } else {
3328
+ currentVal -= this.hourStep;
3329
+ }
3330
+ }
3331
+ this.hourInput.val(currentVal);
3332
+ this._updateState('hour', this.convert12hTo24(currentVal));
3333
+ return this;
3334
+ },
3335
+
3336
+
3337
+ /**
3338
+ *
3339
+ * @param mode
3340
+ * @returns {Class_Timepicker}
3341
+ * @private
3342
+ */
3343
+ _moveminute: function (mode) {
3344
+ var currentVal = parseInt(this.minuteInput.val());
3345
+ if (mode === 'up') {
3346
+ if (currentVal === 59) {
3347
+ currentVal = 0;
3348
+ } else {
3349
+ currentVal += this.minuteStep;
3350
+ }
3351
+ } else {
3352
+ if (currentVal === 0) {
3353
+ currentVal = 59;
3354
+ } else {
3355
+ currentVal -= this.minuteStep;
3356
+ }
3357
+ }
3358
+ this.minuteInput.val(currentVal);
3359
+ this._updateState('minute', currentVal);
3360
+ return this;
3361
+ },
3362
+
3363
+
3364
+ /**
3365
+ *
3366
+ * @param mode
3367
+ * @returns {Class_Timepicker}
3368
+ * @private
3369
+ */
3370
+ _movesecond: function (mode) {
3371
+ var currentVal = parseInt(this.secondInput.val());
3372
+ if (mode === 'up') {
3373
+ if (currentVal === 59) {
3374
+ currentVal = 0;
3375
+ } else {
3376
+ currentVal += this.secondStep;
3377
+ }
3378
+ } else {
3379
+ if (currentVal === 0) {
3380
+ currentVal = 59;
3381
+ } else {
3382
+ currentVal -= this.secondStep;
3383
+ }
3384
+ }
3385
+ this.secondInput.val(currentVal);
3386
+ this._updateState('second', currentVal);
3387
+ return this;
3388
+ },
3389
+
3390
+
3391
+ /**
3392
+ *
3393
+ * @returns {Class_Timepicker}
3394
+ * @private
3395
+ */
3396
+ _movemeridian: function () {
3397
+ this._toggleMeridian();
3398
+ this._updateState('hour', this.convert12hTo24(parseInt(this.hourInput.val())));
3399
+ return this;
3400
+ },
3401
+
3402
+
3403
+ /**
3404
+ *
3405
+ * @param key
3406
+ * @param val
3407
+ * @returns {Class_Timepicker}
3408
+ * @private
3409
+ */
3410
+ _updateState: function (key, val) {
3411
+ this.datepicker.selectTime(key, val);
3412
+ this._updateMeridian(this.datepicker.state);
3413
+ return this;
3414
+ },
3415
+
3416
+
3417
+ /**
3418
+ *
3419
+ * @returns {Class_Timepicker}
3420
+ * @private
3421
+ */
3422
+ _attachEvent: function () {
3423
+ var self = this;
3424
+ $('.up-btn', this.container).click(function () {
3425
+ self['_move' + $(this).parent().attr('data-time-key')]('up');
3426
+ return false;
3427
+ });
3428
+ $('.down-btn', this.container).click(function () {
3429
+ self['_move' + $(this).parent().attr('data-time-key')]('down');
3430
+ return false;
3431
+ });
3432
+ if (this.scrollEnabled) {
3433
+ $('> div.time-segment', this.container).mousewheel(function (event) {
3434
+ var moveMode = 'down';
3435
+ if (event.deltaY > 0) {
3436
+ moveMode = 'up';
3437
+ }
3438
+ self['_move' + $(this).attr('data-time-key')](moveMode);
3439
+ });
3440
+ $('> div.time-segment', this.container).bind('mousewheel DOMMouseScroll', function (e) {
3441
+ var scrollTo = null;
3442
+
3443
+ if (e.type == 'mousewheel') {
3444
+ scrollTo = (e.originalEvent.wheelDelta * -1);
3445
+ }
3446
+ else if (e.type == 'DOMMouseScroll') {
3447
+ scrollTo = 40 * e.originalEvent.detail;
3448
+ }
3449
+ if (scrollTo) {
3450
+ e.preventDefault();
3451
+ $(this).scrollTop(scrollTo + $(this).scrollTop());
3452
+ }
3453
+ });
3454
+ }
3455
+ return this;
3456
+ },
3457
+
3458
+
3459
+ /**
3460
+ *
3461
+ * @returns {Class_Timepicker}
3462
+ * @private
3463
+ */
3464
+ _bootstrap: function () {
3465
+ if (this.showMeridian === false) {
3466
+ $('.meridian', this.container).hide();
3467
+ $('.meridian-divider', this.container).hide();
3468
+ $('.time-segment', this.container).css({
3469
+ width: '31%'
3470
+ });
3471
+
3472
+ }
3473
+ if (this.showSeconds === false) {
3474
+ $('.second', this.container).hide();
3475
+ $('.second-divider', this.container).hide();
3476
+ $('.time-segment', this.container).css({
3477
+ width: '31%'
3478
+ });
3479
+ }
3480
+ if (this.showMeridian === false && this.showSeconds === false) {
3481
+ $('.time-segment', this.container).css({
3482
+ width: '47%'
3483
+ });
3484
+ }
3485
+ this.hourInput = $('.hour-input', this.container);
3486
+ this.minuteInput = $('.minute-input', this.container);
3487
+ this.secondInput = $('.second-input', this.container);
3488
+ this.meridianInput = $('.meridian-input', this.container);
3489
+ this._updateTime(this.datepicker.state);
3490
+ return this;
3491
+ },
3492
+
3493
+ /**
3494
+ *
3495
+ * @param unix
3496
+ */
3497
+ setTime:function(unix){
3498
+ var pd = new persianDate(unix);
3499
+ this._updateState('hour', pd.hour());
3500
+ this._updateState('minute', pd.minute());
3501
+ this._updateState('second', pd.second());
3502
+ this.minuteInput.val(pd.minute());
3503
+ this.secondInput.val(pd.second());
3504
+ this.hourInput.val(pd.hour());
3505
+ },
3506
+
3507
+
3508
+ /**
3509
+ *
3510
+ * @returns {Class_Timepicker}
3511
+ */
3512
+ init: function () {
3513
+ this._render()._bootstrap()._attachEvent();
3514
+
3515
+ return this;
3516
+ }
3517
+ };
3518
+ var TimePicker = function (options, container) {
3519
+ return inherit(this, [ClassSprite, ClassTimePicker, options, {
3520
+ container: container
3521
+ }]);
3522
+ };
3523
+
3524
+ 'use strict';
3525
+ /**
3526
+ * @desc Instantiate in {@link ClassDatepicker}
3527
+ * @class ClassDatepickerState
3528
+ * @type {{view: {year: number, month: number, date: number, hour: number, minute: number, second: number, unixDate: number}, selected: {year: number, month: number, date: number, hour: number, minute: number, second: number, unixDate: number}, _updateSelectedUnix: _updateSelectedUnix, setTime: setTime, setSelected: setSelected, syncViewWithelected: syncViewWithelected, setView: setView}}
3529
+ */
3530
+ var ClassDatepickerState = {
3531
+ /**
3532
+ * @desc define start and end of available date
3533
+ */
3534
+ filterDate: {
3535
+ start: {
3536
+ year: 0,
3537
+ month: 0,
3538
+ date: 0,
3539
+ hour: 0,
3540
+ minute: 0,
3541
+ second: 0,
3542
+ unixDate: 0
3543
+ },
3544
+ end: {
3545
+ year: 0,
3546
+ month: 0,
3547
+ date: 0,
3548
+ hour: 0,
3549
+ minute: 0,
3550
+ second: 0,
3551
+ unixDate: 100
3552
+ }
3553
+ },
3554
+
3555
+ /**
3556
+ * @desc view
3557
+ */
3558
+ view: {
3559
+ year: 0,
3560
+ month: 0,
3561
+ date: 0,
3562
+ hour: 0,
3563
+ minute: 0,
3564
+ second: 0,
3565
+ unixDate: 0
3566
+ },
3567
+
3568
+
3569
+ /**
3570
+ * @desc selected
3571
+ */
3572
+ selected: {
3573
+ year: 0,
3574
+ month: 0,
3575
+ date: 0,
3576
+ hour: 0,
3577
+ minute: 0,
3578
+ second: 0,
3579
+ unixDate: 0
3580
+ },
3581
+
3582
+
3583
+ /**
3584
+ * @desc setFilterDate
3585
+ * @param key
3586
+ * @param startVal
3587
+ * @param endVal
3588
+ */
3589
+ setFilterDate: function (key, startVal, endVal) {
3590
+ var self = this;
3591
+ if (!startVal) {
3592
+ startVal = -99999999999999;
3593
+ }
3594
+ var pd = new persianDate(startVal);
3595
+ self.filterDate.start.unixDate = startVal;
3596
+ self.filterDate.start.hour = pd.hour();
3597
+ self.filterDate.start.minute = pd.minute();
3598
+ self.filterDate.start.second = pd.second();
3599
+ self.filterDate.start.month = pd.month();
3600
+ self.filterDate.start.date = pd.date();
3601
+ self.filterDate.start.year = pd.year();
3602
+
3603
+ if (!endVal) {
3604
+ endVal = 99999999999999
3605
+ }
3606
+ var pd = new persianDate(endVal);
3607
+ self.filterDate.end.unixDate = endVal;
3608
+ self.filterDate.end.hour = pd.hour();
3609
+ self.filterDate.end.minute = pd.minute();
3610
+ self.filterDate.end.second = pd.second();
3611
+ self.filterDate.end.month = pd.month();
3612
+ self.filterDate.end.date = pd.date();
3613
+ self.filterDate.end.year = pd.year();
3614
+ },
3615
+
3616
+
3617
+ /**
3618
+ * @desc _updateSelectedUnix
3619
+ * @returns {Class_DatepickerState}
3620
+ * @private
3621
+ */
3622
+ _updateSelectedUnix: function () {
3623
+ this.selected.dateObj = new persianDate([this.selected.year,
3624
+ this.selected.month,
3625
+ this.selected.date,
3626
+ this.selected.hour,
3627
+ this.selected.minute,
3628
+ this.selected.second
3629
+ ])
3630
+ this.selected.unixDate = this.selected.dateObj.valueOf();
3631
+ return this;
3632
+ },
3633
+
3634
+
3635
+ /**
3636
+ * @desc setTime
3637
+ * @param key
3638
+ * @param value
3639
+ * @returns {Class_DatepickerState}
3640
+ */
3641
+ setTime: function (key, value) {
3642
+ var self = this;
3643
+ switch (key) {
3644
+ case 'unix':
3645
+ self.selected.unixDate = value;
3646
+ var pd = new persianDate(value);
3647
+ self.selected.hour = pd.hour();
3648
+ self.selected.minute = pd.minute();
3649
+ self.selected.second = pd.second();
3650
+ self._updateSelectedUnix();
3651
+ break;
3652
+ case 'hour':
3653
+ this.selected.hour = value;
3654
+ self._updateSelectedUnix();
3655
+ break;
3656
+ case 'minute':
3657
+ this.selected.minute = value;
3658
+ self._updateSelectedUnix();
3659
+ break;
3660
+ case 'second':
3661
+ this.selected.second = value;
3662
+ self._updateSelectedUnix();
3663
+ break;
3664
+ }
3665
+ return this;
3666
+ },
3667
+
3668
+
3669
+ /**
3670
+ * @desc setSelected
3671
+ * @public
3672
+ * @param key
3673
+ * @param value
3674
+ * @returns {Class_DatepickerState}
3675
+ */
3676
+ setSelected: function (key, value) {
3677
+ var self = this;
3678
+ switch (key) {
3679
+ case 'unix':
3680
+ self.selected.unixDate = value;
3681
+ var pd = new persianDate(value);
3682
+ self.selected.year = pd.year();
3683
+ self.selected.month = pd.month();
3684
+ self.selected.date = pd.date();
3685
+ self._updateSelectedUnix();
3686
+ break;
3687
+ case 'year':
3688
+ this.selected.year = value;
3689
+ self._updateSelectedUnix();
3690
+ break;
3691
+ case 'month':
3692
+ this.selected.month = value
3693
+ self._updateSelectedUnix();
3694
+ break;
3695
+ case 'date':
3696
+ this.selected.month = value
3697
+ self._updateSelectedUnix();
3698
+ break;
3699
+ }
3700
+ return this;
3701
+ },
3702
+
3703
+
3704
+ setSelectedDateTime:function (key, value) {
3705
+ var self = this;
3706
+ switch (key) {
3707
+ case 'unix':
3708
+ self.selected.unixDate = value;
3709
+ var pd = new persianDate(value);
3710
+ self.selected.year = pd.year();
3711
+ self.selected.month = pd.month();
3712
+ self.selected.date = pd.date();
3713
+ self.selected.hour = pd.hour();
3714
+ self.selected.minute = pd.minute();
3715
+ self.selected.second = pd.second();
3716
+ self._updateSelectedUnix();
3717
+ break;
3718
+ case 'year':
3719
+ this.selected.year = value;
3720
+ self._updateSelectedUnix();
3721
+ break;
3722
+ case 'month':
3723
+ this.selected.month = value
3724
+ self._updateSelectedUnix();
3725
+ break;
3726
+ case 'date':
3727
+ this.selected.month = value
3728
+ self._updateSelectedUnix();
3729
+ break;
3730
+ }
3731
+ return this;
3732
+ },
3733
+
3734
+
3735
+ /**
3736
+ * @desc syncViewWithelected
3737
+ * @public
3738
+ * @returns {Class_DatepickerState}
3739
+ */
3740
+ syncViewWithelected: function () {
3741
+ this.view.year = this.selected.year;
3742
+ this.view.month = this.selected.month;
3743
+ this.view.date = this.selected.date;
3744
+ this.view.unixDate = this.selected.unixDate;
3745
+ return this;
3746
+ },
3747
+
3748
+
3749
+ /**
3750
+ * @desc _updateViewUnix
3751
+ * @returns {Class_DatepickerState}
3752
+ * @private
3753
+ */
3754
+ _updateViewUnix: function () {
3755
+ this.view.dateObj = new persianDate([
3756
+ this.view.year,
3757
+ this.view.month,
3758
+ this.view.date,
3759
+ this.view.hour,
3760
+ this.view.minute,
3761
+ this.view.second
3762
+ ])
3763
+ this.view.unixDate = this.view.dateObj.valueOf();
3764
+ return this;
3765
+ },
3766
+
3767
+ /**
3768
+ * @desc setView
3769
+ * @public
3770
+ * @param key
3771
+ * @param value
3772
+ * @returns {Class_DatepickerState}
3773
+ */
3774
+ setView: function (key, value) {
3775
+ var self = this;
3776
+ switch (key) {
3777
+ case 'unix':
3778
+ var pd = new persianDate(value);
3779
+ self.view.year = pd.year();
3780
+ self.view.month = pd.month();
3781
+ self.view.date = pd.date();
3782
+ self.view.unixDate = value;
3783
+ break;
3784
+ case 'year':
3785
+ this.view.year = value;
3786
+ this._updateViewUnix();
3787
+ break;
3788
+ case 'month':
3789
+ this.view.month = value;
3790
+ this._updateViewUnix();
3791
+ break;
3792
+ case 'date':
3793
+ this.view.month = value;
3794
+ this._updateViewUnix();
3795
+ break;
3796
+ }
3797
+ return this;
3798
+ }
3799
+ };
3800
+
3801
+
3802
+ var State = function (options) {
3803
+ return inherit(this, [ClassDatepickerState, options]);
3804
+ };
3805
+
3806
+
3807
+ /*!
3808
+ * jQuery Mousewheel 3.1.12
3809
+ *
3810
+ * Copyright 2014 jQuery Foundation and other contributors
3811
+ * Released under the MIT license.
3812
+ * http://jquery.org/license
3813
+ */
3814
+
3815
+ (function (factory) {
3816
+ if ( typeof define === 'function' && define.amd ) {
3817
+ // AMD. Register as an anonymous module.
3818
+ define(['jquery'], factory);
3819
+ } else if (typeof exports === 'object') {
3820
+ // Node/CommonJS style for Browserify
3821
+ module.exports = factory;
3822
+ } else {
3823
+ // Browser globals
3824
+ factory(jQuery);
3825
+ }
3826
+ }(function ($) {
3827
+
3828
+ var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
3829
+ toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
3830
+ ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
3831
+ slice = Array.prototype.slice,
3832
+ nullLowestDeltaTimeout, lowestDelta;
3833
+
3834
+ if ( $.event.fixHooks ) {
3835
+ for ( var i = toFix.length; i; ) {
3836
+ $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
3837
+ }
3838
+ }
3839
+
3840
+ var special = $.event.special.mousewheel = {
3841
+ version: '3.1.12',
3842
+
3843
+ setup: function() {
3844
+ if ( this.addEventListener ) {
3845
+ for ( var i = toBind.length; i; ) {
3846
+ this.addEventListener( toBind[--i], handler, false );
3847
+ }
3848
+ } else {
3849
+ this.onmousewheel = handler;
3850
+ }
3851
+ // Store the line height and page height for this particular element
3852
+ $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
3853
+ $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
3854
+ },
3855
+
3856
+ teardown: function() {
3857
+ if ( this.removeEventListener ) {
3858
+ for ( var i = toBind.length; i; ) {
3859
+ this.removeEventListener( toBind[--i], handler, false );
3860
+ }
3861
+ } else {
3862
+ this.onmousewheel = null;
3863
+ }
3864
+ // Clean up the data we added to the element
3865
+ $.removeData(this, 'mousewheel-line-height');
3866
+ $.removeData(this, 'mousewheel-page-height');
3867
+ },
3868
+
3869
+ getLineHeight: function(elem) {
3870
+ var $elem = $(elem),
3871
+ $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
3872
+ if (!$parent.length) {
3873
+ $parent = $('body');
3874
+ }
3875
+ return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
3876
+ },
3877
+
3878
+ getPageHeight: function(elem) {
3879
+ return $(elem).height();
3880
+ },
3881
+
3882
+ settings: {
3883
+ adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
3884
+ normalizeOffset: true // calls getBoundingClientRect for each event
3885
+ }
3886
+ };
3887
+
3888
+ $.fn.extend({
3889
+ mousewheel: function(fn) {
3890
+ return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
3891
+ },
3892
+
3893
+ unmousewheel: function(fn) {
3894
+ return this.unbind('mousewheel', fn);
3895
+ }
3896
+ });
3897
+
3898
+
3899
+ function handler(event) {
3900
+ var orgEvent = event || window.event,
3901
+ args = slice.call(arguments, 1),
3902
+ delta = 0,
3903
+ deltaX = 0,
3904
+ deltaY = 0,
3905
+ absDelta = 0,
3906
+ offsetX = 0,
3907
+ offsetY = 0;
3908
+ event = $.event.fix(orgEvent);
3909
+ event.type = 'mousewheel';
3910
+
3911
+ // Old school scrollwheel delta
3912
+ if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
3913
+ if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
3914
+ if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
3915
+ if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
3916
+
3917
+ // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
3918
+ if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
3919
+ deltaX = deltaY * -1;
3920
+ deltaY = 0;
3921
+ }
3922
+
3923
+ // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
3924
+ delta = deltaY === 0 ? deltaX : deltaY;
3925
+
3926
+ // New school wheel delta (wheel event)
3927
+ if ( 'deltaY' in orgEvent ) {
3928
+ deltaY = orgEvent.deltaY * -1;
3929
+ delta = deltaY;
3930
+ }
3931
+ if ( 'deltaX' in orgEvent ) {
3932
+ deltaX = orgEvent.deltaX;
3933
+ if ( deltaY === 0 ) { delta = deltaX * -1; }
3934
+ }
3935
+
3936
+ // No change actually happened, no reason to go any further
3937
+ if ( deltaY === 0 && deltaX === 0 ) { return; }
3938
+
3939
+ // Need to convert lines and pages to pixels if we aren't already in pixels
3940
+ // There are three delta modes:
3941
+ // * deltaMode 0 is by pixels, nothing to do
3942
+ // * deltaMode 1 is by lines
3943
+ // * deltaMode 2 is by pages
3944
+ if ( orgEvent.deltaMode === 1 ) {
3945
+ var lineHeight = $.data(this, 'mousewheel-line-height');
3946
+ delta *= lineHeight;
3947
+ deltaY *= lineHeight;
3948
+ deltaX *= lineHeight;
3949
+ } else if ( orgEvent.deltaMode === 2 ) {
3950
+ var pageHeight = $.data(this, 'mousewheel-page-height');
3951
+ delta *= pageHeight;
3952
+ deltaY *= pageHeight;
3953
+ deltaX *= pageHeight;
3954
+ }
3955
+
3956
+ // Store lowest absolute delta to normalize the delta values
3957
+ absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
3958
+
3959
+ if ( !lowestDelta || absDelta < lowestDelta ) {
3960
+ lowestDelta = absDelta;
3961
+
3962
+ // Adjust older deltas if necessary
3963
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
3964
+ lowestDelta /= 40;
3965
+ }
3966
+ }
3967
+
3968
+ // Adjust older deltas if necessary
3969
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
3970
+ // Divide all the things by 40!
3971
+ delta /= 40;
3972
+ deltaX /= 40;
3973
+ deltaY /= 40;
3974
+ }
3975
+
3976
+ // Get a whole, normalized value for the deltas
3977
+ delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
3978
+ deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
3979
+ deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
3980
+
3981
+ // Normalise offsetX and offsetY properties
3982
+ if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
3983
+ var boundingRect = this.getBoundingClientRect();
3984
+ offsetX = event.clientX - boundingRect.left;
3985
+ offsetY = event.clientY - boundingRect.top;
3986
+ }
3987
+
3988
+ // Add information to the event object
3989
+ event.deltaX = deltaX;
3990
+ event.deltaY = deltaY;
3991
+ event.deltaFactor = lowestDelta;
3992
+ event.offsetX = offsetX;
3993
+ event.offsetY = offsetY;
3994
+ // Go ahead and set deltaMode to 0 since we converted to pixels
3995
+ // Although this is a little odd since we overwrite the deltaX/Y
3996
+ // properties with normalized deltas.
3997
+ event.deltaMode = 0;
3998
+
3999
+ // Add event and delta to the front of the arguments
4000
+ args.unshift(event, delta, deltaX, deltaY);
4001
+
4002
+ // Clearout lowestDelta after sometime to better
4003
+ // handle multiple device types that give different
4004
+ // a different lowestDelta
4005
+ // Ex: trackpad = 3 and mouse wheel = 120
4006
+ if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
4007
+ nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
4008
+
4009
+ return ($.event.dispatch || $.event.handle).apply(this, args);
4010
+ }
4011
+
4012
+ function nullLowestDelta() {
4013
+ lowestDelta = null;
4014
+ }
4015
+
4016
+ function shouldAdjustOldDeltas(orgEvent, absDelta) {
4017
+ // If this is an older event and the delta is divisable by 120,
4018
+ // then we are assuming that the browser is treating this as an
4019
+ // older mouse wheel event and that we should divide the deltas
4020
+ // by 40 to try and get a more usable deltaFactor.
4021
+ // Side note, this actually impacts the reported scroll distance
4022
+ // in older browsers and can cause scrolling to be slower than native.
4023
+ // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
4024
+ return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
4025
+ }
4026
+
4027
+ }));}());