span javascript angularjs drop-down-menu multi-select handsontable

javascript - span - select group html



Desplegable de mesa con mĂșltiples selecciones (2)

Estoy tratando de extender el complemento handsontable para admitir varias selecciones en su lista desplegable. Ya he intentado ampliar el Editor base integrado en la biblioteca modificando el ''editor de dropdown'' como se sugiere https://github.com/trebuchetty/Handsontable-select2-editor/issues/7 . Pasé horas leyendo y buscando en la fuente las palabras clave, pero no creo nada de uso real.

No me importa si esto se responde con la extensión Angular u otra forma nativa de ECMA5 o 6 de extender el complemento https://github.com/handsontable/handsontable .

Hasta ahora, mis únicos pensamientos eran extender el marco con este bit de código siguiendo los patrones que existen. Handsontable.MultiselectDropdownCell todos los LOC a continuación que apuntan a: multiselect o Handsontable.MultiselectDropdownCell copió el método dropdown , llamado el nuevo nombre y todo funciona, sin embargo, todavía no puedo ver dónde puedo encontrar lo que estoy buscando.

Handsontable.MultiselectDropdownCell = { editor: getEditorConstructor(''multiselectdropdown''), renderer: getRenderer(''autocomplete'') }; Handsontable.cellTypes = { text: Handsontable.TextCell, date: Handsontable.DateCell, numeric: Handsontable.NumericCell, checkbox: Handsontable.CheckboxCell, autocomplete: Handsontable.AutocompleteCell, handsontable: Handsontable.HandsontableCell, password: Handsontable.PasswordCell, dropdown: Handsontable.DropdownCell, multiselect: Handsontable.MultiselectDropdownCell }; Handsontable.cellLookup = { validator: { numeric: Handsontable.NumericValidator, autocomplete: Handsontable.AutocompleteValidator }};

Tengo una versión modificada del editor desplegable que se parece a esto:

import {getEditor, registerEditor} from ''./../editors.js''; import {AutocompleteEditor} from ''./autocompleteEditor.js''; /** * @private * @editor MultiSelectDropdownEditor * @class MultiSelectDropdownEditor * @dependencies AutocompleteEditor */ class MultiSelectDropdownEditor extends AutocompleteEditor { prepare(row, col, prop, td, originalValue, cellProperties) { super.prepare(row, col, prop, td, originalValue, cellProperties); this.cellProperties.filter = false; this.cellProperties.strict = true; } } export {MultiSelectDropdownEditor}; registerEditor(''multiselectdropdown'', MultiSelectDropdownEditor);

En este momento no tengo idea de dónde está ocurriendo el evento de clic cuando el usuario selecciona un elemento de la lista desplegable. La depuración ha sido dolorosa para mí porque es a través de Traceur. Intenté establecer un evento de clic después de que el módulo esté listo y el DOM también. Sin embargo, no puedo obtener ni siquiera una alerta para disparar en función de un clic en una de las celdas desplegables de selección. Las celdas ''normales'' me pueden dar un click con un simple:

$(''body'').on(''click'',''#handsontable td'', someAlert)

Sin embargo, no es así para los contenidos del menú. Al hacer clic con el botón derecho para inspeccionar el menú desplegable, primero se deshabilita el menú contextual como el de http://handsontable.com/ . Luego notará que hacer clic con el botón derecho para inspeccionar cualquier cosa activará un evento que cierra el menú desplegable que está intentando inspeccionar.

He puesto puntos de interrupción a lo largo del código fuente de las bibliotecas, no puedo resolver esto.

Lo único que quiero hacer es averiguar en qué parte del código que resalta el elemento del menú y lo establece en una selección activa, conviértalo en un método que acepte varias selecciones (hasta la gama completa de opciones disponibles, haciendo clic en un elemento activo lo deshabilitará solo digamos).

Luego, asegúrese de que esas selecciones estén realmente en el ''alcance de datos'' de Handsontable.

Eso es, no necesito ni siquiera para representar en la celda las cosas que se han elegido, aunque cualquier ayuda sería genial porque, desafortunadamente, todavía tengo que encontrar el lugar cuando las opciones en el menú desplegable se representen.

También he intentado usar el Select2Editor hecho para handsontable como se ve http://jsfiddle.net/4mpyhbjw/40/ y https://github.com/trebuchetty/Handsontable-select2-editor/issues/3 , sin embargo, no ayuda mi causa mucho Aquí es cómo se ve la celda desplegable en handsontable:

http://docs.handsontable.com/0.15.1/demo-dropdown.html

Finalmente, aquí hay un violín: http://jsfiddle.net/tjrygch6/

Estaría muy agradecido si alguien pudiera ayudarme aquí. ¡Gracias!

ACTUALIZAR

Me las arreglé para analizar los valores en la celda y convertir el tipo en una matriz que contiene los valores (de modo que teclear rojo azul convertirá una matriz que contenga [''red'',''blue''] ). He ejecutado esta matriz a través del algoritmo de ordenación interno que analiza las opciones y devuelve un índice de un elemento coincidente. Consigo este trabajo bien y ahora estoy pasando la matriz al método de resaltado. Este método pasa los valores de la biblioteca central WalkOnTable. No veo dónde puedo alterar la lógica para seleccionar más de un valor en lugar de resaltar la primera opción.

this.selectCell = function(row, col, endRow, endCol, scrollToCell, changeListener) { var coords; changeListener = typeof changeListener === ''undefined'' || changeListener === true; if (typeof row !== ''number'' && !Array.isArray(row) || row < 0 || row >= instance.countRows()) { return false; } if (typeof col !== ''number'' || col < 0 || col >= instance.countCols()) { return false; } if (typeof endRow !== ''undefined'') { if (typeof endRow !== ''number'' || endRow < 0 || endRow >= instance.countRows()) { return false; } if (typeof endCol !== ''number'' || endCol < 0 || endCol >= instance.countCols()) { return false; } } // Normal number value, one item typed in if (!Array.isArray(row) && typeof row === ''number''){ coords = new WalkontableCellCoords(row, col); walkSelection(coords); }

Este es el lugar donde creo que necesito que WalkontableCellCoords se modifique para aceptar una matriz y luego resaltar y seleccionar ambos valores cuando se abre y cierra el menú desplegable. También necesito poder seleccionar múltiples opciones a través del evento táctil o de clic.

else { // Array found, apply to each value new WalkontableCellCoords(row[0], col); new WalkontableCellCoords(row[1], col); } function walkSelection(coords){ priv.selRange = new WalkontableCellRange(coords, coords, coords); if (document.activeElement && document.activeElement !== document.documentElement && document.activeElement !== document.body) { document.activeElement.blur(); } if (changeListener) { instance.listen(); } if (typeof endRow === ''undefined'') { selection.setRangeEnd(priv.selRange.from, scrollToCell); } else { selection.setRangeEnd(new WalkontableCellCoords(endRow, endCol), scrollToCell); } instance.selection.finish(); } return true;

};

Actualización 2

He obtenido los métodos internos para reconocer y seleccionar parcialmente ambos valores en el DOM, pero aún está lejos de ser correcto.

Aquí se muestra la salida de la consola generada por el método WalkOnTableCellCords que parece ser lo que resalta la selección desplegable en el caso de que la celda solo contenga 1 valor (funcionalidad predeterminada). Esta salida es de escribir negro azul en una celda desplegable que contiene tanto el azul como el negro como opciones individuales en la lista.

extended_hot_v15-01.js:5041 DropdownEditor { "highlight": { "row": 6, "col": 0 }, "from": { "row": 4, "col": 0 }, "to": { "row": 6, "col": 0 } }

ACTUALIZACIÓN Si alguien resuelve esto, volaré personalmente a donde sea que esté en persona y le daré la mano. DOS VECES.


Guau. Tanto esfuerzo Ahora, más de un año después, es mucho más fácil.

Usé el plugin JQuery elegido con éxito. Fue bastante fácil.

Aquí hay un ejemplo de una persona: https://github.com/mydea/handsontable-chosen-editor

Elegido es hermoso. Estoy usando autocompletar con un multiselección. Aquí está el renderizador:

function customDropdownRenderer(instance, td, row, col, prop, value, cellProperties) { var selectedId; var optionsList = cellProperties.chosenOptions.data; if(typeof optionsList === "undefined" || typeof optionsList.length === "undefined" || !optionsList.length) { Handsontable.TextCell.renderer(instance, td, row, col, prop, value, cellProperties); return td; } var values = (value + "").split(","); value = []; for (var index = 0; index < optionsList.length; index++) { if (values.indexOf(optionsList[index].id + "") > -1) { selectedId = optionsList[index].id; value.push(optionsList[index].label); } } value = value.join(", "); Handsontable.TextCell.renderer(instance, td, row, col, prop, value, cellProperties); return td; }

y luego acabo de configurar la columna particular como esta:

columns: [ {}, {}, {type: ''numeric''}, {type: ''dropdown'', source: ['''', ''NAME'', ''FNB'']}, {}, {}, {}, {}, {}, {}, {}, {type: ''dropdown'', source: ['''', ''S'', ''M'']}, {}, {}, { renderer: customDropdownRenderer, editor: "chosen", width: 150, chosenOptions: { multiple: true, data: productData } }, {}, {editor: false, readOnly: true, width: 1}, {editor: false, readOnly: true, width: 1} ],


Ok, espero que te ayude. Me tomó tiempo leer la api y personalizar el código :)

Tomé un código de muestra de la biblioteca de Handsontable (última versión) e hice pequeños cambios.

Puede haber algunos errores, pero es solo un prototipo, así que puedes editar y hacer que se vea mejor, por supuesto.

Por alguna razón no tuve éxito en hacer que la dropdownlist pueda hacer clic. Parece que el tema z-index u otros juegos de propiedades css. Confío en ti para encontrar la manera de arreglarlo. De todos modos, por ahora, puede usar el teclado para seleccionar manteniendo presionada la tecla shift para la selección múltiple.

La salida es una colección de opciones seleccionadas unidas por comas separadas.

por ejemplo:

Para que funcione, agregue este código después de cargar la biblioteca de handsontable. Extenderá sus tipos de celulares Handsontable .

(function(Handsontable) { var SelectEditor = Handsontable.editors.BaseEditor.prototype.extend(); SelectEditor.prototype.init = function() { // Create detached node, add CSS class and make sure its not visible this.select = document.createElement(''SELECT''); Handsontable.Dom.addClass(this.select, ''htSelectEditor''); this.select.style.display = ''none''; // Attach node to DOM, by appending it to the container holding the table this.instance.rootElement.appendChild(this.select); }; // Create options in prepare() method SelectEditor.prototype.prepare = function() { // Remember to invoke parent''s method Handsontable.editors.BaseEditor.prototype.prepare.apply(this, arguments); this.isMultiple = !!this.cellProperties.multiple; if (this.isMultiple) this.select.multiple = true; var selectOptions = this.cellProperties.selectOptions; var options; if (typeof selectOptions == ''function'') { options = this.prepareOptions(selectOptions(this.row, this.col, this.prop)) } else { options = this.prepareOptions(selectOptions); } Handsontable.Dom.empty(this.select); for (var option in options) { if (options.hasOwnProperty(option)) { var optionElement = document.createElement(''OPTION''); optionElement.value = option; Handsontable.Dom.fastInnerHTML(optionElement, options[option]); this.select.appendChild(optionElement); } } }; SelectEditor.prototype.prepareOptions = function(optionsToPrepare) { var preparedOptions = {}; if (Array.isArray(optionsToPrepare)) { for (var i = 0, len = optionsToPrepare.length; i < len; i++) { preparedOptions[optionsToPrepare[i]] = optionsToPrepare[i]; } } else if (typeof optionsToPrepare == ''object'') { preparedOptions = optionsToPrepare; } return preparedOptions; }; SelectEditor.prototype.getValue = function() { var result = []; var options = this.select && this.select.options; var opt; for (var i = 0, iLen = options.length; i < iLen; i++) { opt = options[i]; if (opt.selected) { result.push(opt.value || opt.text); } } return result.join(); }; SelectEditor.prototype.setValue = function(value) { this.select.value = value; }; SelectEditor.prototype.open = function() { var width = Handsontable.Dom.outerWidth(this.TD); // important - group layout reads together for better performance var height = Handsontable.Dom.outerHeight(this.TD); var rootOffset = Handsontable.Dom.offset(this.instance.rootElement); var tdOffset = Handsontable.Dom.offset(this.TD); var editorSection = this.checkEditorSection(); var cssTransformOffset; if (this.select && this.select.options && this.isMultiple) { var height = 0; for (var i = 0; i < this.select.options.length - 1; i++) { height += Handsontable.Dom.outerHeight(this.TD); } } switch (editorSection) { case ''top'': cssTransformOffset = Handsontable.Dom.getCssTransform(this.instance.view.wt.wtScrollbars.vertical.clone.wtTable.holder.parentNode); break; case ''left'': cssTransformOffset = Handsontable.Dom.getCssTransform(this.instance.view.wt.wtScrollbars.horizontal.clone.wtTable.holder.parentNode); break; case ''corner'': cssTransformOffset = Handsontable.Dom.getCssTransform(this.instance.view.wt.wtScrollbars.corner.clone.wtTable.holder.parentNode); break; } var selectStyle = this.select.style; if (cssTransformOffset && cssTransformOffset !== -1) { selectStyle[cssTransformOffset[0]] = cssTransformOffset[1]; } else { Handsontable.Dom.resetCssTransform(this.select); } selectStyle.height = height + ''px''; selectStyle.minWidth = width + ''px''; selectStyle.top = tdOffset.top - rootOffset.top + ''px''; selectStyle.left = tdOffset.left - rootOffset.left + ''px''; selectStyle.margin = ''0px''; selectStyle.display = ''''; }; SelectEditor.prototype.checkEditorSection = function() { if (this.row < this.instance.getSettings().fixedRowsTop) { if (this.col < this.instance.getSettings().fixedColumnsLeft) { return ''corner''; } else { return ''top''; } } else { if (this.col < this.instance.getSettings().fixedColumnsLeft) { return ''left''; } } }; SelectEditor.prototype.close = function() { this.select.style.display = ''none''; }; Handsontable.editors.registerEditor(''dvirH'', SelectEditor); })(Handsontable);

La forma de usarlo:

var container = document.getElementById("example1"); var hot1; hot1 = new Handsontable(container, { data: [ [''2008'', ''Nissan'', 11], [''2009'', ''Honda'', 11], [''2010'', ''Kia'', 15] ], colHeaders: true, contextMenu: false, columns: [{}, { editor: ''select'', selectOptions: [''Kia'', ''Nissan'', ''Toyota'', ''Honda''], // notice that attribute. You can remove it to get a regular select multiple: true } {}] });

Demo en vivo here

Para que sea fácil para ti. Si desea editar el código, hay 2 métodos que puede querer cambiar.

  1. prepare : se llamará cada vez que el usuario active un evento de edición de editor. Para configuraciones y manipulaciones.
  2. init : se llamará a ese método cada vez que haga clic en una celda. Crea el código html para que pueda cambiarlo a casillas de verificación, por ejemplo.

Otra cosa se relaciona con sus preguntas sobre dónde están las cosas en el código.

Handsontable divide cualquier tipo de celda a editor y renderiza. Es probable que todo el código html del editor exista en el init en caso de que desee cambiar uno de ellos. El value que es el contenido html que aparece en la celda cuando no está en modo de edición existe en getValue método getValue .

Espero que ayude, y espero que se ajuste a su versión actual.