UNPKG

persiandate-picker

Version:
471 lines (423 loc) 14.4 kB
/** * @class ClassDatepicker * @type {{_pickers: {}, _getNextState: _getNextState, _checkNextStateAvalibility: _checkNextStateAvalibility, changeView: changeView, _flagSelfManipulate: boolean, selectTime: selectTime, selectDate: selectDate, selectMonth: selectMonth, selectYear: selectYear, _formatDigit: _formatDigit, destroy: destroy, _syncWithImportData: _syncWithImportData, _attachEvents: _attachEvents, _updateInputElement: _updateInputElement, _defineOnInitState: _defineOnInitState, events: {}, _viewed: boolean, init: init}} */ var ClassDatepicker = { /** * * @desc list of picker obejcts like dayPicker,monthPicker,yearPicker * @private */ _pickers: {}, /** * @desc save current visibility state of plugin * @private */ _viewed: false, /** * @desc if plugin selector detect as a div or any element exsept inpout set as true * @private */ _inlineView: false, /** * @desc define next state of {@link ClassDatepicker._pickers} * @param {string} action . Acceptable Value : 'day','month',year * @returns {*} * @private */ _getNextState: function (action) { var currentState = this.currentView; var nextState = this.currentView; if (action === 'next') { if (currentState === 'month' && this.dayPicker) { nextState = 'day'; } if (currentState === 'year') { if (this.monthPicker) { nextState = 'month'; } else { if (this.dayPicker) { nextState = 'day'; } } } } else if (action === 'prev') { if (currentState === 'month' && this.yearPicker) { nextState = 'year'; } if (currentState === 'day') { if (this.monthPicker) { nextState = 'month'; } else { if (this.yearPicker) { nextState = 'year'; } } } } return this._checkNextStateAvalibility(nextState); }, /** * @desc check next state is available in {@link ClassDatepicker._pickers} * @param {string} state Accepptable Value: 'day','month','year' * @returns {*} * @private */ _checkNextStateAvalibility: function (state) { if (!this._pickers[state]) { this.element.main.hide(); return false; $.error(state + "Picker Set as {enabled:false} and dos not exist!! Set viewMode to Enabled view Check Configuration"); } return state; }, /** * @desc update {@link ClassNavigator} object switch text * @param switchStr * @public * @returns {ClassDatepicker} */ updateNavigator: function (switchStr) { if (this.navigator) { this.navigator.updateSwitchBtn(this._formatDigit(switchStr)); } return this; }, /** * @desc update {@link ClassNavigator} relaion state * @param switchStr * @public * @returns {ClassDatepicker} */ switchNavigatorRelation: function (newState) { if (this.navigator) { this.navigator.switchRelation(newState); } return this; }, /** * @desc change {@link _pickers} visibility * @param state * @param action * @returns {ClassDatepicker} */ changeView: function (state, action) { var self = this; var newState; if (!action) { newState = this._checkNextStateAvalibility(state); } else { newState = this._getNextState(action); } if (newState) { self.publishInDic(self._pickers, 'hide'); self._pickers[newState].show(); self.switchNavigatorRelation(newState); self.currentView = newState; } return this; }, /** * @desc used in {@link ClassDatepicker._attachEvents} * @private */ _flagSelfManipulate: true, /** * @desc only called by {@link ClassTimepicker} * @param key * @param val * @event */ selectTime: function (key, val) { this.state.setTime(key, val); this._updateInputElement(); this.onSelect(key, this); }, /** * @desc only called by {@link ClassDaypicker} * @param key * @param unixDate * @returns {ClassDatepicker} * @event */ selectDate: function (unixDate) { var self = this; self.state.setSelected('unix', unixDate); this.state.syncViewWithelected(); switch (self.currentView) { case ('month'): self.monthPicker.selectMonth(); break; case ('year'): self.yearPicker.selectYear(); break; case ('day'): self.dayPicker.selectDay(); break; } self._updateInputElement(); self.onSelect(unixDate, this); if (self.autoClose) { self.element.main.hide(); } return this; }, /** * @desc only called by {@link ClassDaypicker} * @param key * @param unixDate * @returns {ClassDatepicker} * @event */ selectDateTime: function (unixDate) { var self = this; self.state.setSelectedDateTime('unix', unixDate); this.state.syncViewWithelected(); switch (self.currentView) { case ('month'): self.monthPicker.selectMonth(); break case ('year'): self.yearPicker.selectYear(); break case ('day'): self.dayPicker.selectDay(); break } self._updateInputElement(); self.onSelect(unixDate, this); if (self.autoClose) { self.element.main.hide(); } return this; }, /** * @desc only called by {@link ClassMonthPicker} * @param monthNum * @returns {ClassDatepicker} */ selectMonth: function (monthNum) { var self = this; if (this.justSelectOnDate) { self.state.setView('month', monthNum); } else { self.state.setSelected('month', monthNum); self.state.setSelected('year', self.state.view.year); self.state.syncViewWithelected(); } self._updateInputElement(); self.changeView(self.currentView, 'next'); return this; }, /** * @desc only called by {@link ClassYearPicker} * @param yearNum * @returns {ClassDatepicker} */ selectYear: function (yearNum) { var self = this; if (this.justSelectOnDate) { self.state.setView('year', yearNum); } else { self.state.setSelected('year', yearNum); self.state.syncViewWithelected(); } self._updateInputElement(); self.changeView(self.currentView, 'next'); return this; }, /** * @desc check {@link ClassDatepicker.persianDigit} and if set true all digit convert to persian * @param digit * @returns {*} * @private */ _formatDigit: function (digit) { if (this.persianDigit && digit) { return digit.toString().toPersianDigit(); } else { return digit; } }, /** * @desc use in {@link ClassDatepicker._attachEvents} * @param pasted * @returns {ClassDatepicker} * @private */ _syncWithImportData: function (pasted) { if (pasted) { var self = this; if (jQuery.isNumeric(pasted)) { var newPersainDate = new persianDate(pasted); self.state.setSelected('unix', newPersainDate); self._updateInputElement(); } else { var persianDateArray = self.validatePersianDateString(pasted); if (persianDateArray != null) { delay(function () { var newPersainDate = new persianDate(persianDateArray); self.selectDate(newPersainDate.valueOf()); }, self.inputDelay) } } } return this; }, /** * @desc Attach all dom events to rendered element. * @returns {ClassDatepicker} * @private */ _attachEvents: function () { var self = this; $(window).resize(function () { self.view.fixPosition(self); }); if (self.observer) { ///////////////// Manipulate by Copy And paste self.inputElem.bind('paste', function (e) { delay(function () { self._syncWithImportData(e.target.value); }, 60); }); ///////////////// Manipulate by alt changes $(self.altField).bind("change", function () { if (!self._flagSelfManipulate) { var newDate = new Date($(this).val()); if (newDate !== "Invalid Date") { var newPersainDate = new persianDate(newDate); self.selectDate(newPersainDate.valueOf()); } } }); ///////////////// Manipulate by keyboard var ctrlDown = false; var ctrlKey = [17, 91], vKey = 86, cKey = 67; $(document).keydown(function (e) { if ($.inArray(e.keyCode, ctrlKey) > 0) ctrlDown = true; }).keyup(function (e) { if ($.inArray(e.keyCode, ctrlKey) > 0) ctrlDown = false; }); self.inputElem.bind("keyup", function (e) { var $self = $(this); if (!self._flagSelfManipulate) { var trueKey = false; 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 ))) { trueKey = true; } if (trueKey) { self._syncWithImportData($self.val()); } } }); } self.inputElem.focus(function () { self.show(); }); self.inputElem.click(function (e) { e.stopPropagation(); return false; }); self.inputElem.blur(function () { if (!$.browser.msie) { self.hide(); } }); $(document).not(".datepicker-plot-area,.datepicker-plot-area > *").click(function (e) { self.inputElem.blur(); self.hide(); }); $(self.element.main).mousedown(function (e) { e.stopPropagation(); return false; }); return this; }, /** * @desc update input and altField input elemet value * @returns {ClassDatepicker} * @private */ _updateInputElement: function () { var self = this; self._flagSelfManipulate = true; // Update Alt Field self.altField.val(self.altFieldFormatter(self.state.selected.unixDate)).trigger('change'); ; // Update Display Field self.inputElem.val(self.formatter(self.state.selected.unixDate)).trigger('change'); ; self._flagSelfManipulate = false; return self; }, /** * @desc bootstrap method of {@link ClassDatepicker} * @returns {ClassDatepicker} * @private */ _defineOnInitState: function () { if ($(this.$container)[0].nodeName == 'INPUT') { var garegurianDate = new Date(this.inputElem.val()).valueOf(); this.$container = $('body'); } else { var garegurianDate = new Date($(this.$container).data('date')).valueOf(); this._inlineView = true; } if (garegurianDate && garegurianDate != 'undefined') { this.state.unixDate = garegurianDate; } else { this.state.unixDate = new Date().valueOf(); } this.altField = $(this.altField); this.state.setSelectedDateTime('unix', this.state.unixDate); this.state.setTime('unix', this.state.unixDate); this.state.setView('unix', this.state.unixDate); return this; }, /** * @desc set time of timepicker */ setTime: function () { this.timePicker.setTime(this.state.selected.unixDate); }, /** * @desc set date of datepicker */ setDate: function (p) { var date = new persianDate(p); this.selectDateTime(date.valueOf()); if (this.timePicker.enabled) this.setTime(); return this; }, /** * @desc initilize {@link ClassDatepicker} * @returns {ClassDatepicker} */ init: function () { var self = this; this.state = new State({datepicker: self}); this.compatConfig(); this._defineOnInitState(); this._updateInputElement(); this.view = this.views['default']; this.view.render(this); this.inputElem.data("datepicker", this); this.inputElem.addClass(self.cssClass); this._attachEvents(); return this; } }; var Datepicker = function (mainElem, options) { return inherit(this, [ClassSprite, ClassCompat, ClassDatepicker, ViewsDatePicker, ClassConfig, options, { $container: mainElem, inputElem: $(mainElem) }]); };