Thanks for the reply.
I have then opened an improvement request on Github here : https://github.com/handsontable/react-handsontable/issues/201
If anyone is trying to achieve what I want. Here is what I’ve achieved that could be a work-around. The idea is to create a unique React editor (set on the whole table), and use it to dispatch edition to the different editors.
In the following example, instead of setting the editors in cellProperties.type
, I set it on cellProperties.theType
, and call it just like Handsontable would do. That allows me to use basic Handsontable editors.
But I can also use a React editor if I want, for example here I’m using a KeyboardDatePicker.
import React from 'react';
import NativeListener from 'react-native-listener';
import { BaseEditorComponent } from '@handsontable/react';
import Handsontable from 'handsontable';
import { KeyboardDatePicker } from '@material-ui/pickers';
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
export default class EditorComponent extends BaseEditorComponent {
// Our already created editors
editors = new Map();
// Current 'normal' editor we are working on
currentEditor;
constructor(props) {
super(props);
this.mainElementRef = React.createRef();
this.containerStyle = {
display: 'none',
position: 'absolute',
left: 0,
top: 0,
background: '#fff',
// border: '1px solid #000',
// padding: '15px',
zIndex: 999,
};
// Trigger state for the reactEditor
this.state = {
reactEditor: undefined,
value: undefined,
};
}
discardEditor(result) {
if (this.currentEditor) {
super.discardEditor(result);
} else {
super.discardEditor(false);
}
console.log('discard editor', result);
}
setValue(value, callback) {
console.log(value);
if (this.currentEditor) {
this.currentEditor.setValue(value);
} else {
//this.cellProperties.instance.setDataAtCell(this.row, this.col, 42);
this.setState((state, props) => {
return { value };
}, callback);
}
}
getValue() {
if (this.currentEditor) {
return this.currentEditor.getValue();
}
return this.state.value;
}
open() {
if (this.currentEditor) {
this.currentEditor.open();
} else {
this.mainElementRef.current.style.display = 'block';
}
}
close() {
if (this.currentEditor) {
this.currentEditor.close();
this.currentEditor = undefined;
} else {
this.setState((state, props) => {
return { reactEditor: undefined };
});
this.mainElementRef.current.style.display = 'none';
}
}
onClose() {
super.discardEditor(true);
this.close();
}
prepare(row, col, prop, td, originalValue, cellProperties) {
// We'll need to call the `prepare` method from
// the `BaseEditorComponent` class, as it provides
// the component with the information needed to use the editor
// (hotInstance, row, col, prop, TD, originalValue, cellProperties)
super.prepare(row, col, prop, td, originalValue, cellProperties);
// Here I create a normal editor (not React)
if (row % 2 === 0) {
const TheClass = new Handsontable.cellTypes.getCellType(cellProperties.theType).editor;
if (!this.editors.has(TheClass)) {
this.editors.set(TheClass, new TheClass(cellProperties.instance));
}
this.currentEditor = this.editors.get(TheClass);
this.currentEditor.prepare(row, col, prop, td, originalValue, cellProperties);
} else {
this.setState((state, props) => {
return {
reactEditor: <KeyboardDatePicker onChange={date => this.setValue(date)} onClose={() => this.onClose()} />,
};
});
const tdPosition = td.getBoundingClientRect();
// As the `prepare` method is triggered after selecting
// any cell, we're updating the styles for the editor element,
// so it shows up in the correct position.
this.mainElementRef.current.style.left = tdPosition.left + 'px';
this.mainElementRef.current.style.top = tdPosition.top + 'px';
}
}
stopMousedownPropagation(e) {
e.stopPropagation();
}
render() {
return (
<NativeListener onMouseDown={this.stopMousedownPropagation}>
<div style={this.containerStyle} ref={this.mainElementRef} id="editorElement">
{this.state.reactEditor}
</div>
</NativeListener>
);
}
}
Note that this specific case is not working because opening the calendar on MUI-Pickers cancels Hot edition and makes the whole editor disappear. I have not found a work-around for that.