2 * Tag Selector plugin for jQuery: Facilitates selecting multiple tags by extending jQuery UI Autocomplete.
3 * You may use Tag Selector under the terms of either the MIT License or the GNU General Public License (GPL) Version 2.
4 * https://petprojects.googlecode.com/svn/trunk/MIT-LICENSE.txt
5 * https://petprojects.googlecode.com/svn/trunk/GPL-LICENSE.txt
8 function hide_error(input) {
9 var err = input.parent().parent().find(".invalid-remaining");
13 function show_error(input, msg) {
14 var err = input.parent().parent().find(".invalid-remaining");
15 console.log(err.length);
20 $.fn.selectSelector = function(source, select) {
21 return this.each(function() {
22 var selector = $(this),
23 input = $('input[type=text]', this);
25 selector.click(function() { input.focus(); })
26 .delegate('.badge a', 'click', function() {
27 var id = $(this).parent().data("id");
28 select.find("option[value=" + id + "]").attr("selected", false)
32 function addTag(id, text) {
33 $('<span class="badge badge-pill badge-primary"/>')
38 input.attr("placeholder", null);
39 select.find("option[value='" + id + "']").attr("selected", "selected")
44 selector.find("span").remove();
45 select.find("option").each(function() {
46 if (this.hasAttribute("selected")) {
47 addTag(this.getAttribute("value"), this.innerText);
53 input.focusout(function(e) {
54 var value = input.val().trim()
56 show_error(input, "Please select an existing tag, it;s not possible to add custom ones.");
60 input.keydown(function(e) {
61 if (e.keyCode === $.ui.keyCode.TAB && $(this).data('ui-autocomplete').menu.active)
67 select: function(event, ui) {
68 addTag(ui.item.id, ui.item.toString());
73 // The following works only once.
74 // $(this).trigger('keydown.autocomplete');
75 // As suggested by digitalPBK, works multiple times
76 // $(this).data("autocomplete").search($(this).val());
77 // As noted by Jonny in his answer, with newer versions use uiAutocomplete
78 $(this).data("ui-autocomplete").search($(this).val());
81 input.data('ui-autocomplete')._renderItem = function(ul, item) {
83 .data('item.autocomplete', item)
84 .append($('<a/>').text(item.toString()))
88 input.data('ui-autocomplete')._resizeMenu = function(ul, item) {
89 var ul = this.menu.element;
90 ul.outerWidth(Math.max(
91 ul.width('').outerWidth(),
98 $.fn.csvSelector = function(source, name, result, allowSlash) {
99 return this.each(function() {
100 var selector = $(this),
101 input = $('input[type=text]', this);
105 for (var i = 0; i < source.length; i++) {
106 lookup[source[i].id] = source[i];
109 selector.click(function() { input.focus(); })
110 .delegate('.badge a', 'click', function() {
111 var id = $(this).parent().data("id");
112 for (var i = 0; i < selected.length; i++) {
113 if (selected[i] == id) {
114 selected.splice(i, 1);
120 function selectItem(id) {
121 for (var i = 0; i < selected.length; i++) {
122 if (selected[i] == id) {
130 function addTag(id, value) {
131 var tag = $('<span class="badge badge-pill badge-primary"/>')
135 .insertBefore(input);
137 input.attr("placeholder", null);
141 function recreate() {
142 selector.find("span").remove();
143 for (var i = 0; i < selected.length; i++) {
144 var value = lookup[selected[i]] || { value: selected[i] };
145 addTag(selected[i], value.value);
147 result.val(selected.join(","))
150 function readFromResult() {
152 var selected_raw = result.val().split(",");
153 for (var i = 0; i < selected_raw.length; i++) {
154 var raw = selected_raw[i].trim();
155 if (lookup[raw] || raw.match(/^([a-z0-9_]+)$/)) {
164 result.change(readFromResult);
166 input.focusout(function() {
167 var item = input.val();
168 if (item.length == 0) {
169 input.data("ui-autocomplete").search("");
170 } else if (item.match(/^([a-z0-9_]+)$/)) {
178 input.keydown(function(e) {
179 if (e.keyCode === $.ui.keyCode.TAB && $(this).data('ui-autocomplete').menu.active)
181 else if (e.keyCode === $.ui.keyCode.COMMA) {
182 var item = input.val();
183 if (item.length == 0) {
184 input.data("ui-autocomplete").search("");
185 } else if (item.match(/^([a-z0-9_]+)$/)) {
190 show_error(input, "Only lowercase alphanumeric and number names allowed.");
194 } else if (e.keyCode === $.ui.keyCode.BACKSPACE) {
195 if (input.val() == "") {
196 var item = selected[selected.length - 1];
197 selected.splice(selected.length - 1, 1);
199 if (!(item.indexOf("/") > 0))
209 select: function(event, ui) {
210 selectItem(ui.item.id);
217 input.data('ui-autocomplete')._renderItem = function(ul, item) {
219 .data('item.autocomplete', item)
220 .append($('<a/>').text(item.toString()))
224 input.data('ui-autocomplete')._resizeMenu = function(ul, item) {
225 var ul = this.menu.element;
226 ul.outerWidth(Math.max(
227 ul.width('').outerWidth(),
228 selector.outerWidth()
235 $(".multichoice_selector").each(function() {
237 var sel = ele.parent().find("select");
241 sel.find("option").each(function() {
242 var text = $(this).text();
244 id: $(this).attr("value"),
246 selected: $(this).attr("selected") ? true : false,
247 toString: function() { return text; },
251 ele.selectSelector(options, sel);
254 $(".metapackage_selector").each(function() {
255 var input = $(this).parent().children("input[type='text']");
257 $(this).csvSelector(meta_packages, input.attr("name"), input);
260 $(".deps_selector").each(function() {
261 var input = $(this).parent().children("input[type='text']");
263 $(this).csvSelector(all_packages, input.attr("name"), input);