Added tag siblings to frontend

This commit is contained in:
Marcin Kurczewski 2014-10-11 22:00:22 +02:00
parent 6015199559
commit 6ca08e5532
3 changed files with 120 additions and 36 deletions

1
TODO
View file

@ -28,7 +28,6 @@ everything related to tags:
- tag editing
- category (from config.ini)
- description
- related tags
- aliases
- take care of recursion
- listing

View file

@ -197,9 +197,31 @@ input[type=checkbox]:checked + label::before {
}
.tag-input li a {
color: black;
}
.tag-input li a.close {
font-size: 14px;
margin-left: 0.5em;
cursor: pointer;
margin-left: 0.75em;
}
.related-tags {
line-height: 200%;
font-size: 15px;
display: none;
margin: 0.5em 0.5em 1em 0.5em;
}
.related-tags span {
float: left;
}
.related-tags ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
}
.related-tags li {
display: inline-block;
margin: 0 0.5em;
padding: 0;
}
.autocomplete {

View file

@ -4,6 +4,8 @@ App.Controls = App.Controls || {};
App.Controls.TagInput = function($underlyingInput) {
var _ = App.DI.get('_');
var jQuery = App.DI.get('jQuery');
var promise = App.DI.get('promise');
var api = App.DI.get('api');
var KEY_RETURN = 13;
var KEY_SPACE = 32;
@ -18,6 +20,15 @@ App.Controls.TagInput = function($underlyingInput) {
inputConfirmed: null,
};
var $wrapper = jQuery('<div class="tag-input">');
var $tagList = jQuery('<ul class="tags">');
var $input = jQuery('<input class="tag-real-input" type="text"/>');
var $related = jQuery('<div class="related-tags"><span>Related tags:</span><ul>');
init();
render();
initAutocomplete();
function init() {
if ($underlyingInput.length === 0) {
throw new Error('Tag input element was not found');
}
@ -28,11 +39,10 @@ App.Controls.TagInput = function($underlyingInput) {
throw new Error('Tag input was already initialized for this element');
}
$underlyingInput.attr('data-tagged', true);
$underlyingInput.hide();
}
var $wrapper = jQuery('<div class="tag-input">');
var $tagList = jQuery('<ul class="tags">');
var $input = jQuery('<input class="tag-real-input" type="text"/>');
function render() {
$underlyingInput.hide();
$wrapper.append($tagList);
$wrapper.append($input);
$wrapper.insertAfter($underlyingInput);
@ -44,11 +54,11 @@ App.Controls.TagInput = function($underlyingInput) {
$input.focus();
});
$input.attr('placeholder', $underlyingInput.attr('placeholder'));
$related.insertAfter($wrapper);
addTagsFromText($underlyingInput.val());
$underlyingInput.val('');
initAutocomplete();
}
function initAutocomplete() {
var autocomplete = new App.Controls.AutoCompleteInput($input);
@ -131,14 +141,13 @@ App.Controls.TagInput = function($underlyingInput) {
return;
}
var oldTags = getTags();
if (_.contains(_.map(oldTags, function(tag) { return tag.toLowerCase(); }), tag.toLowerCase())) {
if (isTaggedWith(tag)) {
flashTag(tag);
} else {
if (typeof(options.beforeTagAdded) === 'function') {
options.beforeTagAdded(tag);
}
var newTags = oldTags.slice();
var newTags = getTags().slice();
newTags.push(tag);
setTags(newTags);
}
@ -155,6 +164,14 @@ App.Controls.TagInput = function($underlyingInput) {
}
}
function isTaggedWith(tag) {
var tags = getTags();
var tagNames = _.map(tags, function(tag) {
return tag.toLowerCase();
});
return _.contains(tagNames, tag.toLowerCase());
}
function removeLastTag() {
removeTag(_.last(getTags()));
}
@ -170,11 +187,18 @@ App.Controls.TagInput = function($underlyingInput) {
$underlyingInput.val(newTags.join(' '));
_.each(newTags, function(tag) {
var $elem = jQuery('<li/>');
$elem.text(tag);
$elem.attr('data-tag', tag.toLowerCase());
var $deleteButton = jQuery('<a><i class="fa fa-remove"></i></a>');
$deleteButton.bind('click', function(e) {
var $tagLink = jQuery('<a class="tag">');
$tagLink.text(tag);
$tagLink.click(function(e) {
e.preventDefault();
showRelatedTags(tag);
});
$elem.append($tagLink);
var $deleteButton = jQuery('<a class="close"><i class="fa fa-remove"></i></a>');
$deleteButton.click(function(e) {
e.preventDefault();
removeTag(tag);
$input.focus();
@ -185,6 +209,45 @@ App.Controls.TagInput = function($underlyingInput) {
});
}
function showRelatedTags(tag) {
if ($related.data('lastTag') === tag) {
$related.slideUp('fast');
$related.data('lastTag', null);
return;
}
$related.slideUp('fast', function() {
$related.data('lastTag', tag);
var $list = $related.find('ul');
promise.wait(api.get('/tags/' + tag + '/siblings'))
.then(function(response) {
$list.empty();
var relatedTags = response.json.data;
relatedTags = _.filter(relatedTags, function(tag) {
return !isTaggedWith(tag.name);
});
relatedTags = relatedTags.slice(0, 20);
_.each(relatedTags, function(tag) {
var $li = jQuery('<li>');
var $a = jQuery('<a href="#/posts/query=' + tag.name + '">');
$a.text(tag.name);
$a.click(function(e) {
e.preventDefault();
addTag(tag.name);
});
$li.append($a);
$list.append($li);
});
if (_.size(relatedTags)) {
$related.slideDown('fast');
}
}).fail(function() {
console.log(arguments);
});
});
}
function getTags() {
return tags;
}