Merge pull request from ArthurHoaro/feature/tag-separators

This commit is contained in:
ArthurHoaro 2020-11-08 14:07:33 +01:00 committed by GitHub
commit d9d71b10c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 657 additions and 171 deletions
assets
default
vintage/js

View file

@ -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');

View file

@ -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 {

View file

@ -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;
});
})();