Solución:
Ok, espero que te ayude. Me tomó tiempo leer la API y personalizar el código 🙂
Tomé código de muestra de Handsontable
biblioteca (última versión) e hizo pequeños cambios.
Puede haber algunos errores con él, pero es solo un prototipo, por lo que puede editarlo y, por supuesto, hace que se vea mejor.
Por alguna razón no tuve éxito en hacer el dropdownlist
para que se pueda hacer clic. Parece un problema de z-index u otros juegos de propiedades de CSS. Confío en ti para encontrar cómo solucionarlo. De todos modos, por ahora, puede usar el teclado para seleccionar manteniendo presionada la tecla Mayús para selección múltiple.
La salida es una colección de opciones seleccionadas unidas por comas.
por ejemplo:
Para que eso funcione, agregue este código después de cargar la biblioteca handsontable. Extenderá tu Handsontable
tipos de células.
(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 aquí
Para ponértelo fácil. Si desea editar el código, es posible que desee cambiar 2 métodos.
-
prepare
– Se llamará cada vez que el usuario active un evento de apertura del editor. Para configuraciones y manipulaciones. -
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 en editor y renderizado. Todo el código html del editor probablemente exista en el init
en caso de que desee cambiar alguno de ellos. los value
que es el contenido html que aparece en la celda cuando está no en modo de edición existe en getValue
método.
Espero que te ayude y que se ajuste a tu versión actual.
Guau. Tanto esfuerzo. Ahora, más de un año después, es mucho más fácil.
Utilicé el complemento jQuery elegido con éxito. Fue bastante fácil.
Este es el ejemplo de una persona: https://github.com/mydea/handsontable-chosen-editor
Elegido es hermoso. Estoy usando autocompletar con una selección múltiple. 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 configuré la columna particular de esta manera:
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}
],