UNPKG

toloframework

Version:

Javascript/HTML/CSS compiler for Firefox OS or nodewebkit apps using modules in the nodejs style.

275 lines (258 loc) 7.29 kB
var Widget = require("wdg"); /** * HTML5 text input with many options. * * @param {string} opts.value Initial value. * @param {string} opts.type Input's type. Can be `text`, `password`, ... * @param {string} opts.name The name can be used by the browser to give a help combo. * @param {string} opts.placeholder Text to display when input is empty. * @param {function|regexp} opts.validator function to check the * validity of this input. Takes the input value as argument and * returns a boolean. `onEnter` is not fired until input is valid. You * can use a RegExp instead of a function to check validity. * @param {function|object} opts.onEnter function to call when user * hits `enter` key. `function(this)`. It can be an object with a * function called `fire()`. * @param {function|object} opts.onValid function to call when * validator has been called. `function(validity, this)`. It can be an * object with a function `enabled({boolean})`. For instance a * `wdg.Button`. * * @example * var Input = require("wdg.input"); * var opts = { * placeholder: 'email address'; * validator: /[^@]+@([^@\.]+\.)*[^@\.]+/, * onEnter: function(wdg) { * console.log("Enter has been hitten!"); * }, * onValid: function(validity, wdg) { * console.log("Validity: ", validity); * } * } * var instance = new Input(opts); * @example * var I = require("wdg.input").create; * var btnNext = B(_("next")).Tap( * function() { * alert("Youpi!"); * } * ); * var login = I( * { * type: "email", * name: "email", * placeholder: _("email"), * validator: /^[^@]+@[^@]+$/, * onEnter: btnNext, * onValid: btnNext * } * ); * @class Input */ var Input = function(opts) { Widget.call(this); var input = Widget.tag("input"); this._input = input; var that = this; this.addClass("wdg-input"); if (typeof opts !== 'object') opts = {}; if (typeof opts.type !== 'string') opts.type = 'text'; input.attr("type", opts.type); if (typeof opts.placeholder === 'string') { input.attr("placeholder", opts.placeholder); } if (typeof opts.size !== 'undefined') { opts.size = parseInt(opts.size) || 8; input.attr("size", opts.size); } if (typeof opts.width !== 'undefined') { input.css("width", opts.width); } var onValid = opts.onValid; if (typeof onValid === 'object' && typeof onValid.enabled === 'function') { opts.onValid = function(v) { onValid.enabled(v); }; } else if (typeof onValid !== 'function') opts.onValid = null; if (typeof opts.validator === 'object') { var rx = opts.validator; opts.validator = function(v) { return rx.test(v); }; } this._valid = 0; if (typeof opts.validator === 'function') { input.addEvent( "keyup", function() { opts.validator.call(this); } ); } input.addEvent( "keyup", function() { that.fireChange(); } ); if (typeof opts.onEnter === 'object' && typeof opts.onEnter.fire === 'function') { var onEnter = opts.onEnter; this.Enter(function() { onEnter.fire(); }); } input.addEvent( "keyup", function(evt) { if (that._valid > -1 && evt.keyCode == 13) { // On rend l'événement asynchrone pour éviter les // problèmes de clavier virtuel qui reste affiché. window.setTimeout( function() { that.fireEnter(); } ); } else { that.validate(); } } ); if (typeof opts.value !== 'string') { opts.value = ""; } input.addEvent( "focus", function() { that.selectAll(); } ); this._opts = opts; this.val(opts.value); if (typeof opts.label !== 'undefined') { var label = Widget.div("label").text(opts.label).attr("title", opts.label); this.append(label); } this.append(input); }; // Cette classe hérite de Widget Input.prototype = Object.create(Widget.prototype); Input.prototype.constructor = Input; /** * Force value validation. */ Input.prototype.validate = function() { var opts = this._opts; if (typeof opts.validator !== 'function') return this; var onValid = opts.onValid; try { if (opts.validator(this.val())) { this._valid = 1; this._input.removeClass("not-valid").addClass("valid"); if (onValid) onValid(true, this); } else { this._valid = -1; this._input.removeClass("valid").addClass("not-valid"); if (onValid) onValid(false, this); } } catch (ex) { console.error("[wdg.input] Validation error: ", ex); } return this; }; /** * @return void */ Input.prototype.fireChange = function() { var slot = this._Change; if (typeof slot === 'function') { slot.call(this); } }; /** * Accessor for attribute Change. */ Input.prototype.Change = function(slot) { if (typeof slot === 'undefined') return this._Change; if (typeof slot === 'function') { this._Change = slot; } return this; }; /** * Accessor for attribute Enter. */ Input.prototype.Enter = function(slot) { if (typeof slot === 'undefined') return this._Enter; if (typeof slot === 'function') { this._Enter = slot; } return this; }; /** * @return void */ Input.prototype.fireEnter = function() { var slot = this._Enter; if (typeof slot === 'function') { slot.call(this); } }; /** * Select whole text. * @return {this} */ Input.prototype.selectAll = function() { var e = this._input.element(); e.setSelectionRange(0, e.value.length); return true; }; /** * Accessor for textual content of this input. */ Input.prototype.val = function(v) { var e = this._input.element(); if (typeof v === 'undefined') return e.value; e.value = v; this.validate(); return this; }; /** * @return void */ Input.prototype.focus = function() { var e = this._input.element(); window.setTimeout( function() { e.focus(); }, 1 ); return this; }; /** * @return void */ Input.prototype.isValid = function() { return this._valid == 1 ? true : false; }; /** * @return void */ Input.prototype.enabled = function(v) { if (typeof v === 'undefined') { return this._input.hasAttr("disabled"); } if (v) { this._input.removeAttr("disabled"); } else { this._input.attr("disabled", "true"); } return this; }; Input.create = function(opts) { return new Input(opts); }; module.exports = Input;