我一直在阅读Handsontable for Cell Editors的文档,但我似乎无法正确创建自定义单元格编辑器。
我正在引用Select2 for Handsontable并将此脚本添加到angular-cli中,但没有运气。任何人都知道如何使这项工作?
jsfiddle的代码是:
(function (Handsontable) {
"use strict";
var Select2Editor = Handsontable.editors.TextEditor.prototype.extend();
Select2Editor.prototype.prepare = function (row, col, prop, td, originalValue, cellProperties) {
Handsontable.editors.TextEditor.prototype.prepare.apply(this, arguments);
this.options = {};
if (this.cellProperties.select2Options) {
this.options = $.extend(this.options, cellProperties.select2Options);
}
};
Select2Editor.prototype.createElements = function () {
this.$body = $(document.body);
this.TEXTAREA = document.createElement('input');
this.TEXTAREA.setAttribute('type', 'text');
this.$textarea = $(this.TEXTAREA);
Handsontable.Dom.addClass(this.TEXTAREA, 'handsontableInput');
this.textareaStyle = this.TEXTAREA.style;
this.textareaStyle.width = 0;
this.textareaStyle.height = 0;
this.TEXTAREA_PARENT = document.createElement('DIV');
Handsontable.Dom.addClass(this.TEXTAREA_PARENT, 'handsontableInputHolder');
this.textareaParentStyle = this.TEXTAREA_PARENT.style;
this.textareaParentStyle.top = 0;
this.textareaParentStyle.left = 0;
this.textareaParentStyle.display = 'none';
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
this.instance.rootElement.appendChild(this.TEXTAREA_PARENT);
var that = this;
this.instance._registerTimeout(setTimeout(function () {
that.refreshDimensions();
}, 0));
};
var onSelect2Changed = function () {
this.close();
this.finishEditing();
};
var onSelect2Closed = function () {
this.close();
this.finishEditing();
};
var onBeforeKeyDown = function (event) {
var instance = this;
var that = instance.getActiveEditor();
var keyCodes = Handsontable.helper.keyCode;
var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; //catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
//Process only events that have been fired in the editor
if (!$(event.target).hasClass('select2-input') || event.isImmediatePropagationStopped()) {
return;
}
if (event.keyCode === 17 || event.keyCode === 224 || event.keyCode === 91 || event.keyCode === 93) {
//when CTRL or its equivalent is pressed and cell is edited, don't prepare selectable text in textarea
event.stopImmediatePropagation();
return;
}
var target = event.target;
switch (event.keyCode) {
case keyCodes.ARROW_RIGHT:
if (Handsontable.Dom.getCaretPosition(target) !== target.value.length) {
event.stopImmediatePropagation();
} else {
that.$textarea.select2('close');
}
break;
case keyCodes.ARROW_LEFT:
if (Handsontable.Dom.getCaretPosition(target) !== 0) {
event.stopImmediatePropagation();
} else {
that.$textarea.select2('close');
}
break;
case keyCodes.ENTER:
var selected = that.instance.getSelected();
var isMultipleSelection = !(selected[0] === selected[2] && selected[1] === selected[3]);
if ((ctrlDown && !isMultipleSelection) || event.altKey) { //if ctrl+enter or alt+enter, add new line
if (that.isOpened()) {
that.val(that.val() + '\n');
that.focus();
} else {
that.beginEditing(that.originalValue + '\n')
}
event.stopImmediatePropagation();
}
event.preventDefault(); //don't add newline to field
break;
case keyCodes.A:
case keyCodes.X:
case keyCodes.C:
case keyCodes.V:
if (ctrlDown) {
event.stopImmediatePropagation(); //CTRL+A, CTRL+C, CTRL+V, CTRL+X should only work locally when cell is edited (not in table context)
}
break;
case keyCodes.BACKSPACE:
case keyCodes.DELETE:
case keyCodes.HOME:
case keyCodes.END:
event.stopImmediatePropagation(); //backspace, delete, home, end should only work locally when cell is edited (not in table context)
break;
}
};
Select2Editor.prototype.open = function () {
this.refreshDimensions();
this.textareaParentStyle.display = 'block';
this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
this.$textarea.css({
height: $(this.TD).height() + 4,
'min-width': $(this.TD).outerWidth() - 4
});
//display the list
this.$textarea.show();
//make sure that list positions matches cell position
// this.$textarea.offset($(this.TD).offset());
var self = this;
this.$textarea.select2(this.options)
.on('change', onSelect2Changed.bind(this))
.on('select2-close', onSelect2Closed.bind(this));
self.$textarea.select2('open');
};
Select2Editor.prototype.init = function () {
Handsontable.editors.TextEditor.prototype.init.apply(this, arguments);
};
Select2Editor.prototype.close = function () {
this.instance.listen();
this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
this.$textarea.off();
this.$textarea.hide();
Handsontable.editors.TextEditor.prototype.close.apply(this, arguments);
};
Select2Editor.prototype.val = function (value) {
if (typeof value == 'undefined') {
return this.$textarea.val();
} else {
this.$textarea.val(value);
}
};
Select2Editor.prototype.focus = function () {
this.instance.listen();
// DO NOT CALL THE BASE TEXTEDITOR FOCUS METHOD HERE, IT CAN MAKE THIS EDITOR BEHAVE POORLY AND HAS NO PURPOSE WITHIN THE CONTEXT OF THIS EDITOR
//Handsontable.editors.TextEditor.prototype.focus.apply(this, arguments);
};
Select2Editor.prototype.beginEditing = function (initialValue) {
var onBeginEditing = this.instance.getSettings().onBeginEditing;
if (onBeginEditing && onBeginEditing() === false) {
return;
}
Handsontable.editors.TextEditor.prototype.beginEditing.apply(this, arguments);
};
Select2Editor.prototype.finishEditing = function (isCancelled, ctrlDown) {
this.instance.listen();
return Handsontable.editors.TextEditor.prototype.finishEditing.apply(this, arguments);
};
Handsontable.editors.Select2Editor = Select2Editor;
Handsontable.editors.registerEditor('select2', Select2Editor);
})(Handsontable);
我也在使用ng2-handsontable组件,我想知道这是否会导致更多问题?
答案 0 :(得分:0)
我能够让select2在大多数情况下工作。
import * as Handsontable from 'handsontable';
export const Select2Editor = Handsontable.editors.TextEditor.prototype.extend();
Select2Editor.prototype.prepare = function (row, col, prop, td, originalValue, cellProperties) {
Handsontable.editors.TextEditor.prototype.prepare.apply(this, arguments);
this.options = {};
if (this.cellProperties.select2Options) {
this.options = $.extend(this.options, cellProperties.select2Options);
}
};
Select2Editor.prototype.createElements = function () {
this.$body = $(document.body);
this.TEXTAREA = document.createElement('select');
this.$textarea = $(this.TEXTAREA);
Handsontable.Dom.addClass(this.TEXTAREA, 'handsontableInput');
this.textareaStyle = this.TEXTAREA.style;
this.textareaStyle.width = 0;
this.textareaStyle.height = 0;
this.TEXTAREA_PARENT = document.createElement('DIV');
Handsontable.Dom.addClass(this.TEXTAREA_PARENT, 'handsontableInputHolder');
this.textareaParentStyle = this.TEXTAREA_PARENT.style;
this.textareaParentStyle.top = 0;
this.textareaParentStyle.left = 0;
this.textareaParentStyle.display = 'none';
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
this.instance.rootElement.appendChild(this.TEXTAREA_PARENT);
var that = this;
this.instance._registerTimeout(setTimeout(function () {
that.refreshDimensions();
}, 0));
};
var onSelect2Changed = function (e) {
//console.log(e);
console.log(this.$textarea.val());
// this.close();
// this.finishEditing();
};
var onSelect2Closed = function () {
this.close();
this.finishEditing();
};
var onBeforeKeyDown = function (event) {
var instance = this;
var that = instance.getActiveEditor();
var keyCodes = (<any>Handsontable.helper).keyCode;
var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; //catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
//Process only events that have been fired in the editor
if (!$(event.target).hasClass('select2-input') || event.isImmediatePropagationStopped()) {
return;
}
if (event.keyCode === 17 || event.keyCode === 224 || event.keyCode === 91 || event.keyCode === 93) {
//when CTRL or its equivalent is pressed and cell is edited, don't prepare selectable text in textarea
event.stopImmediatePropagation();
return;
}
var target = event.target;
switch (event.keyCode) {
case keyCodes.ARROW_RIGHT:
if ((<any>Handsontable.Dom).getCaretPosition(target) !== target.value.length) {
event.stopImmediatePropagation();
} else {
that.$textarea.select2('close');
}
break;
case keyCodes.ARROW_LEFT:
if ((<any>Handsontable.Dom).getCaretPosition(target) !== 0) {
event.stopImmediatePropagation();
} else {
that.$textarea.select2('close');
}
break;
case keyCodes.ENTER:
var selected = that.instance.getSelected();
var isMultipleSelection = !(selected[0] === selected[2] && selected[1] === selected[3]);
if ((ctrlDown && !isMultipleSelection) || event.altKey) { //if ctrl+enter or alt+enter, add new line
if (that.isOpened()) {
that.val(that.val() + '\n');
that.focus();
} else {
that.beginEditing(that.originalValue + '\n')
}
event.stopImmediatePropagation();
}
event.preventDefault(); //don't add newline to field
break;
case keyCodes.A:
case keyCodes.X:
case keyCodes.C:
case keyCodes.V:
if (ctrlDown) {
event.stopImmediatePropagation(); //CTRL+A, CTRL+C, CTRL+V, CTRL+X should only work locally when cell is edited (not in table context)
}
break;
case keyCodes.BACKSPACE:
case keyCodes.DELETE:
case keyCodes.HOME:
case keyCodes.END:
event.stopImmediatePropagation(); //backspace, delete, home, end should only work locally when cell is edited (not in table context)
break;
}
};
Select2Editor.prototype.open = function () {
this.refreshDimensions();
this.textareaParentStyle.display = 'block';
this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
this.$textarea.css({
height: $(this.TD).height() + 4,
'min-width': $(this.TD).outerWidth() - 4
});
//display the list
this.$textarea.show();
//make sure that list positions matches cell position
// this.$textarea.offset($(this.TD).offset());
var self = this;
this.$textarea.select2(this.options)
.on('change', onSelect2Changed.bind(this))
.on('select2-close', onSelect2Closed.bind(this));
self.$textarea.select2('open');
};
Select2Editor.prototype.init = function () {
Handsontable.editors.TextEditor.prototype.init.apply(this, arguments);
};
Select2Editor.prototype.close = function () {
this.instance.listen();
this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
this.$textarea.off();
this.$textarea.hide();
Handsontable.editors.TextEditor.prototype.close.apply(this, arguments);
};
Select2Editor.prototype.val = function (value) {
if (typeof value == 'undefined') {
return this.$textarea.val();
} else {
this.$textarea.val(value);
}
};
Select2Editor.prototype.getValue = function() {
return this.$textarea.val();
};
Select2Editor.prototype.setValue = function(value) {
this.$textarea.val(value);
};
Select2Editor.prototype.focus = function () {
this.instance.listen();
// DO NOT CALL THE BASE TEXTEDITOR FOCUS METHOD HERE, IT CAN MAKE THIS EDITOR BEHAVE POORLY AND HAS NO PURPOSE WITHIN THE CONTEXT OF THIS EDITOR
//Handsontable.editors.TextEditor.prototype.focus.apply(this, arguments);
};
Select2Editor.prototype.beginEditing = function (initialValue) {
var onBeginEditing = this.instance.getSettings().onBeginEditing;
if (onBeginEditing && onBeginEditing() === false) {
return;
}
Handsontable.editors.TextEditor.prototype.beginEditing.apply(this, arguments);
};
Select2Editor.prototype.finishEditing = function (isCancelled, ctrlDown) {
this.instance.listen();
return Handsontable.editors.TextEditor.prototype.finishEditing.apply(this, arguments);
};
答案 1 :(得分:0)
我正在vue js的Handsontable表中实现select2编辑器解决方案,并出现错误
“未捕获的TypeError:无法读取t.Select2Editor.createElements处未定义的属性'addClass'”
经过一番努力,我可以通过对原始文件https://github.com/trebuchetty/Handsontable-select2-editor/blob/master/select2-editor.js的select2 plugin.js代码进行少量更改来解决问题。
解决方案:
更改
"Handsontable.Dom" to "Handsontable.dom" in select2 plugin.js
并且select2插件将起作用。