UNPKG

mtt-simple

Version:

Biblioteca de componentes y helpers para desarrollo de formularios en SIMPLE digital

132 lines (118 loc) 4.25 kB
'use strict' const $ = require('jquery') /** * @typedef {Object} DropdownSimpleOpsTypedef * @property {string} propEtiqueta - nombre de la propiedad en el objeto usado como etiqueta del campo * @property {string} propValor - nombre de la propiedad en el objeto usada como valor del campo * @property {string} valorComo - forma en que se guarda el valor en el campo destino object|value * @property {string} textoSeleccionar - texto que aparecerá como primer valor en caso de que el Select no tenga valor * @property {number} habilitaBusqueda - cantidad de elementos máxima presentada sin habilitar la búsqueda */ /** * @type {DropdownSimpleOpsTypedef} */ const DEFAULTS_DROPDOWN_SIMPLE = { propEtiqueta: 'etiqueta', propValor: 'valor', valorComo: 'object', // 'object', 'value', textoSeleccionar: 'Seleccione', habilitaBusqueda: 5 // -1 search disabled } class DropdownSimpleUI { /** * * @param {string} nombreCampo * @param {any[]} listaDatos * @param {any} valorInicial * @param {DropdownSimpleOpsTypedef} opciones */ constructor(nombreCampo, listaDatos, valorInicial, opciones) { const elm = $(`[name='${nombreCampo}']`) if (elm.length) { this.$elmRef = elm[0] this.listadoDatos = listaDatos this.valorInicial = valorInicial /** @type {DropdownSimpleOpsTypedef} */ this.opts = Object.assign({}, DEFAULTS_DROPDOWN_SIMPLE, opciones || {}) this._dibujar() } else { throw new Error(`elemento de formulario no encontrado '${nombreCampo}'`) } } /** * Obtener el valor del elemento dependiendo del tipo y la configuracion * relativa al estilo seleccion 'valorComo' */ _getValorElemento(elm) { if (typeof elm === 'object') { return elm[this.opts.propValor] + '' } else { return elm + '' } } /** * Obtener el valor usado para mostrar como etiqueta del elemento indicado dependiendo tipo * y configuracion relativa al estilo selección 'valorComo' */ _getTextoEtiqueta(elm) { if (typeof elm === 'object') { if (typeof this.opts.propEtiqueta === 'function') { return this.opts.propEtiqueta(elm) } else { return elm[this.opts.propEtiqueta] } } else { return elm } } /** * comparación de dos elementos a y b en torno a su valor * usando configuración relativa a 'valorComo' * @param {any} a * @param {any} b */ _valoresIguales(a, b) { return this._getValorElemento(a) === this._getValorElemento(b) } /** * despliega el elemento en pantalla según el tipo de elemento referenciado */ _dibujar() { if (this.$elmRef.nodeName === 'SELECT') { this.$formElement = this._transformarElemento(this.$elmRef) } else { this.$formElement = this._crearElemento() } } _agregarOptions(select, items, selected, placeholderText) { const $select = $(select) $select.append(`<option value=''>${placeholderText}</option>`) items.forEach(item => { const valueEquals = this._valoresIguales(item, selected) const opt = $(`<option value='${this._getValorElemento(item)}' ${valueEquals ? 'selected' : ''}>${this._getTextoEtiqueta(item)}</option>`) $select.append(opt) }); } _transformarElemento(elm) { const $elm = $(elm) const selectedValue = $elm.val() || this.valorInicial $elm.empty() this._agregarOptions(elm, this.listadoDatos, selectedValue, this.opts.textoSeleccionar) // forzar redibujo para tomar nuevas opciones $elm.chosen('destroy').chosen({ disable_search_threshold: this.opts.habilitaBusqueda > 0 ? this.opts.habilitaBusqueda : 999999 }) return $elm } _crearElemento() { const $select = $(`<select id='${DropdownSimpleUI._name}_${this.$elmRef.attr('name')}' class="form-control form-control-chosen" data-placeholder="${this.opts.textoSeleccionar}"></select>`) this._agregarOptions($select, this.listadoDatos) $select.chosen() return $select } } DropdownSimpleUI._name = 'DropdownSimpleUI' module.exports = { DropdownSimpleUI }