UNPKG

@transmutable/bink

Version:

A sleek and reactive framework for web pages

109 lines (97 loc) 3.35 kB
import dom from '../../DOM.js' import Component from '../../Component.js' /** TextInputComponent shows the user a field or area in which to enter text. @example <caption>Set `TextInputComponent.text` to user's input (no DataModel)</caption> * const component = new TextInputComponent(undefined, { * text: 'Starting text', * placeholder: 'Enter some text here' // Shown when no text had been entered * }) * // Listen for text changes * component.listenTo(TextInputComponent.TextChangeEvent, (eventName, textValue) => { * console.log('Text was input', textValue) * }) @example <caption>Bind text input to a DataModel field</caption> * const component = new TextInputComponent(myDataModel, { * dataField: 'biography', * placeholder: 'Tell us who you are', // Shown when no text had been entered * submitOnEnter: true * }) * // Listen for text submission, usually by pressing the 'Enter' key * component.listenTo(TextInputComponent.TextSubmitEvent, (eventName, newValue) => { * console.log('New text was submitted', newValue) * }) */ const TextInputComponent = class extends Component { /** @param {string} [options.text=''] initial text @param {string} [options.dataField=''] a field on the dataObject on which to bind @param {string} [options.placeholder=''] text to show when the input is empty @param {bool} [options.submitOnEnter=true] trigger a submit event on `enter` keyUp event */ constructor(dataObject = null, options = {}) { super( dataObject, Object.assign( { text: '', placeholder: '', dom: dom.input({ type: 'text' }), name: 'TextInputComponent', submitOnEnter: true, }, options ) ) this.addClass('text-input-component') this._handleModelChange = this._handleModelChange.bind(this) this._placeholderText = this.options.placeholder if (this._placeholderText) { this.dom.setAttribute('placeholder', this._placeholderText) } this._text = null this._shifted = false this.listenTo('input', this.dom, (ev) => { this.text = this.dom.value }) this.listenTo('keyup', this.dom, (ev) => { if (this.options.submitOnEnter && ev.keyCode === 13) { this.trigger(TextInputComponent.TextSubmitEvent, this._text) this.text = '' } }) if (this.dataObject && this.options.dataField) { this.text = this.dataObject.get(this.options.dataField, '') this.listenTo(`changed:${this.options.dataField}`, this.dataObject, this._handleModelChange) } else { this.text = this.options.text } this.dom.value = this.text } _handleModelChange() { this.text = this.dataObject.get(this.options.dataField, '') } get text() { return this._text } set text(value) { value = value || '' if (this._text === value) return this._text = value const usingPlaceholder = !this._text if (usingPlaceholder) { this.addClass('placeholder') } else { this.removeClass('placeholder') } this.value = this._text if (this.dataObject && this.options.dataField && this.dataObject.get(this.options.dataField) !== this._text) { this.dataObject.set(this.options.dataField, this._text) } this.trigger(TextInputComponent.TextChangeEvent, this._text) } } TextInputComponent.TextChangeEvent = 'text-input-change' TextInputComponent.TextSubmitEvent = 'text-input-submit' export default TextInputComponent export { TextInputComponent }