contentdb/app/public/static/tagselector.js

144 lines
3.5 KiB
JavaScript
Raw Normal View History

/*!
* Tag Selector plugin for jQuery: Facilitates selecting multiple tags by extending jQuery UI Autocomplete.
2021-02-05 17:19:34 +01:00
* License: MIT
* https://petprojects.googlecode.com/svn/trunk/MIT-LICENSE.txt
*/
(function($) {
2021-02-05 15:19:29 +01:00
function make_bold(text) {
const idx = text.indexOf(":");
if (idx > 0) {
return `<b>${text.substring(0, idx)}</b><span class="text-muted">: ${text.substring(idx + 1)}`;
} else {
return `<b>${text}</b>`;
}
}
2018-12-22 12:23:58 +01:00
function hide_error(input) {
2020-12-04 03:34:08 +01:00
const err = input.parent().parent().find(".invalid-remaining");
2018-12-22 12:23:58 +01:00
err.hide();
}
function show_error(input, msg) {
2020-12-04 03:34:08 +01:00
const err = input.parent().parent().find(".invalid-remaining");
2018-12-22 12:23:58 +01:00
err.text(msg);
err.show();
}
$.fn.selectSelector = function(source, select) {
return this.each(function() {
2020-12-04 03:34:08 +01:00
const selector = $(this),
2020-07-14 04:49:30 +02:00
input = $('input[type=text]', this);
2021-02-05 17:19:34 +01:00
const lookup = {};
for (let i = 0; i < source.length; i++) {
lookup[source[i].id] = source[i];
}
selector.click(() => input.focus())
2020-07-14 04:49:30 +02:00
.delegate('.badge a', 'click', function() {
2020-12-04 03:34:08 +01:00
const id = $(this).parent().data("id");
2020-07-14 04:49:30 +02:00
select.find("option[value=" + id + "]").attr("selected", false)
recreate();
});
2021-02-05 17:19:34 +01:00
function addTag(item) {
const id = item.id;
let text = item.text;
const idx = text.indexOf(':');
if (idx > 0) {
text = text.substr(0, idx);
}
2020-07-14 04:49:30 +02:00
$('<span class="badge badge-pill badge-primary"/>')
.text(text + ' ')
.data("id", id)
.append('<a>x</a>')
.insertBefore(input);
input.attr("placeholder", null);
select.find("option[value='" + id + "']").attr("selected", "selected")
hide_error(input);
}
2020-07-14 04:49:30 +02:00
function recreate() {
selector.find("span").remove();
select.find("option").each(function() {
if (this.hasAttribute("selected")) {
2021-02-05 17:19:34 +01:00
addTag(lookup[this.getAttribute("value")]);
2020-07-14 04:49:30 +02:00
}
});
}
recreate();
2020-12-04 03:34:08 +01:00
input.focusout(function() {
const value = input.val().trim();
2021-02-05 17:19:34 +01:00
if (value !== "") {
show_error(input, "Please select an existing tag, it's not possible to add custom ones.");
}
2020-07-14 04:49:30 +02:00
})
2020-07-14 04:49:30 +02:00
input.keydown(function(e) {
2021-02-05 17:19:34 +01:00
if (e.keyCode === $.ui.keyCode.TAB && $(this).data('ui-autocomplete').menu.active) {
e.preventDefault();
2018-05-27 22:31:11 +02:00
}
2021-02-05 17:19:34 +01:00
}).autocomplete({
minLength: 0,
source: source,
select: function(event, ui) {
addTag(ui.item);
input.val("");
return false;
2018-05-27 21:15:35 +02:00
}
2021-02-05 17:19:34 +01:00
}).focus(function() {
$(this).data("ui-autocomplete").search($(this).val());
2018-05-27 21:15:35 +02:00
});
2021-02-05 17:19:34 +01:00
input.data('ui-autocomplete')._renderItem = function(ul, item) {
return $('<li/>')
.data('item.autocomplete', item)
.append($('<a/>').html(item.toString()))
.appendTo(ul);
};
input.data('ui-autocomplete')._resizeMenu = function() {
const ul = this.menu.element;
ul.outerWidth(Math.max(
ul.width('').outerWidth(),
selector.outerWidth()
));
};
});
2018-05-27 21:15:35 +02:00
}
$(function() {
$(".multichoice_selector").each(function() {
2020-12-04 03:34:08 +01:00
const ele = $(this);
const sel = ele.parent().find("select");
2018-05-27 21:15:35 +02:00
sel.hide();
2020-12-04 03:34:08 +01:00
const options = [];
sel.find("option").each(function() {
2020-12-04 03:34:08 +01:00
const text = $(this).text();
2021-02-05 17:19:34 +01:00
const option = {
id: $(this).attr("value"),
2021-02-05 17:19:34 +01:00
text: text,
2020-12-04 03:34:08 +01:00
selected: !!$(this).attr("selected"),
2021-02-05 15:19:29 +01:00
toString: function() { return make_bold(text); },
2021-02-05 17:19:34 +01:00
};
2021-02-05 17:19:34 +01:00
const idx = text.indexOf(":");
if (idx > 0) {
option.title = text.substring(0, idx);
option.description = text.substring(idx + 1);
} else {
option.title = text
}
2018-05-27 21:15:35 +02:00
2021-02-05 17:19:34 +01:00
options.push(option);
});
2018-05-27 22:31:11 +02:00
2021-02-05 17:19:34 +01:00
ele.selectSelector(options, sel);
2018-05-27 22:31:11 +02:00
});
});
})(jQuery);