mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 09:35:49 +02:00
93 lines
4 KiB
JavaScript
93 lines
4 KiB
JavaScript
|
/**
|
||
|
* click_to_edit plugin for Tomselect
|
||
|
*
|
||
|
* This plugin allows editing (and selecting text in) any selected item by clicking it.
|
||
|
*
|
||
|
* Usually, when the user typed some text and created an item in Tomselect that item cannot be edited anymore. To make
|
||
|
* a change, the item has to be deleted and retyped completely. There is also generally no way to copy text out of a
|
||
|
* tomselect item. The "restore_on_backspace" plugin improves that somewhat, by allowing the user to edit an item after
|
||
|
* pressing backspace. However, it is somewhat confusing to first have to focus the field an then hit backspace in order
|
||
|
* to copy a piece of text. It may also not be immediately obvious for editing.
|
||
|
* This plugin transforms an item into editable text when it is clicked, e.g. when the user tries to place the caret
|
||
|
* within an item or when they try to drag across the text to highlight it.
|
||
|
* It also plays nice with the remove_button plugin which still removes (deselects) an option entirely.
|
||
|
*
|
||
|
* It is recommended to also enable the autoselect_typed plugin when using this plugin. Without it, the text in the
|
||
|
* input field (i.e. the item that was just clicked) is lost when the user clicks outside the field. Also, when the user
|
||
|
* clicks an option (making it text) and then tries to enter another one by entering the delimiter (e.g. space) nothing
|
||
|
* happens until enter is pressed or the text is changed from what it was.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Return a dom element from either a dom query string, jQuery object, a dom element or html string
|
||
|
* https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
|
||
|
*
|
||
|
* param query should be {}
|
||
|
*/
|
||
|
const getDom = query => {
|
||
|
if (query.jquery) {
|
||
|
return query[0];
|
||
|
}
|
||
|
if (query instanceof HTMLElement) {
|
||
|
return query;
|
||
|
}
|
||
|
if (isHtmlString(query)) {
|
||
|
var tpl = document.createElement('template');
|
||
|
tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
|
||
|
return tpl.content.firstChild;
|
||
|
}
|
||
|
return document.querySelector(query);
|
||
|
};
|
||
|
const isHtmlString = arg => {
|
||
|
if (typeof arg === 'string' && arg.indexOf('<') > -1) {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
function plugin(plugin_options_) {
|
||
|
const self = this
|
||
|
|
||
|
const plugin_options = Object.assign({
|
||
|
//If there is unsubmitted text in the input field, should that text be automatically used to select a matching
|
||
|
//element? If this is off, clicking on item1 and then clicking on item2 will result in item1 being deselected
|
||
|
auto_select_before_edit: true,
|
||
|
//If there is unsubmitted text in the input field, should that text be automatically used to create a matching
|
||
|
//element if no matching element was found or auto_select_before_edit is off?
|
||
|
auto_create_before_edit: true,
|
||
|
//customize this function to change which text the item is replaced with when clicking on it
|
||
|
text: option => {
|
||
|
return option[self.settings.labelField];
|
||
|
}
|
||
|
}, plugin_options_);
|
||
|
|
||
|
|
||
|
self.hook('after', 'setupTemplates', () => {
|
||
|
const orig_render_item = self.settings.render.item;
|
||
|
self.settings.render.item = (data, escape) => {
|
||
|
const item = getDom(orig_render_item.call(self, data, escape));
|
||
|
|
||
|
item.addEventListener('click', evt => {
|
||
|
if (self.isLocked) {
|
||
|
return;
|
||
|
}
|
||
|
const val = self.inputValue();
|
||
|
|
||
|
if (self.options[val]) {
|
||
|
self.addItem(val)
|
||
|
} else if (self.settings.create) {
|
||
|
self.createItem();
|
||
|
}
|
||
|
const option = self.options[item.dataset.value]
|
||
|
self.setTextboxValue(plugin_options.text.call(self, option));
|
||
|
self.focus();
|
||
|
self.removeItem(item);
|
||
|
}
|
||
|
);
|
||
|
|
||
|
return item;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
}
|
||
|
export { plugin as default };
|