2015-10-17 23:49:24 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var FieldViewText = require('./field-view-text');
|
|
|
|
|
|
|
|
var FieldViewTags = FieldViewText.extend({
|
|
|
|
renderValue: function(value) {
|
|
|
|
return value ? _.escape(value.join(', ')) : '';
|
|
|
|
},
|
|
|
|
|
|
|
|
getEditValue: function(value) {
|
|
|
|
return value ? value.join(', ') : '';
|
|
|
|
},
|
|
|
|
|
2015-10-18 17:43:16 +02:00
|
|
|
valueToTags: function(val) {
|
|
|
|
var allTags = {};
|
|
|
|
this.model.tags.forEach(function(tag) {
|
|
|
|
allTags[tag.toLowerCase()] = tag;
|
|
|
|
});
|
|
|
|
return _.unique(val.split(/\s*[;,:]\s*/).filter(_.identity).map(function (tag) {
|
|
|
|
return allTags[tag.toLowerCase()] || tag;
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
2015-10-17 23:49:24 +02:00
|
|
|
endEdit: function(newVal, extra) {
|
|
|
|
if (newVal !== undefined) {
|
2015-10-18 17:43:16 +02:00
|
|
|
newVal = this.valueToTags(newVal);
|
|
|
|
}
|
|
|
|
if (this.tagsAutocomplete) {
|
|
|
|
this.tagsAutocomplete.remove();
|
|
|
|
this.tagsAutocomplete = null;
|
2015-10-17 23:49:24 +02:00
|
|
|
}
|
|
|
|
FieldViewText.prototype.endEdit.call(this, newVal, extra);
|
2015-10-18 17:43:16 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
startEdit: function() {
|
|
|
|
FieldViewText.prototype.startEdit.call(this);
|
|
|
|
var fieldRect = this.input[0].getBoundingClientRect();
|
|
|
|
this.tagsAutocomplete = $('<div class="details__tags-autocomplete"></div>').appendTo('body');
|
|
|
|
this.tagsAutocomplete.css({
|
|
|
|
top: fieldRect.bottom,
|
|
|
|
left: fieldRect.left,
|
|
|
|
width: fieldRect.width - 2
|
|
|
|
});
|
|
|
|
this.tagsAutocomplete.mousedown(this.tagsAutocompleteClick.bind(this));
|
|
|
|
this.setTags();
|
|
|
|
},
|
|
|
|
|
|
|
|
fieldValueInput: function(e) {
|
|
|
|
e.stopPropagation();
|
|
|
|
this.setTags();
|
|
|
|
FieldViewText.prototype.fieldValueInput.call(this, e);
|
|
|
|
},
|
|
|
|
|
|
|
|
getAvailableTags: function() {
|
|
|
|
var tags = this.valueToTags(this.input.val());
|
2016-01-14 19:49:33 +01:00
|
|
|
var last = tags[tags.length - 1];
|
|
|
|
var isLastPart = last && this.model.tags.indexOf(last) < 0;
|
2015-10-18 17:43:16 +02:00
|
|
|
return this.model.tags.filter(function(tag) {
|
2016-01-14 19:49:33 +01:00
|
|
|
return tags.indexOf(tag) < 0 && (!isLastPart || tag.toLowerCase().indexOf(last.toLowerCase()) >= 0);
|
2015-10-18 17:43:16 +02:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
setTags: function() {
|
|
|
|
var availableTags = this.getAvailableTags();
|
|
|
|
var tagsHtml = availableTags.map(function(tag) {
|
|
|
|
return '<div class="details__tags-autocomplete-tag">' + _.escape(tag) + '</div>';
|
|
|
|
}).join('');
|
|
|
|
this.tagsAutocomplete.html(tagsHtml);
|
2016-02-14 15:09:57 +01:00
|
|
|
this.tagsAutocomplete.toggle(!!tagsHtml);
|
2015-10-18 17:43:16 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
tagsAutocompleteClick: function(e) {
|
|
|
|
e.stopPropagation();
|
|
|
|
if (e.target.classList.contains('details__tags-autocomplete-tag')) {
|
2016-01-16 13:35:34 +01:00
|
|
|
var selectedTag = $(e.target).text(), newVal = this.input.val();
|
|
|
|
if (newVal) {
|
|
|
|
var tags = this.valueToTags(newVal);
|
|
|
|
var last = tags[tags.length - 1];
|
|
|
|
var isLastPart = last && this.model.tags.indexOf(last) < 0;
|
|
|
|
if (isLastPart) {
|
|
|
|
newVal = newVal.substr(0, newVal.lastIndexOf(last)) + selectedTag;
|
|
|
|
} else {
|
|
|
|
newVal += ', ' + selectedTag;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
newVal = selectedTag;
|
|
|
|
}
|
|
|
|
this.input.val(newVal);
|
|
|
|
this.input.focus();
|
|
|
|
this.setTags();
|
2015-10-18 17:43:16 +02:00
|
|
|
}
|
2016-01-16 13:35:34 +01:00
|
|
|
this.afterPaint(function() { this.input.focus(); });
|
2015-10-17 23:49:24 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
module.exports = FieldViewTags;
|