изменить, как jquery UI рассчитывает количество дней в месяце

0

Я хочу отредактировать jQuery UI datepicker, чтобы работать с датой hijri, теперь плагин вычисляет количество дней в каждом месяце самостоятельно, используя

" _getDaysInMonth "

в плагине jQuery UI, как я могу обновить эту функцию без редактирования библиотеки?

и могу ли я использовать фабрику виджета jQuery для ее реализации? он просто переопределит эту основную функцию в библиотеке пользовательского интерфейса jQuery

1 ответ

0
Лучший ответ

Сделанный с использованием JQuery Widget Factory, я скопировал весь календарь jquery ui и отредактировал его код и добавил его к виджету hijridate:

    /**
 * Created by Hassan.Alnator on 1/7/14.
 */


$.widget("ui.hijridate", {

    _init: function () {

        $el.datepicker(this.options);


    },


    _widgetDatepicker: function () {
        return this.dpDiv;
    },


    setDefaults: function (settings) {
        extendRemove(this._defaults, settings || {});
        return this;
    },


    _attachDatepicker: function (target, settings) {

        var inlineSettings = null;
        for (var attrName in this._defaults) {
            var attrValue = target.getAttribute('date:' + attrName);
            if (attrValue) {
                inlineSettings = inlineSettings || {};
                try {
                    inlineSettings[attrName] = eval(attrValue);
                } catch (err) {
                    inlineSettings[attrName] = attrValue;
                }
            }
        }
        var nodeName = target.nodeName.toLowerCase();
        var inline = (nodeName == 'div' || nodeName == 'span');
        if (!target.id) {
            this.uuid += 1;
            target.id = 'dp' + this.uuid;
        }
        var inst = this._newInst($(target), inline);
        inst.settings = $.extend({}, settings || {}, inlineSettings || {});
        if (nodeName == 'input') {
            this._connectDatepicker(target, inst);
        } else if (inline) {
            this._inlineDatepicker(target, inst);
        }
    },

    /* Create a new instance object. */
    _newInst: function (target, inline) {
        var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1');
        return {id: id, input: target,
            selectedDay: 0, selectedMonth: 0, selectedYear: 0,
            drawMonth: 0, drawYear: 0,
            inline: inline,
            dpDiv: (!inline ? this.dpDiv :
                bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
    },

    /* Attach the date picker to an input field. */
    _connectDatepicker: function (target, inst) {
        var input = $(target);
        inst.append = $([]);
        inst.trigger = $([]);
        if (input.hasClass(this.markerClassName))
            return;
        this._attachments(input, inst);
        input.addClass(this.markerClassName).keydown(this._doKeyDown).
            keypress(this._doKeyPress).keyup(this._doKeyUp).
            bind("setData.datepicker",function (event, key, value) {
                inst.settings[key] = value;
            }).bind("getData.datepicker", function (event, key) {
                return this._get(inst, key);
            });
        this._autoSize(inst);
        $.data(target, PROP_NAME, inst);

        if (inst.settings.disabled) {
            this._disableDatepicker(target);
        }
    },



    _refreshDatepicker: function (target) {
        var inst = this._getInst(target);
        if (inst) {
            this._updateDatepicker(inst);
        }
    },


    _setDateDatepicker: function (target, date) {
        var inst = this._getInst(target);
        if (inst) {
            this._setDate(inst, date);
            this._updateDatepicker(inst);
            this._updateAlternate(inst);
        }
    },


    _getDateDatepicker: function (target, noDefault) {
        var inst = this._getInst(target);
        if (inst && !inst.inline)
            this._setDateFromField(inst, noDefault);
        return (inst ? this._getDate(inst) : null);
    },


    _doKeyDown: function (event) {
        var inst = $.datepicker._getInst(event.target);
        var handled = true;
        var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
        inst._keyEvent = true;
        if ($.datepicker._datepickerShowing)
            switch (event.keyCode) {
                case 9:
                    $.datepicker._hideDatepicker();
                    handled = false;
                    break;
                case 13:
                    var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
                        $.datepicker._currentClass + ')', inst.dpDiv);
                    if (sel[0])
                        $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
                    var onSelect = $.datepicker._get(inst, 'onSelect');
                    if (onSelect) {
                        var dateStr = $.datepicker._formatDate(inst);


                        onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
                    }
                    else
                        $.datepicker._hideDatepicker();
                    return false;
                    break;
                case 27:
                    $.datepicker._hideDatepicker();
                    break;
                case 33:
                    $.datepicker._adjustDate(event.target, (event.ctrlKey ?
                        -$.datepicker._get(inst, 'stepBigMonths') :
                        -$.datepicker._get(inst, 'stepMonths')), 'M');
                    break;
                case 34:
                    $.datepicker._adjustDate(event.target, (event.ctrlKey ?
                        +$.datepicker._get(inst, 'stepBigMonths') :
                        +$.datepicker._get(inst, 'stepMonths')), 'M');
                    break;
                case 35:
                    if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
                    handled = event.ctrlKey || event.metaKey;
                    break;
                case 36:
                    if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
                    handled = event.ctrlKey || event.metaKey;
                    break;
                case 37:
                    if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
                    handled = event.ctrlKey || event.metaKey;

                    if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
                        -$.datepicker._get(inst, 'stepBigMonths') :
                        -$.datepicker._get(inst, 'stepMonths')), 'M');

                    break;
                case 38:
                    if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
                    handled = event.ctrlKey || event.metaKey;
                    break;
                case 39:
                    if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
                    handled = event.ctrlKey || event.metaKey;

                    if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
                        +$.datepicker._get(inst, 'stepBigMonths') :
                        +$.datepicker._get(inst, 'stepMonths')), 'M');

                    break;
                case 40:
                    if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
                    handled = event.ctrlKey || event.metaKey;
                    break;
                default:
                    handled = false;
            }
        else if (event.keyCode == 36 && event.ctrlKey)
            $.datepicker._showDatepicker(this);
        else {
            handled = false;
        }
        if (handled) {
            event.preventDefault();
            event.stopPropagation();
        }
    },


    _doKeyPress: function (event) {
        var inst = $.datepicker._getInst(event.target);
        if ($.datepicker._get(inst, 'constrainInput')) {
            var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
            var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
            return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
        }
    },


    _doKeyUp: function (event) {
        var inst = $.datepicker._getInst(event.target);
        if (inst.input.val() != inst.lastVal) {
            try {
                var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
                    (inst.input ? inst.input.val() : null),
                    $.datepicker._getFormatConfig(inst));
                if (date) {
                    $.datepicker._setDateFromField(inst);
                    $.datepicker._updateAlternate(inst);
                    $.datepicker._updateDatepicker(inst);
                }
            }
            catch (err) {
                $.datepicker.log(err);
            }
        }
        return true;
    },


    _showDatepicker: function (input) {
        input = input.target || input;
        if (input.nodeName.toLowerCase() != 'input')
            input = $('input', input.parentNode)[0];
        if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input)
            return;
        var inst = $.datepicker._getInst(input);
        if ($.datepicker._curInst && $.datepicker._curInst != inst) {
            $.datepicker._curInst.dpDiv.stop(true, true);
            if (inst && $.datepicker._datepickerShowing) {
                $.datepicker._hideDatepicker($.datepicker._curInst.input[0]);
            }
        }
        var beforeShow = $.datepicker._get(inst, 'beforeShow');
        var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
        if (beforeShowSettings === false) {

            return;
        }
        extendRemove(inst.settings, beforeShowSettings);
        inst.lastVal = null;
        $.datepicker._lastInput = input;
        $.datepicker._setDateFromField(inst);
        if ($.datepicker._inDialog)
            input.value = '';
        if (!$.datepicker._pos) {
            $.datepicker._pos = $.datepicker._findPos(input);
            $.datepicker._pos[1] += input.offsetHeight;
        }
        var isFixed = false;
        $(input).parents().each(function () {
            isFixed |= $(this).css('position') == 'fixed';
            return !isFixed;
        });
        if (isFixed && $.browser.opera) {
            $.datepicker._pos[0] -= document.documentElement.scrollLeft;
            $.datepicker._pos[1] -= document.documentElement.scrollTop;
        }
        var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
        $.datepicker._pos = null;

        inst.dpDiv.empty();

        inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
        $.datepicker._updateDatepicker(inst);


        offset = $.datepicker._checkOffset(inst, offset, isFixed);
        inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
            'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
            left: offset.left + 'px', top: offset.top + 'px'});
        if (!inst.inline) {
            var showAnim = $.datepicker._get(inst, 'showAnim');
            var duration = $.datepicker._get(inst, 'duration');
            var postProcess = function () {
                var cover = inst.dpDiv.find('iframe.ui-datepicker-cover');
                if (!!cover.length) {
                    var borders = $.datepicker._getBorders(inst.dpDiv);
                    cover.css({left: -borders[0], top: -borders[1],
                        width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
                }
            };
            inst.dpDiv.zIndex($(input).zIndex() + 1);
            $.datepicker._datepickerShowing = true;
            if ($.effects && $.effects[showAnim])
                inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
            else
                inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
            if (!showAnim || !duration)
                postProcess();
            if (inst.input.is(':visible') && !inst.input.is(':disabled'))
                inst.input.focus();
            $.datepicker._curInst = inst;
        }
    },


    _updateDatepicker: function (inst) {


        if (!ValidateHijriDate(inst.drawYear, inst.drawMonth)) {
            alert("Invalid Hijri Year !! Out of Range.");
            return 0;
        }


        var self = this;
        self.maxRows = 4;
        var borders = $.datepicker._getBorders(inst.dpDiv);
        instActive = inst;
        inst.dpDiv.empty().append(this._generateHTML(inst));
        var cover = inst.dpDiv.find('iframe.ui-datepicker-cover');
        if (!!cover.length) {
            cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
        }
        inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
        var numMonths = this._getNumberOfMonths(inst);
        var cols = numMonths[1];
        var width = 17;
        inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
        if (cols > 1)
            inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
        inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
            'Class']('ui-datepicker-multi');
        inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
            'Class']('ui-datepicker-rtl');
        if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&


            inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
            inst.input.focus();

        if (inst.yearshtml) {
            var origyearshtml = inst.yearshtml;
            setTimeout(function () {

                if (origyearshtml === inst.yearshtml && inst.yearshtml) {
                    inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
                }
                origyearshtml = inst.yearshtml = null;
            }, 0);
        }
    },


    _getBorders: function (elem) {
        var convert = function (value) {
            return {thin: 1, medium: 2, thick: 3}[value] || value;
        };
        return [parseFloat(convert(elem.css('border-left-width'))),
            parseFloat(convert(elem.css('border-top-width')))];
    },


    _checkOffset: function (inst, offset, isFixed) {
        var dpWidth = inst.dpDiv.outerWidth();
        var dpHeight = inst.dpDiv.outerHeight();
        var inputWidth = inst.input ? inst.input.outerWidth() : 0;
        var inputHeight = inst.input ? inst.input.outerHeight() : 0;
        var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
        var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();

        offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
        offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
        offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;


        offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
            Math.abs(offset.left + dpWidth - viewWidth) : 0);
        offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
            Math.abs(dpHeight + inputHeight) : 0);

        return offset;
    },


    _findPos: function (obj) {
        var inst = this._getInst(obj);
        var isRTL = this._get(inst, 'isRTL');
        while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
            obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
        }
        var position = $(obj).offset();
        return [position.left, position.top];
    },


    _hideDatepicker: function (input) {
        var inst = this._curInst;
        if (!inst || (input && inst != $.data(input, PROP_NAME)))
            return;
        if (this._datepickerShowing) {
            var showAnim = this._get(inst, 'showAnim');
            var duration = this._get(inst, 'duration');
            var postProcess = function () {
                $.datepicker._tidyDialog(inst);
            };
            if ($.effects && $.effects[showAnim])
                inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
            else
                inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
                    (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
            if (!showAnim)
                postProcess();
            this._datepickerShowing = false;
            var onClose = this._get(inst, 'onClose');
            if (onClose)
                onClose.apply((inst.input ? inst.input[0] : null),
                    [(inst.input ? inst.input.val() : ''), inst]);
            this._lastInput = null;
            if (this._inDialog) {
                this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
                if ($.blockUI) {
                    $.unblockUI();
                    $('body').append(this.dpDiv);
                }
            }
            this._inDialog = false;
        }
    },


    _tidyDialog: function (inst) {
        inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
    },


    _checkExternalClick: function (event) {
        if (!$.datepicker._curInst)
            return;

        var $target = $(event.target),
            inst = $.datepicker._getInst($target[0]);

        if (( ( $target[0].id != $.datepicker._mainDivId &&
            $target.parents('#' + $.datepicker._mainDivId).length == 0 && !$target.hasClass($.datepicker.markerClassName) && !$target.closest("." + $.datepicker._triggerClass).length &&
            $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
            ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ))
            $.datepicker._hideDatepicker();
    },


    _adjustDate: function (id, offset, period) {
        var target = $(id);
        var inst = this._getInst(target[0]);
        if (this._isDisabledDatepicker(target[0])) {
            return;
        }
        this._adjustInstDate(inst, offset +
            (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0),
            period);
        this._updateDatepicker(inst);
    },


    _gotoToday: function (id) {
        var target = $(id);
        var inst = this._getInst(target[0]);
        if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
            inst.selectedDay = inst.currentDay;
            inst.drawMonth = inst.selectedMonth = inst.currentMonth;
            inst.drawYear = inst.selectedYear = inst.currentYear;
        }
        else {
            var date = new HijriDate();
            inst.selectedDay = date.getDate();
            inst.drawMonth = inst.selectedMonth = date.getMonth();
            inst.drawYear = inst.selectedYear = date.getFullYear();
        }
        this._notifyChange(inst);
        this._adjustDate(target);
    },


    _selectMonthYear: function (id, select, period) {
        var target = $(id);
        var inst = this._getInst(target[0]);
        inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
            inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
                parseInt(select.options[select.selectedIndex].value, 10);
        this._notifyChange(inst);
        this._adjustDate(target);
    },


    _selectDay: function (id, month, year, td) {
        var target = $(id);
        if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
            return;
        }
        var inst = this._getInst(target[0]);
        inst.selectedDay = inst.currentDay = $('a', td).html();
        inst.selectedMonth = inst.currentMonth = month;
        inst.selectedYear = inst.currentYear = year;
        this._selectDate(id, this._formatDate(inst,
            inst.currentDay, inst.currentMonth, inst.currentYear));
    },


    _clearDate: function (id) {
        var target = $(id);
        var inst = this._getInst(target[0]);
        this._selectDate(target, '');
    },

    _selectDate: function (id, dateStr) {
        var target = $(id);
        var inst = this._getInst(target[0]);
        dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
        if (inst.input)
            inst.input.val(dateStr);
        this._updateAlternate(inst);
        var onSelect = this._get(inst, 'onSelect');
        if (onSelect)
            onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
        else if (inst.input)
            inst.input.trigger('change');
        if (inst.inline) {
            this._updateDatepicker(inst);
        }
        else {
            this._hideDatepicker();
            this._lastInput = inst.input[0];
            if (typeof(inst.input[0]) != 'object')
                inst.input.focus();
            this._lastInput = null;
        }
    },


    _updateAlternate: function (inst) {
        var altField = this._get(inst, 'altField');
        if (altField) {
            var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
            var date = this._getDate(inst);
            var dateStr = this.formatDate(altFormat, date.gregDate, this._getFormatConfig(inst));
            $(altField).each(function () {
                $(this).val(dateStr);
            });
        }
    }


});
  • 0
    Вам действительно нужно использовать функцию eval() ?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню