具有多个选择的双手下拉菜单

Alp*_*33k 18 javascript multi-select angularjs handsontable drop-down-menu

我正在尝试扩展handsontable插件以支持其下拉列表中的多个选择.我已经尝试通过按照建议https://github.com/trebuchetty/Handsontable-select2-editor/issues/7修改'dropdownEditor'来扩展内置到库中的基本编辑器 .我花了几个小时阅读和搜索关键字的来源,但我没有想出任何真正的用途.

我不介意使用Angular扩展或其他原生ECMA5或扩展https://github.com/handsontable/handsontable插件的方式来解决这个问题.

到目前为止,我唯一的想法是使用这些代码按照存在的模式实际扩展框架.我在下面添加了指向的所有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
}};
Run Code Online (Sandbox Code Playgroud)

我有一个修改版的下拉编辑器,它看起来像:

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);
Run Code Online (Sandbox Code Playgroud)

此时,我不知道用户从下拉列表中选择项目时发生click事件的位置.调试对我来说很痛苦,因为它是通过Traceur实现的.我尝试在模块准备就绪后设置点击事件,并且DOM也是如此,但是根据其中一个选择下拉单元格的点击,我甚至无法触发警报."普通"单元格我只需简单点击即可:

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

但是,菜单内容不是这样.右键单击以检查下拉菜单意味着首先禁用上下文菜单,如http://handsontable.com/上的菜单.然后您会注意到右键单击以检查任何内容将触发一个事件,该事件将关闭您要检查的下拉菜单.

我已经通过库源代码放置了断点,我无法想出这一点.

我唯一想做的就是找出突出显示菜单项并将其设置为活动选择的代码部分,将其转换为接受多个选择的方法(直到可用的整个选项数组,单击一个活动的项目将禁用它只是说).

然后确保这些选择实际上在Handsontable'数据范围'中.

多数民众赞成,我不需要它甚至在单元格中呈现所选择的内容,尽管任何帮助都会很棒,因为不幸的是,我还没有找到下拉列表中的选项时的位置.

我也尝试过使用Select2Editor for handsontable,如http://jsfiddle.net/4mpyhbjw/40/https://github.com/trebuchetty/Handsontable-select2-editor/issues/3,但它没有帮助我的事业很多.以下是handontable中的下拉单元格:

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

最后,还有一个小提琴:http://jsfiddle.net/tjrygch6/

如果有人能帮助我,我会非常感激.谢谢!

UPDATE

我已设法解析单元格中的值并将类型转换为包含值的数组(因此键入红色蓝色将转换包含的数组['red','blue']).我通过内部排序算法运行此数组,该算法解析选项并返回匹配项的索引.我得到了这个工作正常,我现在将数组传递给高亮方法.此方法传递核心库WalkOnTable的值.我没有看到我可以在哪里改变逻辑来选择多个值而不是取消第一个选项的突出显示.

 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);
}
Run Code Online (Sandbox Code Playgroud)

这是我认为我需要WalkontableCellCoords修改以接受数组然后在打开和关闭下拉列表时突出显示并选择这两个值的位置.我还需要能够通过触摸或点击事件选择多个选项.

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;
Run Code Online (Sandbox Code Playgroud)

};

更新2

我已经获得了内部方法来识别和部分选择DOM中的两个值,但它仍远未正确.

根据键入单元格中的两个值显示两个项目的选择(类型),同时在控制台中显示从此动手插件中幕后使用的WalkOnTable工具返回的coord的输出. 输出低于

这是由WalkOnTableCellCords要调用的方法生成的控制台输出,这似乎是在单元格仅包含1个值(默认功能)的情况下突出显示下拉选择的内容.此输出是将黑蓝键入包含蓝色和黑色的下拉单元格,作为列表中的单个选项.

extended_hot_v15-01.js:5041 DropdownEditor {
            "highlight": {
                    "row": 6,
                    "col": 0
            },
            "from":
                   {
                    "row": 4,
                    "col": 0
                   },
             "to": {
                    "row": 6,
                    "col": 0
                    }
            }
Run Code Online (Sandbox Code Playgroud)

更新如果有人解决了这个问题,我将亲自飞往您所在的任何地方,并握手.两次.

小智 3

哇。这么多努力。现在,一年多过去了,事情变得容易多了。

我成功使用了 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;
}
Run Code Online (Sandbox Code Playgroud)

然后我像这样设置特定的列:

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}
],
Run Code Online (Sandbox Code Playgroud)