/*! * 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 `${text.substring(0, idx)}: ${text.substring(idx + 1)}`; } else { return `${text}`; } } 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); } $('') .text(text + ' ') .data("id", id) .append('x') .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 $('
  • ') .data('item.autocomplete', item) .append($('').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);