/// chosen plugin
(function(Handsontable) {
"use strict";
var ChosenEditor = Handsontable.editors.TextEditor.prototype.extend();
ChosenEditor.prototype.prepare = function(row, col, prop, td, originalValue, cellProperties) {
Handsontable.editors.TextEditor.prototype.prepare.apply(this, arguments);
this.options = {};
if (this.cellProperties.chosenOptions) {
this.options = $.extend(this.options, cellProperties.chosenOptions);
}
cellProperties.chosenOptions = $.extend({}, cellProperties.chosenOptions);
};
ChosenEditor.prototype.createElements = function() {
this.$body = $(document.body);
this.TEXTAREA = document.createElement('select');
//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.textareaParentStyle.width = "200px";
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 onChosenChanged = function() {
var options = this.cellProperties.chosenOptions;
if (!options.multiple) {
this.close();
this.finishEditing();
}
};
var onChosenClosed = function() {
var options = this.cellProperties.chosenOptions;
if (!options.multiple) {
this.close();
this.finishEditing();
} else {}
};
var onBeforeKeyDown = function(event) {
var instance = this;
var that = instance.getActiveEditor();
var keyCodes = Handsontable.helper.KEY_CODES;
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.tagName !== "INPUT") {
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.trigger("chosen:close");
}
break;
case keyCodes.ARROW_LEFT:
if (Handsontable.dom.getCaretPosition(target) !== 0) {
event.stopImmediatePropagation();
} else {
that.$textarea.trigger("chosen:close");
}
break;
case keyCodes.ENTER:
if (that.cellProperties.chosenOptions.multiple) {
event.stopImmediatePropagation();
event.preventDefault();
event.stopPropagation();
}
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:
var txt = $(that.TEXTAREA_PARENT).find("input").val();
$(that.TEXTAREA_PARENT).find("input").val(txt.substr(0, txt.length - 1)).trigger("keyup.chosen");
event.stopImmediatePropagation();
break;
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;
}
};
ChosenEditor.prototype.open = function(keyboardEvent) {
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.hide();
//make sure that list positions matches cell position
//this.$textarea.offset($(this.TD).offset());
var options = $.extend({}, this.options, {
width: "100%",
search_contains: true
});
if (options.multiple) {
this.$textarea.attr("multiple", true);
} else {
this.$textarea.attr("multiple", false);
}
this.$textarea.empty();
this.$textarea.append("");
var el = null;
var originalValue = (this.originalValue + "").split(",");
if (options.data && options.data.length) {
for (var i = 0; i < options.data.length; i++) {
this.$textarea.append(el);
if (options[i].content && options[i].content.length) {
for (let k = 0; k < options[i].content.length; k++) {
if (options[i].content[k] && options[i].content[k].length) {
for (let j = 0; j < options[i].content[k].length; j++) {
el = $("");
el.attr("value", options[i].content[k].content[j].code);
el.html(options[i].content[k].content[j].name);
if (originalValue.indexOf(options[i].content[k].content[j].code + "") > -1) {
el.attr("selected", true);
}
}
} else {
el = $("");
el.attr("value", options[i].content[k].code);
el.html(options[i].content[k].name);
if (originalValue.indexOf(options[i].content[k].code + "") > -1) {
el.attr("selected", true);
}
}
}
} else {
el = $("");
el.attr("value", options[i].content[k].code);
el.html(options[i].content[k].name);
if (originalValue.indexOf(options[i].content[k].code + "") > -1) {
el.attr("selected", true);
}
}
}
}
}
if ($(this.TEXTAREA_PARENT).find(".chosen-container").length) {
this.$textarea.chosen("destroy");
}
this.$textarea.chosen(options);
var self = this;
setTimeout(function() {
self.$textarea.on('change', onChosenChanged.bind(self));
self.$textarea.on('chosen:hiding_dropdown', onChosenClosed.bind(self));
self.$textarea.trigger("chosen:open");
$(self.TEXTAREA_PARENT).find("input").on("keydown", function(e) {
if (e.keyCode === Handsontable.helper.KEY_CODES.ENTER /*|| e.keyCode === Handsontable.helper.KEY_CODES.BACKSPACE*/ ) {
if ($(this).val()) {
e.preventDefault();
e.stopPropagation();
} else {
e.preventDefault();
e.stopPropagation();
self.close();
self.finishEditing();
}
}
if (e.keyCode === Handsontable.helper.KEY_CODES.BACKSPACE) {
var txt = $(self.TEXTAREA_PARENT).find("input").val();
$(self.TEXTAREA_PARENT).find("input").val(txt.substr(0, txt.length - 1)).trigger("keyup.chosen");
e.preventDefault();
e.stopPropagation();
}
if (e.keyCode === Handsontable.helper.KEY_CODES.ARROW_DOWN || e.keyCode === Handsontable.helper.KEY_CODES.ARROW_UP) {
e.preventDefault();
e.stopPropagation();
}
});
setTimeout(function() {
self.$textarea.trigger("chosen:activate").focus();
if (keyboardEvent && keyboardEvent.keyCode && keyboardEvent.keyCode != 113) {
var key = keyboardEvent.keyCode;
var keyText = (String.fromCharCode((96 <= key && key <= 105) ? key - 48 : key)).toLowerCase();
$(self.TEXTAREA_PARENT).find("input").val(keyText).trigger("keyup.chosen");
self.$textarea.trigger("chosen:activate");
}
}, 1);
}, 1);
};
ChosenEditor.prototype.init = function() {
Handsontable.editors.TextEditor.prototype.init.apply(this, arguments);
};
ChosenEditor.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);
};
ChosenEditor.prototype.getValue = function() {
if (!this.$textarea.val()) {
return "";
}
if (typeof this.$textarea.val() === "object") {
return this.$textarea.val().join(",");
}
return this.$textarea.val();
};
ChosenEditor.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);
};
ChosenEditor.prototype.beginEditing = function(initialValue) {
var onBeginEditing = this.instance.getSettings().onBeginEditing;
if (onBeginEditing && onBeginEditing() === false) {
return;
}
Handsontable.editors.TextEditor.prototype.beginEditing.apply(this, arguments);
};
ChosenEditor.prototype.finishEditing = function(isCancelled, ctrlDown) {
this.instance.listen();
return Handsontable.editors.TextEditor.prototype.finishEditing.apply(this, arguments);
};
Handsontable.editors.ChosenEditor = ChosenEditor; Handsontable.editors.registerEditor('chosen', ChosenEditor);
})(Handsontable);