具有多项选择的可操作下拉菜单
Handsontable dropdowns with multiple selections
我正在尝试扩展 handsontable 插件以支持其下拉列表中的多个 selection。我已经尝试通过按照建议 https://github.com/trebuchetty/Handsontable-select2-editor/issues/7 修改 'dropdownEditor' 来扩展库中内置的基本编辑器。我花了几个小时阅读和搜索源代码中的关键字,但我没有想出任何真正有用的东西。
我不介意使用 Angular 扩展或另一种扩展 https://github.com/handsontable/handsontable 插件的本机 ECMA5 或 6 方式来回答这个问题。
到目前为止,我唯一的想法是按照现有模式使用这段代码实际扩展框架。我在下面添加了所有指向的 LOC:multiselect
或 Handsontable.MultiselectDropdownCell
复制了 dropdown
方法,调用了新名称并且一切正常,但是仍然看不到我可以从哪里开始找到我的东西正在寻找。
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
}};
我有一个修改版的下拉编辑器,看起来像:
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);
在这一点上,当用户 select 从下拉列表中选择一项时,我不知道点击事件发生在何处。调试对我来说很痛苦,因为它是通过 Traceur 进行的。我尝试在模块准备就绪后设置点击事件,DOM 也准备就绪,但是我什至无法通过点击 select 下拉单元格之一触发警报。 'normal' 个单元格我可以通过简单的点击获得:
$('body').on('click','#handsontable td', someAlert)
但是,菜单内容并非如此。右键单击以检查下拉菜单意味着首先禁用上下文菜单,如 http://handsontable.com/ 上的那个。然后您会注意到,右键单击检查任何内容都会触发一个事件,该事件会关闭您尝试检查的下拉菜单。
我在整个库源代码中都设置了断点,我无法理解这一点。
我唯一想做的就是找出代码中突出显示菜单项并将其设置为活动 selection 的部分,将其转换为接受多个 selections(最多可用的整个选项数组,单击一个活动项目将禁用它,只是说)。
然后确保那些 select 离子实际上在 Handsontable 'data scope' 中。
就是这样,我什至不需要它在单元格中呈现已选择的内容,尽管任何帮助都会很棒,因为不幸的是,当下拉列表中的选项是呈现。
我也尝试过使用为 handsontable 制作的 Select2Editor,如 http://jsfiddle.net/4mpyhbjw/40/ and https://github.com/trebuchetty/Handsontable-select2-editor/issues/3 所示,但是它对我的事业没有多大帮助。
handsontable 中的下拉单元格如下所示:
http://docs.handsontable.com/0.15.1/demo-dropdown.html
最后,fiddle:http://jsfiddle.net/tjrygch6/
如果有人能帮助我,我将不胜感激。非常感谢!
更新
我已经设法解析单元格中的值并将类型转换为包含值的数组(因此键入红色蓝色将转换为包含 ['red','blue']
的数组)。我通过解析选项的内部排序算法和 returns 匹配项的索引得到 运行 这个数组。我得到这个工作正常,我现在将数组传递给突出显示方法。此方法将值传递给核心库 WalkOnTable。我看不出在哪里可以将逻辑更改为 select 多个值,而不是取消突出显示第一个选项。
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);
}
这是我认为我需要修改 WalkontableCellCoords
以接受数组然后在打开和关闭下拉列表时突出显示和 select 这两个值的地方。我还需要能够通过触摸或点击事件 select 多个选项。
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;
};
更新 2
我已经得到内部方法来识别 select DOM 中的两个值,但它仍然远未正确。
这是要调用的方法 WalkOnTableCellCords
生成的控制台输出,这似乎是在单元格仅包含 1 个值(默认功能)的情况下突出显示下拉列表 selection 的原因.此输出是通过将 black blue 键入包含蓝色和黑色作为列表中的单独选项的下拉单元格。
extended_hot_v15-01.js:5041 DropdownEditor {
"highlight": {
"row": 6,
"col": 0
},
"from":
{
"row": 4,
"col": 0
},
"to": {
"row": 6,
"col": 0
}
}
UPDATE 如果有人解决了这个问题,我会亲自飞到你在的地方,和你握手。两次。
好的,希望对你有所帮助。我花了时间阅读 api 并自定义代码 :)
我从 Handsontable
库(最新版本)中获取了示例代码并做了一些小改动。
它可能存在一些错误,但它只是一个原型,因此您当然可以对其进行编辑并使其看起来更好。
出于某种原因,我未能成功使 dropdownlist
可点击。这似乎是 z-index 问题或其他 css 属性游戏。我相信您会找到解决方法。
无论如何,现在,您可以通过按住 shift 键 select 来使用键盘 select。
输出是由逗号分隔的 selected 选项的集合。
例如:
要使该工作正常,请在加载 handsontable 库后添加此代码。它将扩展您的 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);
使用方法:
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
} {}]
});
现场演示 here
为了方便您。如果您想编辑代码,您可能需要更改 2 种方法。
prepare
- 每次用户触发编辑器打开事件时都会调用。用于配置和操作。
init
- 每次单击单元格时都会调用该方法。它会创建 html 代码,因此您可以将其更改为复选框等。
另一件事与您有关代码中的内容的问题有关。
Handsontable 将任何单元格类型拆分为编辑器和渲染器。
编辑器的所有 html 代码可能都存在于 init
中,以防您想更改其中一个。
value
是html 当你不是 在编辑模式时出现在单元格中的内容存在于getValue
方法中。
希望对您有所帮助,也希望它适合您当前的版本。
哇。如此努力。现在,一年多过去了,它变得容易多了。
我成功使用了 Chosen jQuery 插件。这很容易。
这是一个人的例子:
https://github.com/mydea/handsontable-chosen-editor
选择是美好的。我正在使用带有多选的自动完成功能。这是渲染器:
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;
}
然后我像这样设置特定的列:
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}
],
我正在尝试扩展 handsontable 插件以支持其下拉列表中的多个 selection。我已经尝试通过按照建议 https://github.com/trebuchetty/Handsontable-select2-editor/issues/7 修改 'dropdownEditor' 来扩展库中内置的基本编辑器。我花了几个小时阅读和搜索源代码中的关键字,但我没有想出任何真正有用的东西。
我不介意使用 Angular 扩展或另一种扩展 https://github.com/handsontable/handsontable 插件的本机 ECMA5 或 6 方式来回答这个问题。
到目前为止,我唯一的想法是按照现有模式使用这段代码实际扩展框架。我在下面添加了所有指向的 LOC:multiselect
或 Handsontable.MultiselectDropdownCell
复制了 dropdown
方法,调用了新名称并且一切正常,但是仍然看不到我可以从哪里开始找到我的东西正在寻找。
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
}};
我有一个修改版的下拉编辑器,看起来像:
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);
在这一点上,当用户 select 从下拉列表中选择一项时,我不知道点击事件发生在何处。调试对我来说很痛苦,因为它是通过 Traceur 进行的。我尝试在模块准备就绪后设置点击事件,DOM 也准备就绪,但是我什至无法通过点击 select 下拉单元格之一触发警报。 'normal' 个单元格我可以通过简单的点击获得:
$('body').on('click','#handsontable td', someAlert)
但是,菜单内容并非如此。右键单击以检查下拉菜单意味着首先禁用上下文菜单,如 http://handsontable.com/ 上的那个。然后您会注意到,右键单击检查任何内容都会触发一个事件,该事件会关闭您尝试检查的下拉菜单。
我在整个库源代码中都设置了断点,我无法理解这一点。
我唯一想做的就是找出代码中突出显示菜单项并将其设置为活动 selection 的部分,将其转换为接受多个 selections(最多可用的整个选项数组,单击一个活动项目将禁用它,只是说)。
然后确保那些 select 离子实际上在 Handsontable 'data scope' 中。
就是这样,我什至不需要它在单元格中呈现已选择的内容,尽管任何帮助都会很棒,因为不幸的是,当下拉列表中的选项是呈现。
我也尝试过使用为 handsontable 制作的 Select2Editor,如 http://jsfiddle.net/4mpyhbjw/40/ and https://github.com/trebuchetty/Handsontable-select2-editor/issues/3 所示,但是它对我的事业没有多大帮助。 handsontable 中的下拉单元格如下所示:
http://docs.handsontable.com/0.15.1/demo-dropdown.html
最后,fiddle:http://jsfiddle.net/tjrygch6/
如果有人能帮助我,我将不胜感激。非常感谢!
更新
我已经设法解析单元格中的值并将类型转换为包含值的数组(因此键入红色蓝色将转换为包含 ['red','blue']
的数组)。我通过解析选项的内部排序算法和 returns 匹配项的索引得到 运行 这个数组。我得到这个工作正常,我现在将数组传递给突出显示方法。此方法将值传递给核心库 WalkOnTable。我看不出在哪里可以将逻辑更改为 select 多个值,而不是取消突出显示第一个选项。
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);
}
这是我认为我需要修改 WalkontableCellCoords
以接受数组然后在打开和关闭下拉列表时突出显示和 select 这两个值的地方。我还需要能够通过触摸或点击事件 select 多个选项。
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;
};
更新 2
我已经得到内部方法来识别 select DOM 中的两个值,但它仍然远未正确。
这是要调用的方法 WalkOnTableCellCords
生成的控制台输出,这似乎是在单元格仅包含 1 个值(默认功能)的情况下突出显示下拉列表 selection 的原因.此输出是通过将 black blue 键入包含蓝色和黑色作为列表中的单独选项的下拉单元格。
extended_hot_v15-01.js:5041 DropdownEditor {
"highlight": {
"row": 6,
"col": 0
},
"from":
{
"row": 4,
"col": 0
},
"to": {
"row": 6,
"col": 0
}
}
UPDATE 如果有人解决了这个问题,我会亲自飞到你在的地方,和你握手。两次。
好的,希望对你有所帮助。我花了时间阅读 api 并自定义代码 :)
我从 Handsontable
库(最新版本)中获取了示例代码并做了一些小改动。
它可能存在一些错误,但它只是一个原型,因此您当然可以对其进行编辑并使其看起来更好。
出于某种原因,我未能成功使 dropdownlist
可点击。这似乎是 z-index 问题或其他 css 属性游戏。我相信您会找到解决方法。
无论如何,现在,您可以通过按住 shift 键 select 来使用键盘 select。
输出是由逗号分隔的 selected 选项的集合。
例如:
要使该工作正常,请在加载 handsontable 库后添加此代码。它将扩展您的 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);
使用方法:
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
} {}]
});
现场演示 here
为了方便您。如果您想编辑代码,您可能需要更改 2 种方法。
prepare
- 每次用户触发编辑器打开事件时都会调用。用于配置和操作。init
- 每次单击单元格时都会调用该方法。它会创建 html 代码,因此您可以将其更改为复选框等。
另一件事与您有关代码中的内容的问题有关。
Handsontable 将任何单元格类型拆分为编辑器和渲染器。
编辑器的所有 html 代码可能都存在于 init
中,以防您想更改其中一个。
value
是html 当你不是 在编辑模式时出现在单元格中的内容存在于getValue
方法中。
希望对您有所帮助,也希望它适合您当前的版本。
哇。如此努力。现在,一年多过去了,它变得容易多了。
我成功使用了 Chosen jQuery 插件。这很容易。
这是一个人的例子: https://github.com/mydea/handsontable-chosen-editor
选择是美好的。我正在使用带有多选的自动完成功能。这是渲染器:
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;
}
然后我像这样设置特定的列:
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}
],