/** * @ignore * year panel for date picker * @author yiminghe@gmail.com */ KISSY.add('date/picker/control', function (S, Node, GregorianCalendar, locale, Control, PickerRender, MonthPanel) { var tap = Node.Gesture.tap; var $ = Node.all; var undefined = undefined; var KeyCode = Node.KeyCode; function goStartMonth(self) { var next = self.get('value').clone(); next.setDayOfMonth(1); self.set('value', next); } function goEndMonth(self) { var next = self.get('value').clone(); next.setDayOfMonth(next.getActualMaximum(GregorianCalendar.MONTH)); self.set('value', next); } function goMonth(self, direction) { var next = self.get('value').clone(); next.addMonth(direction); self.set('value', next); } function goYear(self, direction) { var next = self.get('value').clone(); next.addYear(direction); self.set('value', next); } function goWeek(self, direction) { var next = self.get('value').clone(); next.addWeekOfYear(direction); self.set('value', next); } function goDay(self, direction) { var next = self.get('value').clone(); next.addDayOfMonth(direction); self.set('value', next); } function nextMonth(e) { e.preventDefault(); goMonth(this, 1); } function prevMonth(e) { e.preventDefault(); goMonth(this, -1); } function nextYear(e) { e.preventDefault(); goYear(this, 1); } function prevYear(e) { e.preventDefault(); goYear(this, -1); } function chooseCell(e) { var self = this; self.set('clear', false); var disabledDate = self.get('disabledDate'); e.preventDefault(); var td = $(e.currentTarget); var value = self.dateTable[parseInt(td.attr('data-index'))]; if (disabledDate && disabledDate(value, self.get('value'))) { return } self.set('value', value); self.fire('select', { value: value }); } function showMonthPanel(e) { e.preventDefault(); var monthPanel = this.get('monthPanel'); monthPanel.set('value', this.get('value')); monthPanel.show(); } function setUpMonthPanel() { var self = this; var monthPanel = new MonthPanel({ locale: this.get('locale'), render: self.get('el') }); monthPanel.on('select', onMonthPanelSelect, self); return monthPanel; } function onMonthPanelSelect(e) { this.set('value', e.value); this.get('monthPanel').hide(); } function chooseToday(e) { e.preventDefault(); this.set('clear', false); var today = this.get('value').clone(); today.setTime(S.now()); this.set('value', today); } function toggleClear() { var self = this, v = !self.get('clear'); if (!v) { var value = self.get('value'); value.setDayOfMonth(1); self.set('clear', false); } else { self.set('clear', true); } } function onClearClick(e) { e.preventDefault(); if (!this.get('clear')) { toggleClear.call(this); } this.fire('select', { value: null }); } /** * date picker ui component * @class KISSY.Date.Picker * @extends KISSY.Component.Control */ return Control.extend({ bindUI: function () { var self = this; self.get('nextMonthBtn').on(tap, nextMonth, self); self.get('previousMonthBtn').on(tap, prevMonth, self); self.get('nextYearBtn').on(tap, nextYear, self); self.get('previousYearBtn').on(tap, prevYear, self); self.get('tbodyEl').delegate( tap, '.' + self.view.getBaseCssClass('cell'), chooseCell, self ); self.get('monthSelectEl').on(tap, showMonthPanel, self); self.get('todayBtnEl').on(tap, chooseToday, self); self.get('clearBtnEl').on(tap, onClearClick, self); }, handleKeyDownInternal: function (e) { var self = this; var keyCode = e.keyCode; var ctrlKey = e.ctrlKey; switch (keyCode) { case KeyCode.SPACE: self.set('clear', !self.get('clear')); return true; } if (this.get('clear')) { switch (keyCode) { case KeyCode.DOWN: case KeyCode.UP: case KeyCode.LEFT: case KeyCode.RIGHT: if (!ctrlKey) { toggleClear.call(self); } return true; case KeyCode.HOME: toggleClear.call(self); goStartMonth(self); return true; case KeyCode.END: toggleClear.call(self); goEndMonth(self); return true; case KeyCode.ENTER: self.fire('select', { value: null }); return true; } } switch (keyCode) { case KeyCode.DOWN: goWeek(self, 1); return true; case KeyCode.UP: goWeek(self, -1); return true; case KeyCode.LEFT: if (ctrlKey) { goYear(self, -1); } else { goDay(self, -1); } return true; case KeyCode.RIGHT: if (ctrlKey) { goYear(self, 1); } else { goDay(self, 1); } return true; case KeyCode.HOME: goStartMonth(self); return true; case KeyCode.END: goEndMonth(self); return true; case KeyCode.PAGE_DOWN: goMonth(self, 1); return true; case KeyCode.PAGE_UP: goMonth(self, -1); return true; case KeyCode.ENTER: self.fire('select', { value: self.get('value') }); return true; } return undefined; } }, { xclass: 'date-picker', ATTRS: { focusable: { value: true }, /** * current selected value of current date picker * @cfg {KISSY.Date.Gregorian} value */ /** * @ignore */ value: { view: 1, valueFn: function () { var date = new GregorianCalendar(); date.setTime(S.now()); return date; } }, previousMonthBtn: {}, monthSelectEl: {}, monthPanel: { valueFn: setUpMonthPanel }, nextMonthBtn: {}, tbodyEl: {}, todayBtnEl: {}, /** * function used to render a date cell * * function(current){ * return '<a>'+current.getDay()+'</a>'; * } * * @cfg {Function} dateRender */ /** * @ignore */ dateRender: {}, /** * function used to judge whether this date cell is disabled * * function(current){ * // before 2010 is disabled * return current.getYear()<2010; * } * * @cfg {Function} disabledDate */ /** * @ignore */ disabledDate: {}, /** * locale object for date picker * @cfg {Object} locale */ /** * @ignore */ locale: { value: locale }, /** * whether to show today button. * Defaults to true. * @cfg {Boolean} showToday */ /** * @ignore */ showToday: { view: 1, value: true }, /** * whether to show clear button. * Defaults to true. * @cfg {Boolean} showClear */ /** * @ignore */ showClear: { view: 1, value: true }, clear: { view: 1, value: false }, /** * whether to show week number column. * Defaults to true. * @cfg {Boolean} showWeekNumber */ /** * @ignore */ showWeekNumber: { view: 1, value: true }, xrender: { value: PickerRender } } }); }, { requires: [ 'node', 'date/gregorian', 'i18n!date/picker', 'component/control', './render', './month-panel/control' ] }); /* keyboard - http://www.w3.org/TR/wai-aria-practices/#datepicker */