123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /*! jQuery UI Accessible Datepicker extension
- * (to be appended to jquery-ui-*.custom.min.js)
- *
- * @licstart The following is the entire license notice for the
- * JavaScript code in this page.
- *
- * Copyright 2014 Kolab Systems AG
- *
- * The JavaScript code in this page is free software: you can
- * redistribute it and/or modify it under the terms of the GNU
- * General Public License (GNU GPL) as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option)
- * any later version. The code is distributed WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
- *
- * As additional permission under GNU GPL version 3 section 7, you
- * may distribute non-source (e.g., minimized or compacted) forms of
- * that code without the copy of the GNU GPL normally required by
- * section 4, provided you include this license notice and a URL
- * through which recipients can access the Corresponding Source.
- *
- * @licend The above is the entire license notice
- * for the JavaScript code in this page.
- */
-
- (function($, undefined) {
-
- // references to super class methods
- var __newInst = $.datepicker._newInst;
- var __updateDatepicker = $.datepicker._updateDatepicker;
- var __connectDatepicker = $.datepicker._connectDatepicker;
- var __showDatepicker = $.datepicker._showDatepicker;
- var __hideDatepicker = $.datepicker._hideDatepicker;
-
- // "extend" singleton instance methods
- $.extend($.datepicker, {
-
- /* Create a new instance object */
- _newInst: function(target, inline) {
- var that = this, inst = __newInst.call(this, target, inline);
-
- if (inst.inline) {
- // attach keyboard event handler
- inst.dpDiv.on('keydown.datepicker', '.ui-datepicker-calendar', function(event) {
- // we're only interested navigation keys
- if ($.inArray(event.keyCode, [ 13, 33, 34, 35, 36, 37, 38, 39, 40]) == -1) {
- return;
- }
- event.stopPropagation();
- event.preventDefault();
- inst._hasfocus = true;
-
- var activeCell;
- switch (event.keyCode) {
- case $.ui.keyCode.ENTER:
- if ((activeCell = $('.' + that._dayOverClass, inst.dpDiv).get(0) || $('.' + that._currentClass, inst.dpDiv).get(0))) {
- that._selectDay(inst.input, inst.selectedMonth, inst.selectedYear, activeCell);
- }
- break;
-
- case $.ui.keyCode.PAGE_UP:
- that._adjustDate(inst.input, -that._get(inst, 'stepMonths'), 'M');
- break;
- case $.ui.keyCode.PAGE_DOWN:
- that._adjustDate(inst.input, that._get(inst, 'stepMonths'), 'M');
- break;
-
- default:
- return that._cursorKeydown(event, inst);
- }
- })
- .attr('role', 'region')
- .attr('aria-labelledby', inst.id + '-dp-title');
- }
- else {
- var widgetId = inst.dpDiv.attr('id') || inst.id + '-dp-widget';
- inst.dpDiv.attr('id', widgetId)
- .attr('aria-hidden', 'true')
- .attr('aria-labelledby', inst.id + '-dp-title');
-
- $(inst.input).attr('aria-haspopup', 'true')
- .attr('aria-expanded', 'false')
- .attr('aria-owns', widgetId);
- }
-
- return inst;
- },
-
- /* Attach the date picker to an input field */
- _connectDatepicker: function(target, inst) {
- __connectDatepicker.call(this, target, inst);
-
- var that = this;
-
- // register additional keyboard events to control date selection with cursor keys
- $(target).unbind('keydown.datepicker-extended').bind('keydown.datepicker-extended', function(event) {
- var inc = 1;
- switch (event.keyCode) {
- case 109:
- case 173:
- case 189: // "minus"
- inc = -1;
- case 61:
- case 107:
- case 187: // "plus"
- // do nothing if the input does not contain full date string
- if (this.value.length < that._formatDate(inst, inst.selectedDay, inst.selectedMonth, inst.selectedYear).length) {
- return true;
- }
- that._adjustInstDate(inst, inc, 'D');
- that._selectDateRC(target, that._formatDate(inst, inst.selectedDay, inst.selectedMonth, inst.selectedYear));
- return false;
-
- case $.ui.keyCode.UP:
- case $.ui.keyCode.DOWN:
- // unfold datepicker if not visible
- if ($.datepicker._lastInput !== target && !$.datepicker._isDisabledDatepicker(target)) {
- that._showDatepicker(event);
- event.stopPropagation();
- event.preventDefault();
- return false;
- }
-
- default:
- if (!$.datepicker._isDisabledDatepicker(target) && !event.ctrlKey && !event.metaKey) {
- return that._cursorKeydown(event, inst);
- }
- }
- })
- // fix https://bugs.jqueryui.com/ticket/8593
- .click(function (event) { that._showDatepicker(event); })
- .attr('autocomplete', 'off');
- },
-
- /* Handle keyboard event on datepicker widget */
- _cursorKeydown: function(event, inst) {
- inst._keyEvent = true;
-
- var isRTL = inst.dpDiv.hasClass('ui-datepicker-rtl');
-
- switch (event.keyCode) {
- case $.ui.keyCode.LEFT:
- this._adjustDate(inst.input, (isRTL ? +1 : -1), 'D');
- break;
- case $.ui.keyCode.RIGHT:
- this._adjustDate(inst.input, (isRTL ? -1 : +1), 'D');
- break;
- case $.ui.keyCode.UP:
- this._adjustDate(inst.input, -7, 'D');
- break;
- case $.ui.keyCode.DOWN:
- this._adjustDate(inst.input, +7, 'D');
- break;
- case $.ui.keyCode.HOME:
- // TODO: jump to first of month
- break;
- case $.ui.keyCode.END:
- // TODO: jump to end of month
- break;
- }
-
- return true;
- },
-
- /* Pop-up the date picker for a given input field */
- _showDatepicker: function(input) {
- input = input.target || input;
- __showDatepicker.call(this, input);
-
- var inst = $.datepicker._getInst(input);
- if (inst && $.datepicker._datepickerShowing) {
- inst.dpDiv.attr('aria-hidden', 'false');
- $(input).attr('aria-expanded', 'true');
- }
- },
-
- /* Hide the date picker from view */
- _hideDatepicker: function(input) {
- __hideDatepicker.call(this, input);
-
- var inst = this._curInst;
- if (inst && !$.datepicker._datepickerShowing) {
- inst.dpDiv.attr('aria-hidden', 'true');
- $(inst.input).attr('aria-expanded', 'false');
- }
- },
-
- /* Render the date picker content */
- _updateDatepicker: function(inst) {
- __updateDatepicker.call(this, inst);
-
- var activeCell = $('.' + this._dayOverClass, inst.dpDiv).get(0) || $('.' + this._currentClass, inst.dpDiv).get(0);
- if (activeCell) {
- activeCell = $(activeCell);
- activeCell.attr('id', inst.id + '-day-' + activeCell.text());
- }
-
- // allow focus on main container only
- inst.dpDiv.find('.ui-datepicker-calendar')
- .attr('tabindex', inst.inline ? '0' : '-1')
- .attr('role', 'grid')
- .attr('aria-readonly', 'true')
- .attr('aria-activedescendant', activeCell ? activeCell.attr('id') : '')
- .find('td').attr('role', 'gridcell').attr('aria-selected', 'false')
- .find('a').attr('tabindex', '-1');
-
- $('.ui-datepicker-current-day', inst.dpDiv).attr('aria-selected', 'true');
-
- inst.dpDiv.find('.ui-datepicker-title')
- .attr('id', inst.id + '-dp-title')
-
- // set focus again after update
- if (inst._hasfocus) {
- inst.dpDiv.find('.ui-datepicker-calendar').focus();
- inst._hasfocus = false;
- }
- },
-
- _selectDateRC: function(id, dateStr) {
- var target = $(id), inst = this._getInst(target[0]);
-
- dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
- if (inst.input) {
- inst.input.val(dateStr);
- }
- this._updateAlternate(inst);
- if (inst.input) {
- inst.input.trigger("change"); // fire the change event
- }
- if (inst.inline) {
- this._updateDatepicker(inst);
- }
- }
- });
-
- }(jQuery));
|