// Copyright 2016 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland // www.source-code.biz, www.inventec.ch/chdh // // License: GPL, GNU General Public License, http://www.gnu.org/licenses/gpl.html // Home page: http://www.source-code.biz/snippets/typescript /// namespace InputControls { import makeSmi = Utils.makeSmi; import isSmi = Utils.makeSmi; export class TextInputControl { protected element: JQuery; protected value: any; protected nullAllowed: boolean; public onAfterUpdate: () => void; public onError: (msg: string) => void; constructor (element: JQuery, initialValue: any = null) { this.element = element; this.setValue(initialValue); this.element.change(() => this.onChange()); this.onError = function (msg: string) { alert(msg); }; } public setNullAllowed (nullAllowed: boolean) { this.nullAllowed = nullAllowed; } public setValue (newValue: any) { this.value = newValue; this.element.val(this.formatValue(newValue)); } public getValue() : any { return this.value; } protected formatValue (value: any) : string { if (value == null) { return ""; } return String(value); } protected decodeValue (text: string) : any { let s = $.trim(text); if (s == "") { if (!this.nullAllowed) { throw new Error("Null value not allowed."); } return null; } return s; } private onChange() { let text: string = String(this.element.val()); let newValue: any; try { newValue = this.decodeValue(text); } catch (e) { this.onError(e.toString()); this.setValue(this.value); return; } this.setValue(newValue); if (this.onAfterUpdate != null) { this.onAfterUpdate(); }}} export class NumberInputControl extends TextInputControl { constructor (element: JQuery, initialValue: number | null = null) { super(element, initialValue); } protected decodeValue (text: string) : number | null { let s: string = super.decodeValue(text); if (s == null) { return null; } let x = Number(s); if (isNaN(x)) { throw new Error("Invalid number."); } return x; }} export class IntegerInputControl extends NumberInputControl { protected decodeValue (text: string) : number | null { let x: number | null = super.decodeValue(text); if (x != null && !isSmi(x)) { throw new Error("Not a valid integer value."); } return x; } // This is a redundant additional getValue() method that only delivers SMI values. // It's important for V8 optimization that float and SMI values are not mixed. public getValue() : number { return makeSmi(this.value); }} } // end namespace InputControls