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

529 lines (438 loc) 18.4 kB
/* global Metro, Cake */ (function(Metro, $) { 'use strict'; var Utils = Metro.utils; var InputDefaultConfig = { inputDeferred: 0, label: "", autocomplete: null, autocompleteUrl: null, autocompleteUrlMethod: "GET", autocompleteUrlKey: null, autocompleteDivider: ",", autocompleteListHeight: 200, history: false, historyPreset: "", historyDivider: "|", preventSubmit: false, defaultValue: "", size: "default", prepend: "", append: "", copyInlineStyles: false, searchButton: false, clearButton: true, revealButton: true, clearButtonIcon: "<span class='default-icon-cross'></span>", revealButtonIcon: "<span class='default-icon-eye'></span>", searchButtonIcon: "<span class='default-icon-search'></span>", customButtons: [], searchButtonClick: 'submit', badge: null, clsComponent: "", clsInput: "", clsPrepend: "", clsAppend: "", clsClearButton: "", clsRevealButton: "", clsCustomButton: "", clsSearchButton: "", clsLabel: "", onAutocompleteSelect: Metro.noop, onHistoryChange: Metro.noop, onHistoryUp: Metro.noop, onHistoryDown: Metro.noop, onClearClick: Metro.noop, onRevealClick: Metro.noop, onSearchButtonClick: Metro.noop, onEnterClick: Metro.noop, onInputCreate: Metro.noop }; Metro.inputSetup = function (options) { InputDefaultConfig = $.extend({}, InputDefaultConfig, options); }; if (typeof window["metroInputSetup"] !== undefined) { Metro.inputSetup(window["metroInputSetup"]); } Metro.Component('input', { init: function( options, elem ) { this._super(elem, options, InputDefaultConfig, { history: [], historyIndex: -1, autocomplete: [] }); return this; }, _create: function(){ var element = this.element; this._createStructure(); this._createEvents(); this._fireEvent("input-create", { element: element }); }, _createStructure: function(){ var that = this, element = this.element, o = this.options; var container = $("<div>").addClass("input " + element[0].className); var buttons = $("<div>").addClass("button-group"); var clearButton, revealButton, searchButton; if (Utils.isValue(o.historyPreset)) { $.each(o.historyPreset.toArray(o.historyDivider), function(){ that.history.push(this); }); that.historyIndex = that.history.length - 1; } if (element.attr("type") === undefined) { element.attr("type", "text"); } container.insertBefore(element); element.appendTo(container); buttons.appendTo(container); if (!Utils.isValue(element.val().trim())) { element.val(o.defaultValue); } if (o.clearButton === true && !element[0].readOnly) { clearButton = $("<button>").addClass("button input-clear-button").addClass(o.clsClearButton).attr("tabindex", -1).attr("type", "button").html(o.clearButtonIcon); clearButton.appendTo(buttons); } if (element.attr('type') === 'password' && o.revealButton === true) { revealButton = $("<button>").addClass("button input-reveal-button").addClass(o.clsRevealButton).attr("tabindex", -1).attr("type", "button").html(o.revealButtonIcon); revealButton.appendTo(buttons); } if (o.searchButton === true) { searchButton = $("<button>").addClass("button input-search-button").addClass(o.clsSearchButton).attr("tabindex", -1).attr("type", o.searchButtonClick === 'submit' ? "submit" : "button").html(o.searchButtonIcon); searchButton.appendTo(buttons); } if (Utils.isValue(o.prepend)) { var prepend = $("<div>").html(o.prepend); prepend.addClass("prepend").addClass(o.clsPrepend).appendTo(container); } if (Utils.isValue(o.append)) { var append = $("<div>").html(o.append); append.addClass("append").addClass(o.clsAppend).appendTo(container); } if (typeof o.customButtons === "string") { o.customButtons = Utils.isObject(o.customButtons); } if (typeof o.customButtons === "object" && Utils.objectLength(o.customButtons) > 0) { $.each(o.customButtons, function(){ var item = this; var customButton = $("<button>"); customButton .addClass("button input-custom-button") .addClass(o.clsCustomButton) .addClass(item.cls) .attr("tabindex", -1) .attr("type", "button") .html(item.html); if (item.attr && typeof item.attr === 'object') { $.each(item.attr, function(k, v){ customButton.attr(Str.dashedName(k), v); }); } customButton.data("action", item.onclick); customButton.appendTo(buttons); }); } if (Utils.isValue(element.attr('data-exclaim'))) { container.attr('data-exclaim', element.attr('data-exclaim')); } if (element.attr('dir') === 'rtl' ) { container.addClass("rtl").attr("dir", "rtl"); } element[0].className = ''; if (o.copyInlineStyles === true) { for (var i = 0, l = element[0].style.length; i < l; i++) { container.css(element[0].style[i], element.css(element[0].style[i])); } } container.addClass(o.clsComponent); element.addClass(o.clsInput); if (o.size !== "default") { container.css({ width: o.size }); } if (!Utils.isNull(o.autocomplete) || !Utils.isNull(o.autocompleteUrl)) { $("<div>").addClass("autocomplete-list").css({ maxHeight: o.autocompleteListHeight, display: "none" }).appendTo(container); } if (Utils.isValue(o.autocomplete)) { var autocomplete_obj = Utils.isObject(o.autocomplete); if (autocomplete_obj !== false) { this.autocomplete = autocomplete_obj; } else { this.autocomplete = o.autocomplete.toArray(o.autocompleteDivider); } } if (Utils.isValue(o.autocompleteUrl)) { fetch(o.autocompleteUrl, { method: o.autocompleteUrlMethod }).then(function(response){ return response.text() }).then(function(data){ var newData = []; try { newData = JSON.parse(data); if (o.autocompleteUrlKey) { newData = newData[o.autocompleteUrlKey]; } } catch (e) { newData = data.split("\n"); } that.autocomplete = that.autocomplete.concat(newData); }); } 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 (o.badge) { container.append($("<div>").addClass("badge").html(o.badge)) } if (element.is(":disabled")) { this.disable(); } else { this.enable(); } }, _createEvents: function(){ var that = this, element = this.element, o = this.options; var container = element.closest(".input"); var autocompleteList = container.find(".autocomplete-list"); container.on(Metro.events.click, ".input-clear-button", function(){ var curr = element.val(); element.val(Utils.isValue(o.defaultValue) ? o.defaultValue : "").fire('clear').fire('change').fire('keyup').focus(); if (autocompleteList.length > 0) { autocompleteList.css({ display: "none" }) } that._fireEvent("clear-click", { prev: curr, val: element.val() }); }); container.on(Metro.events.click, ".input-reveal-button", function(){ if (element.attr('type') === 'password') { element.attr('type', 'text'); } else { element.attr('type', 'password'); } that._fireEvent("reveal-click", { val: element.val() }); }); container.on(Metro.events.click, ".input-search-button", function(){ if (o.searchButtonClick !== 'submit') { that._fireEvent("search-button-click", { val: element.val(), button: this }); } else { this.form.submit(); } }); // container.on(Metro.events.stop, ".input-reveal-button", function(){ // element.attr('type', 'password').focus(); // }); container.on(Metro.events.click, ".input-custom-button", function(){ var button = $(this); var action = button.data("action"); Utils.exec(action, [element.val(), button], this); }); element.on(Metro.events.keyup, function(e){ var val = element.val().trim(); if (o.history && e.keyCode === Metro.keyCode.ENTER && val !== "") { element.val(""); that.history.push(val); that.historyIndex = that.history.length - 1; that._fireEvent("history-change", { val: val, history: that.history, historyIndex: that.historyIndex }) if (o.preventSubmit === true) { e.preventDefault(); } } if (o.history && e.keyCode === Metro.keyCode.UP_ARROW) { that.historyIndex--; if (that.historyIndex >= 0) { element.val(""); element.val(that.history[that.historyIndex]); that._fireEvent("history-down", { val: element.val(), history: that.history, historyIndex: that.historyIndex }) } else { that.historyIndex = 0; } e.preventDefault(); } if (o.history && e.keyCode === Metro.keyCode.DOWN_ARROW) { that.historyIndex++; if (that.historyIndex < that.history.length) { element.val(""); element.val(that.history[that.historyIndex]); that._fireEvent("history-up", { val: element.val(), history: that.history, historyIndex: that.historyIndex }) } else { that.historyIndex = that.history.length - 1; } e.preventDefault(); } }); element.on(Metro.events.keydown, function(e){ if (e.keyCode === Metro.keyCode.ENTER) { that._fireEvent("enter-click", { val: element.val() }); } }); element.on(Metro.events.blur, function(){ container.removeClass("focused"); }); element.on(Metro.events.focus, function(){ container.addClass("focused"); }); element.on(Metro.events.input, function(){ var val = this.value.toLowerCase(); that._drawAutocompleteList(val); }); container.on(Metro.events.click, ".autocomplete-list .item", function(){ var val = $(this).attr("data-autocomplete-value"); element.val(val); autocompleteList.css({ display: "none" }); element.trigger("change"); that._fireEvent("autocomplete-select", { value: val }); }); }, _drawAutocompleteList: function(val){ var that = this, element = this.element; var container = element.closest(".input"); var autocompleteList = container.find(".autocomplete-list"); var items; if (autocompleteList.length === 0) { return; } autocompleteList.html(""); items = this.autocomplete.filter(function(item){ return item.toLowerCase().indexOf(val) > -1; }); autocompleteList.css({ display: items.length > 0 ? "block" : "none" }); $.each(items, function(){ var v = this; var index = v.toLowerCase().indexOf(val), content; var item = $("<div>").addClass("item").attr("data-autocomplete-value", v); if (index === 0) { content = "<strong>"+v.substr(0, val.length)+"</strong>"+v.substr(val.length); } else { content = v.substr(0, index) + "<strong>"+v.substr(index, val.length)+"</strong>"+v.substr(index + val.length); } item.html(content).appendTo(autocompleteList); that._fireEvent("draw-autocomplete-item", { item: item }) }); }, getHistory: function(){ return this.history; }, getHistoryIndex: function(){ return this.historyIndex; }, setHistoryIndex: function(val){ this.historyIndex = val >= this.history.length ? this.history.length - 1 : val; }, setHistory: function(history, append) { var that = this, o = this.options; if (Utils.isNull(history)) return; if (!Array.isArray(history) && typeof history === 'string') { history = history.toArray(o.historyDivider); } if (append === true) { $.each(history, function () { that.history.push(this); }) } else{ this.history = history; } this.historyIndex = this.history.length - 1; }, clear: function(){ this.element.val(''); }, toDefault: function(){ this.element.val(Utils.isValue(this.options.defaultValue) ? this.options.defaultValue : ""); }, 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(); } }, setAutocompleteList: function(l){ var autocomplete_list = Utils.isObject(l); if (autocomplete_list !== false) { this.autocomplete = autocomplete_list; } else if (typeof l === "string") { this.autocomplete = l.toArray(this.options.autocompleteDivider); } }, changeAttribute: function(attributeName){ switch (attributeName) { case 'disabled': this.toggleState(); break; } }, destroy: function(){ var element = this.element; var parent = element.parent(); var clearBtn = parent.find(".input-clear-button"); var revealBtn = parent.find(".input-reveal-button"); var customBtn = parent.find(".input-custom-button"); if (clearBtn.length > 0) { clearBtn.off(Metro.events.click); } if (revealBtn.length > 0) { revealBtn.off(Metro.events.start); revealBtn.off(Metro.events.stop); } if (customBtn.length > 0) { clearBtn.off(Metro.events.click); } element.off(Metro.events.blur); element.off(Metro.events.focus); return element; } }); $(document).on(Metro.events.click, function(){ $('.input .autocomplete-list').hide(); }); }(Metro, m4q));