I am trying to extend the handsontable plugin to support multiple selections in its dropdown list. I have already tried extending the base Editor built into the library by modifying the 'dropdownEditor' as suggested https://github.com/trebuchetty/Handsontable-select2-editor/issues/7. I spent hours reading and searching through the source for keywords but I am not coming up with anything of real use.
I do not mind if this is answered using the Angular extension or another native ECMA5 or 6 way of extending the https://github.com/handsontable/handsontable plugin.
So far my only thoughts were to actually extend the framework with this bit of code following the patterns that exist. I added all LOC below that are pointing to: multiselect
or Handsontable.MultiselectDropdownCell
copied the dropdown
method, called the new name and everything works, however still cannot see where I could begin to find what I am looking for.
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
}};
I have at a modified version of dropdown editor in place that looks like:
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);
At this point I have no clue where the click event is happening when the user selects an item from the dropdown list. Debugging has been painful for me because it is through Traceur. I tried setting a click event after the module is ready and the DOM is as well however I cannot get even an alert to fire based off of a click on one of the select dropdown cells. The 'normal' cells I can get a click with a simple:
$('body').on('click','#handsontable td', someAlert)
However, not so for the menu contents. Right clicking to inspect the dropdown menu means first disabling the context menu like the one on http://handsontable.com/. Then you will notice that right clicking to inspect anything will fire an event that closes the dropdown menu you are trying to inspect.
I've put breakpoints all through the libraries source code, I cannot figure this one out.
The only thing I want to do is to figure out where the part of the code that highlights the menu item and sets it to an active selection, turn that into a method that accepts multiple selections (up to the entire array of options available, clicking an active item will disable it lets just say).
Then ensuring that those selections are actually in the Handsontable 'data scope'.
Thats it, I don't need it to even render in the cell what things have been chosen, although any help there would be great because unfortunately, I am yet to find the spot when the options in the dropdown are rendered either.
I have also tried using the Select2Editor made for handsontable as seen http://jsfiddle.net/4mpyhbjw/40/ and https://github.com/trebuchetty/Handsontable-select2-editor/issues/3 , however it does not help my cause much. Here is what the dropdown cell in handsontable looks like:
http://docs.handsontable.com/0.15.1/demo-dropdown.html
Finally, heres a fiddle: http://jsfiddle.net/tjrygch6/
I would be super appreciative if someone could help me out here. Thanks SO!
UPDATE
I have managed to parse the values in the cell and turn the type into an array containing the values (so typing red blue will turn an array containing ['red','blue']
) . I have run this array through the internal sort algorithm which parses the options and returns an index of a matching item. I get this working fine and I now am passing the array into the highlight method. This method passes the values the the core library WalkOnTable. I do not see where I can alter the logic to select more than one value instead of unhighlighting the first option.
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);
}
This is the spot where I think I need WalkontableCellCoords
to be modified to accept an array and then highlight and select both values when the dropdown is opened and closed. I also need to be able to select multiple options via touch or click event.
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;
};
Update 2
I have gotten the internal methods to recognize and partially select both values in the DOM however it is far from correct still.
Here is the console output generated by the method WalkOnTableCellCords
to be called which seems to be what highlights the dropdown selection in the case where the cell contains only 1 value (default functionality). This output is from typing black blue into a dropdown cell containing both blue and black as individual options in the list.
extended_hot_v15-01.js:5041 DropdownEditor {
"highlight": {
"row": 6,
"col": 0
},
"from":
{
"row": 4,
"col": 0
},
"to": {
"row": 6,
"col": 0
}
}
UPDATE If anyone solves this, I will personally fly to wherever you are in person, and shake your hand. TWICE.