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;
|
color: #7f7f7f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#taglist .rename-tag-form {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#taglist .delete-tag {
|
#taglist .delete-tag {
|
||||||
color: #ac2925;
|
color: #ac2925;
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -418,6 +418,9 @@ window.onload = function () {
|
||||||
*
|
*
|
||||||
* TODO: support error code in the backend for AJAX requests
|
* 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
|
// Display/Hide rename form
|
||||||
var renameTagButtons = document.querySelectorAll('.rename-tag');
|
var renameTagButtons = document.querySelectorAll('.rename-tag');
|
||||||
[].forEach.call(renameTagButtons, function(rename) {
|
[].forEach.call(renameTagButtons, function(rename) {
|
||||||
|
@ -425,7 +428,12 @@ window.onload = function () {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var block = findParent(event.target, 'div', {'class': 'tag-list-item'});
|
var block = findParent(event.target, 'div', {'class': 'tag-list-item'});
|
||||||
var form = block.querySelector('.rename-tag-form');
|
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);
|
block.setAttribute('data-tag', totag);
|
||||||
input.setAttribute('name', totag);
|
input.setAttribute('name', totag);
|
||||||
input.setAttribute('value', 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').innerHTML = htmlEntities(totag);
|
||||||
block.querySelector('a.tag-link').setAttribute('href', '?searchtags='+ encodeURIComponent(totag));
|
block.querySelector('a.tag-link').setAttribute('href', '?searchtags='+ encodeURIComponent(totag));
|
||||||
block.querySelector('a.rename-tag').setAttribute('href', '?do=changetag&fromtag='+ 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);
|
xhr.send('renametag=1&fromtag='+ encodeURIComponent(fromtag) +'&totag='+ encodeURIComponent(totag) +'&token='+ token);
|
||||||
|
@ -468,6 +484,7 @@ window.onload = function () {
|
||||||
// Validate input with enter key
|
// Validate input with enter key
|
||||||
var renameTagInputs = document.querySelectorAll('.rename-tag-input');
|
var renameTagInputs = document.querySelectorAll('.rename-tag-input');
|
||||||
[].forEach.call(renameTagInputs, function(rename) {
|
[].forEach.call(renameTagInputs, function(rename) {
|
||||||
|
|
||||||
rename.addEventListener('keypress', function(event) {
|
rename.addEventListener('keypress', function(event) {
|
||||||
if (event.keyCode === 13) { // enter
|
if (event.keyCode === 13) { // enter
|
||||||
findParent(event.target, 'div', {'class': 'tag-list-item'}).querySelector('.validate-rename-tag').click();
|
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)
|
function findParent(element, tagName, attributes)
|
||||||
{
|
{
|
||||||
while (element) {
|
while (element) {
|
||||||
|
@ -522,6 +550,9 @@ function findParent(element, tagName, attributes)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajax request to refresh the CSRF token.
|
||||||
|
*/
|
||||||
function refreshToken()
|
function refreshToken()
|
||||||
{
|
{
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
|
@ -533,6 +564,33 @@ function refreshToken()
|
||||||
xhr.send();
|
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
|
* html_entities in JS
|
||||||
*
|
*
|
||||||
|
|
|
@ -57,7 +57,7 @@ <h2 class="window-title">{'Tag list'|t} - {$countTags} {'tags'|t}</h2>
|
||||||
{/loop}
|
{/loop}
|
||||||
</div>
|
</div>
|
||||||
{if="isLoggedIn()===true"}
|
{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" />
|
<input type="text" name="{$key}" value="{$key}" class="rename-tag-input" />
|
||||||
<a href="#" class="validate-rename-tag"><i class="fa fa-check"></i></a>
|
<a href="#" class="validate-rename-tag"><i class="fa fa-check"></i></a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -74,6 +74,10 @@ <h2 class="window-title">{'Tag list'|t} - {$countTags} {'tags'|t}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{if="isLoggedIn()===true"}
|
||||||
|
<input type="hidden" name="taglist" value="{loop="$tags"}{$key} {/loop}"
|
||||||
|
{/if}
|
||||||
|
|
||||||
{include="tag.sort"}
|
{include="tag.sort"}
|
||||||
|
|
||||||
{include="page.footer"}
|
{include="page.footer"}
|
||||||
|
|
Loading…
Reference in a new issue