144 lines
3.5 KiB
JavaScript
144 lines
3.5 KiB
JavaScript
/*!
|
|
* Tag Selector plugin for jQuery: Facilitates selecting multiple tags by extending jQuery UI Autocomplete.
|
|
* License: MIT
|
|
* https://petprojects.googlecode.com/svn/trunk/MIT-LICENSE.txt
|
|
*/
|
|
(function($) {
|
|
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>`;
|
|
}
|
|
}
|
|
|
|
function hide_error(input) {
|
|
const err = input.parent().parent().find(".invalid-remaining");
|
|
err.hide();
|
|
}
|
|
|
|
function show_error(input, msg) {
|
|
const err = input.parent().parent().find(".invalid-remaining");
|
|
err.text(msg);
|
|
err.show();
|
|
}
|
|
|
|
$.fn.selectSelector = function(source, select) {
|
|
return this.each(function() {
|
|
const selector = $(this),
|
|
input = $('input[type=text]', this);
|
|
|
|
const lookup = {};
|
|
for (let i = 0; i < source.length; i++) {
|
|
lookup[source[i].id] = source[i];
|
|
}
|
|
|
|
selector.click(() => input.focus())
|
|
.delegate('.badge a', 'click', function() {
|
|
const id = $(this).parent().data("id");
|
|
select.find("option[value=" + id + "]").attr("selected", false)
|
|
recreate();
|
|
});
|
|
|
|
function addTag(item) {
|
|
const id = item.id;
|
|
|
|
let text = item.text;
|
|
const idx = text.indexOf(':');
|
|
if (idx > 0) {
|
|
text = text.substr(0, idx);
|
|
}
|
|
|
|
$('<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);
|
|
}
|
|
|
|
function recreate() {
|
|
selector.find("span").remove();
|
|
select.find("option").each(function() {
|
|
if (this.hasAttribute("selected")) {
|
|
addTag(lookup[this.getAttribute("value")]);
|
|
}
|
|
});
|
|
}
|
|
recreate();
|
|
|
|
input.focusout(function() {
|
|
const value = input.val().trim();
|
|
if (value !== "") {
|
|
show_error(input, "Please select an existing tag, it's not possible to add custom ones.");
|
|
}
|
|
})
|
|
|
|
input.keydown(function(e) {
|
|
if (e.keyCode === $.ui.keyCode.TAB && $(this).data('ui-autocomplete').menu.active) {
|
|
e.preventDefault();
|
|
}
|
|
}).autocomplete({
|
|
minLength: 0,
|
|
source: source,
|
|
select: function(event, ui) {
|
|
addTag(ui.item);
|
|
input.val("");
|
|
return false;
|
|
}
|
|
}).focus(function() {
|
|
$(this).data("ui-autocomplete").search($(this).val());
|
|
});
|
|
|
|
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()
|
|
));
|
|
};
|
|
});
|
|
}
|
|
|
|
$(function() {
|
|
$(".multichoice_selector").each(function() {
|
|
const ele = $(this);
|
|
const sel = ele.parent().find("select");
|
|
sel.hide();
|
|
|
|
const options = [];
|
|
sel.find("option").each(function() {
|
|
const text = $(this).text();
|
|
const option = {
|
|
id: $(this).attr("value"),
|
|
text: text,
|
|
selected: !!$(this).attr("selected"),
|
|
toString: function() { return make_bold(text); },
|
|
};
|
|
|
|
const idx = text.indexOf(":");
|
|
if (idx > 0) {
|
|
option.title = text.substring(0, idx);
|
|
option.description = text.substring(idx + 1);
|
|
} else {
|
|
option.title = text
|
|
}
|
|
|
|
options.push(option);
|
|
});
|
|
|
|
ele.selectSelector(options, sel);
|
|
});
|
|
});
|
|
})(jQuery);
|