UNPKG

alpaca

Version:

Alpaca provides the easiest and fastest way to generate interactive forms for the web and mobile devices. It runs simply as HTML5 or more elaborately using Bootstrap, jQuery Mobile or jQuery UI. Alpaca uses Handlebars to process JSON schema and provide

409 lines (344 loc) 11.2 kB
(function($) { // NOTE: this requires bootstrap-datetimepicker.js // NOTE: this requires moment.js var Alpaca = $.alpaca; Alpaca.Fields.DateField = Alpaca.Fields.TextField.extend( /** * @lends Alpaca.Fields.DateField.prototype */ { /** * @see Alpaca.Fields.TextField#getFieldType */ getFieldType: function() { return "date"; }, getDefaultFormat: function() { return Alpaca.defaultDateFormat; }, getDefaultExtraFormats: function() { return []; }, /** * @see Alpaca.Fields.TextField#setup */ setup: function() { var self = this; // default html5 input type = "date"; //this.inputType = "date"; this.base(); if (!self.options.picker) { self.options.picker = {}; } if (typeof(self.options.picker.useCurrent) === "undefined") { self.options.picker.useCurrent = false; } // date format if (self.options.picker.format) { self.options.dateFormat = self.options.picker.format; } if (!self.options.dateFormat) { self.options.dateFormat = self.getDefaultFormat(); } if (!self.options.picker.format) { self.options.picker.format = self.options.dateFormat; } if (!self.options.picker.locale) { self.options.picker.locale = Alpaca.defaultLocale; } if (!self.options.picker.dayViewHeaderFormat) { self.options.picker.dayViewHeaderFormat = "MMMM YYYY"; } // extra formats if (!self.options.picker.extraFormats) { var extraFormats = self.getDefaultExtraFormats(); if (extraFormats) { self.options.picker.extraFormats = extraFormats; } } if (typeof(self.options.manualEntry) === "undefined") { self.options.manualEntry = false; } }, onKeyPress: function(e) { if (this.options.manualEntry) { e.preventDefault(); e.stopImmediatePropagation(); } else { this.base(e); return; } }, onKeyDown: function(e) { if (this.options.manualEntry) { e.preventDefault(); e.stopImmediatePropagation(); } else { this.base(e); return; } }, beforeRenderControl: function(model, callback) { this.field.css("position", "relative"); callback(); }, /** * @see Alpaca.Fields.TextField#afterRenderControl */ afterRenderControl: function(model, callback) { var self = this; this.base(model, function() { if (self.view.type !== "display") { if ($.fn.datetimepicker) { self.getControlEl().datetimepicker(self.options.picker); self.picker = self.getControlEl().data("DateTimePicker"); if (self.picker && self.options.dateFormat) { self.picker.format(self.options.dateFormat); } if (self.picker) { self.options.dateFormat = self.picker.format(); } // with date-time picker, trigger change using plugin self.getFieldEl().on("dp.change", function(e) { // we use a timeout here because we want this to run AFTER control click handlers setTimeout(function() { self.onChange.call(self, e); self.triggerWithPropagation("change", e); }, 250); }); // set value if provided if (self.data) { self.picker.date(self.data); } } } callback(); }); }, /** * Allows manual entry mode to be toggled on and off. * * @param manualEntry */ setManualEntry: function(manualEntry) { this.options.manualEntry = manualEntry; }, /** * Returns field value as a JavaScript Date. * * @returns {Date} Field value. */ getDate: function() { var self = this; var date = null; try { if (self.picker) { date = (self.picker.date() ? self.picker.date()._d: null); } else { date = new Date(this.getValue()); } } catch (e) { console.error(e); } return date; }, /** * Returns field value as a JavaScript Date. * * @returns {Date} Field value. */ date: function() { return this.getDate(); }, /** * @see Alpaca.Field#onChange */ onChange: function(e) { this.base(); this.refreshValidationState(); }, isAutoFocusable: function() { return false; }, /** * @see Alpaca.Fields.TextField#handleValidate */ handleValidate: function() { var baseStatus = this.base(); var valInfo = this.validation; var status = this._validateDateFormat(); valInfo["invalidDate"] = { "message": status ? "" : Alpaca.substituteTokens(this.getMessage("invalidDate"), [this.options.dateFormat]), "status": status }; return baseStatus && valInfo["invalidDate"]["status"]; }, /** * Validates date format. * * @returns {Boolean} True if it is a valid date, false otherwise. */ _validateDateFormat: function() { var self = this; var isValid = true; if (self.options.dateFormat) { var value = self.getValue(); if (value || self.isRequired()) { // collect all formats var dateFormats = []; dateFormats.push(self.options.dateFormat); if (self.options.picker && self.options.picker.extraFormats) { for (var i = 0; i < self.options.picker.extraFormats.length; i++) { dateFormats.push(self.options.picker.extraFormats[i]); } } for (var i = 0; i < dateFormats.length; i++) { isValid = isValid || Alpaca.moment(value, self.options.dateFormat, true).isValid(); } } } return isValid; }, /** * @see Alpaca.Fields.TextField#setValue */ setValue: function(value) { var self = this; this.base(value); if (this.picker) { if (Alpaca.moment(value, self.options.dateFormat, true).isValid()) { this.picker.date(value); } } }, destroy: function() { this.base(); this.picker = null; } /* builder_helpers */ , /** * @see Alpaca.Fields.TextField#getTitle */ getTitle: function() { return "Date Field"; }, /** * @see Alpaca.Fields.TextField#getDescription */ getDescription: function() { return "Date Field"; }, /** * @private * @see Alpaca.Fields.TextField#getSchemaOfSchema */ getSchemaOfSchema: function() { return Alpaca.merge(this.base(), { "properties": { "format": { "title": "Format", "description": "Property data format", "type": "string", "default":"date", "enum" : ["date"], "readonly":true } } }); }, /** * @private * @see Alpaca.Fields.TextField#getOptionsForSchema */ getOptionsForSchema: function() { return Alpaca.merge(this.base(), { "fields": { "format": { "type": "text" } } }); }, /** * @private * @see Alpaca.Fields.TextField#getSchemaOfOptions */ getSchemaOfOptions: function() { return Alpaca.merge(this.base(), { "properties": { "dateFormat": { "title": "Date Format", "description": "Date format (using moment.js format)", "type": "string" }, "picker": { "title": "DatetimePicker options", "description": "Options that are supported by the <a href='http://eonasdan.github.io/bootstrap-datetimepicker/'>Bootstrap DateTime Picker</a>.", "type": "any" } } }); }, /** * @private * @see Alpaca.Fields.TextField#getOptionsForOptions */ getOptionsForOptions: function() { return Alpaca.merge(this.base(), { "fields": { "dateFormat": { "type": "text" }, "picker": { "type": "any" } } }); } /* end_builder_helpers */ }); Alpaca.registerMessages({ "invalidDate": "Invalid date for format {0}" }); Alpaca.registerFieldClass("date", Alpaca.Fields.DateField); Alpaca.registerDefaultFormatFieldMapping("date", "date"); })(jQuery);