keeweb/app/scripts/views/fields/field-view-tags.js

115 lines
3.5 KiB
JavaScript
Raw Normal View History

2019-09-15 14:16:32 +02:00
import { FieldViewText } from 'views/fields/field-view-text';
2019-09-18 07:08:23 +02:00
import { escape } from 'util/fn';
2020-05-09 17:00:39 +02:00
import tagsTemplate from 'templates/details/fields/tags.hbs';
2015-10-17 23:49:24 +02:00
2019-09-16 19:55:06 +02:00
class FieldViewTags extends FieldViewText {
hasOptions = false;
2019-08-18 10:17:09 +02:00
renderValue(value) {
2019-09-18 07:08:23 +02:00
return value ? escape(value.join(', ')) : '';
2019-09-16 19:55:06 +02:00
}
2015-10-17 23:49:24 +02:00
2019-08-18 10:17:09 +02:00
getEditValue(value) {
2015-10-17 23:49:24 +02:00
return value ? value.join(', ') : '';
2019-09-16 19:55:06 +02:00
}
2015-10-17 23:49:24 +02:00
2020-05-09 17:00:39 +02:00
getTextValue() {
return this.value ? this.value.join(', ') : '';
}
2019-08-18 10:17:09 +02:00
valueToTags(val) {
2017-01-31 07:50:28 +01:00
const allTags = {};
2020-06-01 16:53:51 +02:00
this.model.tags.forEach((tag) => {
2015-10-18 17:43:16 +02:00
allTags[tag.toLowerCase()] = tag;
});
2019-09-18 20:42:17 +02:00
const valueTags = {};
val.split(/\s*[;,:]\s*/)
2020-06-01 16:53:51 +02:00
.filter((tag) => tag)
.map((tag) => allTags[tag.toLowerCase()] || tag)
.forEach((tag) => {
2019-09-18 20:42:17 +02:00
valueTags[tag] = tag;
});
return Object.keys(valueTags);
2019-09-16 19:55:06 +02:00
}
2015-10-18 17:43:16 +02:00
2019-08-18 10:17:09 +02:00
endEdit(newVal, extra) {
2015-10-17 23:49:24 +02:00
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
}
2019-09-16 19:55:06 +02:00
super.endEdit(newVal, extra);
}
2015-10-18 17:43:16 +02:00
2019-08-18 10:17:09 +02:00
startEdit() {
2019-09-16 19:55:06 +02:00
super.startEdit();
2017-01-31 07:50:28 +01:00
const fieldRect = this.input[0].getBoundingClientRect();
const shadowSpread = parseInt(this.input.css('--focus-shadow-spread')) || 0;
2019-08-18 08:05:38 +02:00
this.tagsAutocomplete = $('<div class="details__field-autocomplete"></div>').appendTo(
'body'
);
2015-10-18 17:43:16 +02:00
this.tagsAutocomplete.css({
2019-09-08 11:32:31 +02:00
top: fieldRect.bottom + shadowSpread,
2015-10-18 17:43:16 +02:00
left: fieldRect.left,
width: fieldRect.width - 2
});
this.tagsAutocomplete.mousedown(this.tagsAutocompleteClick.bind(this));
this.setTags();
2019-09-16 19:55:06 +02:00
}
2015-10-18 17:43:16 +02:00
2019-08-18 10:17:09 +02:00
fieldValueInput(e) {
2015-10-18 17:43:16 +02:00
e.stopPropagation();
this.setTags();
2019-09-16 19:55:06 +02:00
super.fieldValueInput(e);
}
2015-10-18 17:43:16 +02:00
2019-08-18 10:17:09 +02:00
getAvailableTags() {
2017-01-31 07:50:28 +01:00
const tags = this.valueToTags(this.input.val());
const last = tags[tags.length - 1];
const isLastPart = last && this.model.tags.indexOf(last) < 0;
2020-06-01 16:53:51 +02:00
return this.model.tags.filter((tag) => {
2019-08-18 08:05:38 +02:00
return (
tags.indexOf(tag) < 0 &&
(!isLastPart || tag.toLowerCase().indexOf(last.toLowerCase()) >= 0)
);
2015-10-18 17:43:16 +02:00
});
2019-09-16 19:55:06 +02:00
}
2015-10-18 17:43:16 +02:00
2019-08-18 10:17:09 +02:00
setTags() {
2017-01-31 07:50:28 +01:00
const availableTags = this.getAvailableTags();
2020-05-09 17:00:39 +02:00
const tagsHtml = tagsTemplate({ tags: availableTags });
2015-10-18 17:43:16 +02:00
this.tagsAutocomplete.html(tagsHtml);
2016-02-14 15:09:57 +01:00
this.tagsAutocomplete.toggle(!!tagsHtml);
2019-09-16 19:55:06 +02:00
}
2015-10-18 17:43:16 +02:00
2019-08-18 10:17:09 +02:00
tagsAutocompleteClick(e) {
2015-10-18 17:43:16 +02:00
e.stopPropagation();
2016-02-28 12:16:05 +01:00
if (e.target.classList.contains('details__field-autocomplete-item')) {
2017-01-31 07:50:28 +01:00
const selectedTag = $(e.target).text();
let newVal = this.input.val();
2016-01-16 13:35:34 +01:00
if (newVal) {
2017-01-31 07:50:28 +01:00
const tags = this.valueToTags(newVal);
const last = tags[tags.length - 1];
const isLastPart = last && this.model.tags.indexOf(last) < 0;
2016-01-16 13:35:34 +01:00
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
}
2019-09-20 22:26:32 +02:00
this.afterPaint(() => {
2019-08-16 23:05:39 +02:00
this.input.focus();
});
2015-10-17 23:49:24 +02:00
}
2019-09-16 19:55:06 +02:00
}
2015-10-17 23:49:24 +02:00
2019-09-15 14:16:32 +02:00
export { FieldViewTags };