UNPKG

metro4

Version:

The front-end framework for Build responsive, mobile-first projects on the web with the first front-end component library in Metro Style

577 lines (473 loc) 19.7 kB
/* global Metro, Datetime, datetime, METRO_LOCALE, METRO_DATE_FORMAT, Cake */ (function(Metro, $) { 'use strict'; var Utils = Metro.utils; var CalendarPickerDefaultConfig = { label: "", value: '', calendarpickerDeferred: 0, nullValue: true, useNow: false, prepend: "", dialogMode: false, dialogPoint: 640, dialogOverlay: true, overlayColor: '#000000', overlayAlpha: .5, locale: METRO_LOCALE, size: "100%", format: METRO_DATE_FORMAT, inputFormat: null, clearButton: false, calendarButtonIcon: "<span class='default-icon-calendar'></span>", clearButtonIcon: "<span class='default-icon-cross'></span>", copyInlineStyles: false, clsPicker: "", clsInput: "", clsPrepend: "", clsLabel: "", onDayClick: Metro.noop, onCalendarPickerCreate: Metro.noop, onCalendarShow: Metro.noop, onCalendarHide: Metro.noop, onChange: Metro.noop, onPickerChange: Metro.noop, onMonthChange: Metro.noop, onYearChange: Metro.noop }; Metro.calendarPickerSetup = function (options) { CalendarPickerDefaultConfig = $.extend({}, CalendarPickerDefaultConfig, options); }; if (typeof window["metroCalendarPickerSetup"] !== undefined) { Metro.calendarPickerSetup(window["metroCalendarPickerSetup"]); } Metro.Component('calendar-picker', { init: function( options, elem ) { this._super(elem, options, $.extend({}, Metro.defaults.Calendar, { }, CalendarPickerDefaultConfig), { value: null, value_date: null, calendar: null, overlay: null, id: Utils.elementId("calendar-picker"), time: [datetime().hour(), datetime().minute()] }); return this; }, _create: function(){ this._createStructure(); this._createEvents(); this._fireEvent("calendar-picker-create", { element: this.element }); }, _createStructure: function(){ var that = this, element = this.element, o = this.options; var container = $("<div>").addClass("input " + element[0].className + " calendar-picker"); var buttons = $("<div>").addClass("button-group"); var calendarButton, clearButton, cal = $("<div>").addClass("drop-shadow"); var curr, _curr, initTime, initHours, initMinutes, elementValue, h, m; var body = $("body"); element.attr("type", "text"); element.attr("autocomplete", "off"); element.attr("readonly", true); if (Utils.isValue(o.initialTime)) { this.time = o.initialTime.trim().split(":"); } if (Utils.isValue(o.initialHours)) { this.time[0] = parseInt(o.initialHours); } if (Utils.isValue(o.initialHours)) { this.time[1] = parseInt(o.initialMinutes); } curr = (""+o.value).trim() !== '' ? o.value : element.val().trim(); if (!Utils.isValue(curr)) { if (o.useNow) { this.value = datetime(); this.time = [this.value.hour(), this.value.minute()]; } } else { _curr = curr.split(" "); this.value = (!o.inputFormat ? datetime(_curr[0]) : Datetime.from(_curr[0], o.inputFormat, o.locale)).align("day"); if (_curr[1]) { this.time = _curr[1].trim().split(":"); } } elementValue = !curr && o.nullValue === true ? "" : datetime(that.value).format(o.format, o.locale); if (o.showTime && this.time && elementValue) { h = Str.lpad(this.time[0], "0", 2); m = Str.lpad(this.time[1], "0", 2); elementValue += " " + h + ":" + m; } element.val(elementValue); container.insertBefore(element); element.appendTo(container); buttons.appendTo(container); cal.appendTo(o.dialogMode ? body : container); if (this.time && this.time.length) { initHours = this.time[0]; if (typeof this.time[1] !== "undefined") initMinutes = this.time[1]; } initTime = o.initialTime; if (o.initialHours) { initHours = o.initialHours; } if (o.initialHours) { initMinutes = o.initialMinutes; } Metro.makePlugin(cal, "calendar", { showTime: o.showTime, initialTime: initTime, initialHours: initHours, initialMinutes: initMinutes, clsCalendarTime: o.clsCalendarTime, clsTime: o.clsTime, clsTimeHours: o.clsTimeHours, clsTimeMinutes: o.clsTimeMinutes, clsTimeButton: o.clsTimeButton, clsTimeButtonPlus: o.clsTimeButtonPlus, clsTimeButtonMinus: o.clsTimeButtonMinus, wide: o.wide, widePoint: o.widePoint, format: o.format, inputFormat: o.inputFormat, pickerMode: true, show: o.value, locale: o.locale, weekStart: o.weekStart, outside: o.outside, buttons: false, headerFormat: o.headerFormat, clsCalendar: [o.clsCalendar, "calendar-for-picker", (o.dialogMode ? "dialog-mode":"")].join(" "), clsCalendarHeader: o.clsCalendarHeader, clsCalendarContent: o.clsCalendarContent, clsCalendarFooter: "d-none", clsCalendarMonths: o.clsCalendarMonths, clsCalendarYears: o.clsCalendarYears, clsToday: o.clsToday, clsSelected: o.clsSelected, clsExcluded: o.clsExcluded, ripple: o.ripple, rippleColor: o.rippleColor, exclude: o.exclude, minDate: o.minDate, maxDate: o.maxDate, yearsBefore: o.yearsBefore, yearsAfter: o.yearsAfter, special: o.special, events: o.events, showHeader: false, showFooter: false, multiSelect: false, showWeekNumber: o.showWeekNumber, onDayClick: function(sel, day, time, el){ var date = datetime(sel[0]).align("day"); var elementValue, h, m; that._removeOverlay(); that.value = date; that.time = time; elementValue = date.format(o.format, o.locale); if (o.showTime) { h = Str.lpad(time[0], "0", 2); m = Str.lpad(time[1], "0", 2); elementValue += " " + h + ":" + m; } element.val(elementValue); element.trigger("change"); cal.removeClass("open open-up"); cal.hide(); that._fireEvent("change", { val: that.value.val(), time: that.time }); that._fireEvent("day-click", { sel: sel, day: day, time: time, el: el }); that._fireEvent("picker-change", { val: that.value.val(), time: that.time }); }, onTimeChange: function(time){ var elementValue, h, m; that.time = time; if (!that.value) { that.value = datetime(); } elementValue = that.value.format(o.format, o.locale); if (o.showTime) { h = Str.lpad(time[0], "0", 2); m = Str.lpad(time[1], "0", 2); elementValue += " " + h + ":" + m; } element.val(elementValue); that._fireEvent("change", { val: that.value.val(), time: that.time }); that._fireEvent("picker-change", { val: that.value.val(), time: that.time }); }, onMonthChange: o.onMonthChange, onYearChange: o.onYearChange }); this.calendar = cal; if (o.clearButton === true) { clearButton = $("<button>").addClass("button input-clear-button").attr("tabindex", -1).attr("type", "button").html(o.clearButtonIcon); clearButton.appendTo(buttons); } calendarButton = $("<button>").addClass("button").attr("tabindex", -1).attr("type", "button").html(o.calendarButtonIcon); calendarButton.appendTo(buttons); if (o.prepend !== "") { var prepend = $("<div>").html(o.prepend); prepend.addClass("prepend").addClass(o.clsPrepend).appendTo(container); } if (element.attr('dir') === 'rtl' ) { container.addClass("rtl"); } if (String(o.size).indexOf("%") > -1) { container.css({ width: o.size }); } else { container.css({ width: parseInt(o.size) + "px" }); } element[0].className = ''; if (o.copyInlineStyles === true) { $.each(Utils.getInlineStyles(element), function(key, value){ container.css(key, value); }); } container.addClass(o.clsPicker); element.addClass(o.clsInput); if (o.dialogOverlay === true) { this.overlay = that._overlay(); } if (o.dialogMode === true) { container.addClass("dialog-mode"); } else { if (Utils.media("(max-width: "+o.dialogPoint+"px)")) { container.addClass("dialog-mode"); this.calendar.addClass("dialog-mode"); } } if (o.label) { var label = $("<label>").addClass("label-for-input").addClass(o.clsLabel).html(o.label).insertBefore(container); if (element.attr("id")) { label.attr("for", element.attr("id")); } if (element.attr("dir") === "rtl") { label.addClass("rtl"); } } if (element.is(":disabled")) { this.disable(); } else { this.enable(); } }, _createEvents: function(){ var that = this, element = this.element, o = this.options; var container = element.parent(); var clear = container.find(".input-clear-button"); var cal = this.calendar; var cal_plugin = Metro.getPlugin(cal[0], 'calendar'); var calendar = this.calendar; $(window).on(Metro.events.resize, function(){ if (o.dialogMode !== true) { if (Utils.media("(max-width: " + o.dialogPoint + "px)")) { container.addClass("dialog-mode"); calendar.appendTo("body").addClass("dialog-mode"); } else { container.removeClass("dialog-mode"); calendar.appendTo(container).removeClass("dialog-mode"); } } }, {ns: this.id}); if (clear.length > 0) clear.on(Metro.events.click, function(e){ element.val("").trigger('change').blur(); // TODO change blur that.value = null; e.preventDefault(); e.stopPropagation(); }); container.on(Metro.events.click, "button, input", function(e){ var value = that.value ? that.value : datetime(); var presetValue = o.inputFormat ? value.format(o.inputFormat) : value.format("YYYY-MM-DD"); value.align("day"); if (cal.hasClass("open") === false && cal.hasClass("open-up") === false) { $(".calendar-picker .calendar").removeClass("open open-up").hide(); cal_plugin.setPreset([presetValue]); cal_plugin.setShow(value); if (container.hasClass("dialog-mode")) { that.overlay.appendTo($('body')); } cal.addClass("open"); if (!Utils.inViewport(cal[0])) { cal.addClass("open-up"); } that._fireEvent("calendar-show", { calendar: cal }); } else { that._removeOverlay(); cal.removeClass("open open-up"); that._fireEvent("calendar-hide", { calendar: cal }); } e.preventDefault(); e.stopPropagation(); }); element.on(Metro.events.blur, function(){container.removeClass("focused");}); element.on(Metro.events.focus, function(){container.addClass("focused");}); element.on(Metro.events.change, function(){ Utils.exec(o.onChange, [that.value.val()], element[0]); }); container.on(Metro.events.click, function(e){ e.preventDefault(); e.stopPropagation(); }) }, _overlay: function(){ var o = this.options; var overlay = $("<div>"); overlay.addClass("overlay for-calendar-picker").addClass(o.clsOverlay); if (o.overlayColor === 'transparent') { overlay.addClass("transparent"); } else { overlay.css({ background: Metro.colors.toRGBA(o.overlayColor, o.overlayAlpha) }); } return overlay; }, _removeOverlay: function(){ $('body').find('.overlay.for-calendar-picker').remove(); }, clear: function(){ this.value = datetime(); this.time = [datetime().hour(), datetime().minute()]; this.element.val("") }, val: function(v, f){ var element = this.element, o = this.options; var elementValue, h, m; if (arguments.length === 0 || Utils.isNull(v)) { return { date: this.value.val(), time: this.time }; } if (v === "") { return this.clear(); } if (f) { o.inputFormat = f; } var _curr = v.split(" "); this.value = !o.inputFormat ? datetime(_curr[0]) : Datetime.from(_curr[0], o.inputFormat, o.locale); if (_curr[1]) { this.time = _curr[1].trim().split(":"); } this.value.align("day"); Metro.getPlugin(this.calendar, "calendar").setTime(this.time); elementValue = this.value.format(o.format); if (o.showTime && this.time && elementValue) { h = Str.lpad(this.time[0], "0", 2); m = Str.lpad(this.time[1], "0", 2); elementValue += " " + h + ":" + m; } element.val(elementValue); element.trigger("change"); }, disable: function(){ this.element.data("disabled", true); this.element.parent().addClass("disabled"); }, enable: function(){ this.element.data("disabled", false); this.element.parent().removeClass("disabled"); }, toggleState: function(){ if (this.elem.disabled) { this.disable(); } else { this.enable(); } }, i18n: function(val){ var o = this.options; var hidden; var cal = this.calendar; if (val === undefined) { return o.locale; } if (Metro.locales[val] === undefined) { return false; } hidden = cal[0].hidden; if (hidden) { cal.css({ visibility: "hidden", display: "block" }); } Metro.getPlugin(cal[0], 'calendar').i18n(val); if (hidden) { cal.css({ visibility: "visible", display: "none" }); } }, getTime: function(asString){ var h, m; asString = asString || false; h = Str.lpad(this.time[0], "0", 2); m = Str.lpad(this.time[1], "0", 2); return asString ? h +":"+ m : this.time; }, changeAttribute: function(attributeName, newValue){ var that = this; var cal = Metro.getPlugin(this.calendar[0], "calendar"); switch (attributeName) { case "value": that.val(newValue); break; case 'disabled': this.toggleState(); break; case 'data-locale': that.i18n(newValue); break; case 'data-special': cal.setSpecial(newValue); break; case 'data-exclude': cal.setExclude(newValue); break; case 'data-min-date': cal.setMinDate(newValue); break; case 'data-max-date': cal.setMaxDate(newValue); break; case 'data-value': that.val(newValue); break; } }, destroy: function(){ var element = this.element; var container = element.parent(); var clear = container.find(".input-clear-button"); $(window).off(Metro.events.resize, {ns: this.id}); clear.off(Metro.events.click); container.off(Metro.events.click, "button, input"); element.off(Metro.events.blur); element.off(Metro.events.focus); element.off(Metro.events.change); Metro.getPlugin(this.calendar, "calendar").destroy(); return element; } }); $(document).on(Metro.events.click, ".overlay.for-calendar-picker",function(){ $(this).remove(); $(".calendar-for-picker.open").removeClass("open open-up"); }); $(document).on(Metro.events.click, function(){ $(".calendar-picker .calendar").removeClass("open open-up"); }); }(Metro, m4q));