Tag list: use awesomplete for tag auto completion
This commit is contained in:
parent
aa4797ba36
commit
82e3bb5f06
3 changed files with 69 additions and 3 deletions
|
@ -1098,6 +1098,10 @@ form[name="linkform"].page-form {
|
|||
color: #7f7f7f;
|
||||
}
|
||||
|
||||
#taglist .rename-tag-form {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#taglist .delete-tag {
|
||||
color: #ac2925;
|
||||
display: none;
|
||||
|
|
|
@ -418,6 +418,9 @@ window.onload = function () {
|
|||
*
|
||||
* TODO: support error code in the backend for AJAX requests
|
||||
*/
|
||||
var existingTags = document.querySelector('input[name="taglist"]').value.split(' ');
|
||||
var awesomepletes = [];
|
||||
|
||||
// Display/Hide rename form
|
||||
var renameTagButtons = document.querySelectorAll('.rename-tag');
|
||||
[].forEach.call(renameTagButtons, function(rename) {
|
||||
|
@ -425,7 +428,12 @@ window.onload = function () {
|
|||
event.preventDefault();
|
||||
var block = findParent(event.target, 'div', {'class': 'tag-list-item'});
|
||||
var form = block.querySelector('.rename-tag-form');
|
||||
form.style.display = form.style.display == 'none' ? 'block' : 'none';
|
||||
if (form.style.display == 'none' || form.style.display == '') {
|
||||
form.style.display = 'block';
|
||||
} else {
|
||||
form.style.display = 'none';
|
||||
}
|
||||
block.querySelector('input').focus();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -454,10 +462,18 @@ window.onload = function () {
|
|||
block.setAttribute('data-tag', totag);
|
||||
input.setAttribute('name', totag);
|
||||
input.setAttribute('value', totag);
|
||||
input.parentNode.style.display = 'none';
|
||||
findParent(input, 'div', {'class': 'rename-tag-form'}).style.display = 'none';
|
||||
block.querySelector('a.tag-link').innerHTML = htmlEntities(totag);
|
||||
block.querySelector('a.tag-link').setAttribute('href', '?searchtags='+ encodeURIComponent(totag));
|
||||
block.querySelector('a.rename-tag').setAttribute('href', '?do=changetag&fromtag='+ encodeURIComponent(totag));
|
||||
|
||||
// Refresh awesomplete values
|
||||
for (var key in existingTags) {
|
||||
if (existingTags[key] == fromtag) {
|
||||
existingTags[key] = totag;
|
||||
}
|
||||
}
|
||||
awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes);
|
||||
}
|
||||
};
|
||||
xhr.send('renametag=1&fromtag='+ encodeURIComponent(fromtag) +'&totag='+ encodeURIComponent(totag) +'&token='+ token);
|
||||
|
@ -468,6 +484,7 @@ window.onload = function () {
|
|||
// Validate input with enter key
|
||||
var renameTagInputs = document.querySelectorAll('.rename-tag-input');
|
||||
[].forEach.call(renameTagInputs, function(rename) {
|
||||
|
||||
rename.addEventListener('keypress', function(event) {
|
||||
if (event.keyCode === 13) { // enter
|
||||
findParent(event.target, 'div', {'class': 'tag-list-item'}).querySelector('.validate-rename-tag').click();
|
||||
|
@ -497,8 +514,19 @@ window.onload = function () {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
updateAwesompleteList('.rename-tag-input', document.querySelector('input[name="taglist"]').value.split(' '), awesomepletes);
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a parent element according to its tag and its attributes
|
||||
*
|
||||
* @param element Element where to start the search
|
||||
* @param tagName Expected parent tag name
|
||||
* @param attributes Associative array of expected attributes (name=>value).
|
||||
*
|
||||
* @returns Found element or null.
|
||||
*/
|
||||
function findParent(element, tagName, attributes)
|
||||
{
|
||||
while (element) {
|
||||
|
@ -522,6 +550,9 @@ function findParent(element, tagName, attributes)
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax request to refresh the CSRF token.
|
||||
*/
|
||||
function refreshToken()
|
||||
{
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
@ -533,6 +564,33 @@ function refreshToken()
|
|||
xhr.send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update awesomplete list of tag for all elements matching the given selector
|
||||
*
|
||||
* @param selector CSS selector
|
||||
* @param tags Array of tags
|
||||
* @param instances List of existing awesomplete instances
|
||||
*/
|
||||
function updateAwesompleteList(selector, tags, instances)
|
||||
{
|
||||
// First load: create Awesomplete instances
|
||||
if (instances.length == 0) {
|
||||
var elements = document.querySelectorAll(selector);
|
||||
[].forEach.call(elements, function (element) {
|
||||
instances.push(new Awesomplete(
|
||||
element,
|
||||
{'list': tags}
|
||||
));
|
||||
});
|
||||
} else {
|
||||
// Update awesomplete tag list
|
||||
for (var key in instances) {
|
||||
instances[key].list = tags;
|
||||
}
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* html_entities in JS
|
||||
*
|
||||
|
|
|
@ -57,7 +57,7 @@ <h2 class="window-title">{'Tag list'|t} - {$countTags} {'tags'|t}</h2>
|
|||
{/loop}
|
||||
</div>
|
||||
{if="isLoggedIn()===true"}
|
||||
<div class="rename-tag-form pure-u-1" style="display:none;">
|
||||
<div class="rename-tag-form pure-u-1">
|
||||
<input type="text" name="{$key}" value="{$key}" class="rename-tag-input" />
|
||||
<a href="#" class="validate-rename-tag"><i class="fa fa-check"></i></a>
|
||||
</div>
|
||||
|
@ -74,6 +74,10 @@ <h2 class="window-title">{'Tag list'|t} - {$countTags} {'tags'|t}</h2>
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{if="isLoggedIn()===true"}
|
||||
<input type="hidden" name="taglist" value="{loop="$tags"}{$key} {/loop}"
|
||||
{/if}
|
||||
|
||||
{include="tag.sort"}
|
||||
|
||||
{include="page.footer"}
|
||||
|
|
Loading…
Reference in a new issue