Merge pull request #1621 from ArthurHoaro/feature/tag-separators
This commit is contained in:
commit
d9d71b10c3
44 changed files with 657 additions and 171 deletions
assets
|
@ -42,19 +42,21 @@ function refreshToken(basePath, callback) {
|
|||
xhr.send();
|
||||
}
|
||||
|
||||
function createAwesompleteInstance(element, tags = []) {
|
||||
function createAwesompleteInstance(element, separator, tags = []) {
|
||||
const awesome = new Awesomplete(Awesomplete.$(element));
|
||||
// Tags are separated by a space
|
||||
awesome.filter = (text, input) => Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]);
|
||||
|
||||
// Tags are separated by separator
|
||||
awesome.filter = (text, input) => Awesomplete.FILTER_CONTAINS(text, input.match(new RegExp(`[^${separator}]*$`))[0]);
|
||||
// Insert new selected tag in the input
|
||||
awesome.replace = (text) => {
|
||||
const before = awesome.input.value.match(/^.+ \s*|/)[0];
|
||||
awesome.input.value = `${before}${text} `;
|
||||
const before = awesome.input.value.match(new RegExp(`^.+${separator}+|`))[0];
|
||||
awesome.input.value = `${before}${text}${separator}`;
|
||||
};
|
||||
// Highlight found items
|
||||
awesome.item = (text, input) => Awesomplete.ITEM(text, input.match(/[^ ]*$/)[0]);
|
||||
awesome.item = (text, input) => Awesomplete.ITEM(text, input.match(new RegExp(`[^${separator}]*$`))[0]);
|
||||
// Don't display already selected items
|
||||
const reg = /(\w+) /g;
|
||||
// WARNING: pseudo classes does not seem to work with string litterals...
|
||||
const reg = new RegExp(`([^${separator}]+)${separator}`, 'g');
|
||||
let match;
|
||||
awesome.data = (item, input) => {
|
||||
while ((match = reg.exec(input))) {
|
||||
|
@ -78,13 +80,14 @@ function createAwesompleteInstance(element, tags = []) {
|
|||
* @param selector CSS selector
|
||||
* @param tags Array of tags
|
||||
* @param instances List of existing awesomplete instances
|
||||
* @param separator Tags separator character
|
||||
*/
|
||||
function updateAwesompleteList(selector, tags, instances) {
|
||||
function updateAwesompleteList(selector, tags, instances, separator) {
|
||||
if (instances.length === 0) {
|
||||
// First load: create Awesomplete instances
|
||||
const elements = document.querySelectorAll(selector);
|
||||
[...elements].forEach((element) => {
|
||||
instances.push(createAwesompleteInstance(element, tags));
|
||||
instances.push(createAwesompleteInstance(element, separator, tags));
|
||||
});
|
||||
} else {
|
||||
// Update awesomplete tag list
|
||||
|
@ -214,6 +217,8 @@ function init(description) {
|
|||
|
||||
(() => {
|
||||
const basePath = document.querySelector('input[name="js_base_path"]').value;
|
||||
const tagsSeparatorElement = document.querySelector('input[name="tags_separator"]');
|
||||
const tagsSeparator = tagsSeparatorElement ? tagsSeparatorElement.value || ' ' : ' ';
|
||||
|
||||
/**
|
||||
* Handle responsive menu.
|
||||
|
@ -575,7 +580,7 @@ function init(description) {
|
|||
|
||||
// Refresh awesomplete values
|
||||
existingTags = existingTags.map((tag) => (tag === fromtag ? totag : tag));
|
||||
awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes);
|
||||
awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes, tagsSeparator);
|
||||
}
|
||||
};
|
||||
xhr.send(`renametag=1&fromtag=${fromtagUrl}&totag=${encodeURIComponent(totag)}&token=${refreshedToken}`);
|
||||
|
@ -615,14 +620,14 @@ function init(description) {
|
|||
refreshToken(basePath);
|
||||
|
||||
existingTags = existingTags.filter((tagItem) => tagItem !== tag);
|
||||
awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes);
|
||||
awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes, tagsSeparator);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const autocompleteFields = document.querySelectorAll('input[data-multiple]');
|
||||
[...autocompleteFields].forEach((autocompleteField) => {
|
||||
awesomepletes.push(createAwesompleteInstance(autocompleteField));
|
||||
awesomepletes.push(createAwesompleteInstance(autocompleteField, tagsSeparator));
|
||||
});
|
||||
|
||||
const exportForm = document.querySelector('#exportform');
|
||||
|
|
|
@ -139,6 +139,16 @@ body,
|
|||
}
|
||||
}
|
||||
|
||||
.page-form,
|
||||
.pure-alert {
|
||||
code {
|
||||
display: inline-block;
|
||||
padding: 0 2px;
|
||||
color: $dark-grey;
|
||||
background-color: var(--background-color);
|
||||
}
|
||||
}
|
||||
|
||||
// Make pure-extras alert closable.
|
||||
.pure-alert-closable {
|
||||
.fa-times {
|
||||
|
|
|
@ -2,29 +2,38 @@ import Awesomplete from 'awesomplete';
|
|||
import 'awesomplete/awesomplete.css';
|
||||
|
||||
(() => {
|
||||
const awp = Awesomplete.$;
|
||||
const autocompleteFields = document.querySelectorAll('input[data-multiple]');
|
||||
[...autocompleteFields].forEach((autocompleteField) => {
|
||||
const awesomplete = new Awesomplete(awp(autocompleteField));
|
||||
awesomplete.filter = (text, input) => Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]);
|
||||
awesomplete.replace = (text) => {
|
||||
const before = awesomplete.input.value.match(/^.+ \s*|/)[0];
|
||||
awesomplete.input.value = `${before}${text} `;
|
||||
};
|
||||
awesomplete.minChars = 1;
|
||||
const tagsSeparatorElement = document.querySelector('input[name="tags_separator"]');
|
||||
const tagsSeparator = tagsSeparatorElement ? tagsSeparatorElement.value || ' ' : ' ';
|
||||
|
||||
autocompleteField.addEventListener('input', () => {
|
||||
const proposedTags = autocompleteField.getAttribute('data-list').replace(/,/g, '').split(' ');
|
||||
const reg = /(\w+) /g;
|
||||
let match;
|
||||
while ((match = reg.exec(autocompleteField.value)) !== null) {
|
||||
const id = proposedTags.indexOf(match[1]);
|
||||
if (id !== -1) {
|
||||
proposedTags.splice(id, 1);
|
||||
[...autocompleteFields].forEach((autocompleteField) => {
|
||||
const awesome = new Awesomplete(Awesomplete.$(autocompleteField));
|
||||
|
||||
// Tags are separated by separator
|
||||
awesome.filter = (text, input) => Awesomplete.FILTER_CONTAINS(
|
||||
text,
|
||||
input.match(new RegExp(`[^${tagsSeparator}]*$`))[0],
|
||||
);
|
||||
// Insert new selected tag in the input
|
||||
awesome.replace = (text) => {
|
||||
const before = awesome.input.value.match(new RegExp(`^.+${tagsSeparator}+|`))[0];
|
||||
awesome.input.value = `${before}${text}${tagsSeparator}`;
|
||||
};
|
||||
// Highlight found items
|
||||
awesome.item = (text, input) => Awesomplete.ITEM(text, input.match(new RegExp(`[^${tagsSeparator}]*$`))[0]);
|
||||
|
||||
// Don't display already selected items
|
||||
// WARNING: pseudo classes does not seem to work with string litterals...
|
||||
const reg = new RegExp(`([^${tagsSeparator}]+)${tagsSeparator}`, 'g');
|
||||
let match;
|
||||
awesome.data = (item, input) => {
|
||||
while ((match = reg.exec(input))) {
|
||||
if (item === match[1]) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
awesomplete.list = proposedTags;
|
||||
});
|
||||
return item;
|
||||
};
|
||||
awesome.minChars = 1;
|
||||
});
|
||||
})();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue