Just tried the excellent Tag-It! plug-in for jquery (http://aehlke.github.com/tag-it/), but I can\'t get it to work how I would like.
I have an object list like this:
The most easiest thing is to get plugin that actually support this. That is Select2 or Chosen.
Overwriting focus
event to handle both label and value is not straightforward. My solution consisted of utilizing close
to create the tag using a saved reference of the last ui.item
from a focus
event:
$$("#search-widget-input")
.tagit(
{
placeholderText : 'Select or type a location, postcode or Web ID',
autocomplete : {
delay : 200,
minLength : 1,
search : function(event, ui) {
...
},
select: function(event, ui) {
// use the item's label instead of value
$$("#search-widget-input").tagit("createTag", ui.item.label, '__value__' + ui.item.value);
return false; // prevents the tag input to auto tag the ui.item.value
},
focus: function(event,ui) {
// `focus` event does not fire `select` but does fires `close` event
// so we store our `ui.item` which allows us to reference it in `close` event
event.preventDefault();
self.oAutoCompleteSavedLastUiItem = ui.item;
},
close: function(event, ui) {
event.preventDefault();
$$("#search-widget-input").tagit("createTag", self.oAutoCompleteSavedLastUiItem.label, '__value__' + self.oAutoCompleteSavedLastUiItem.value);
return false; // prevents the tag input to auto tag the ui.item.value
},
source : function fAutocompleteSource(oRequest, fResponse) {
...
}
...
}
...
});
Tried playing around with it, see: http://jsfiddle.net/pDrzx/46/
What i did:
Extendend the createTag function with the labelname
createTag: function(labelname, value, additionalClass)
And called it on the label creation var
var label = $(this.options.onTagClicked ? '<a class="tagit-label"></a>' : '<span class="tagit-label"></span>').text(labelname);
Then i made sure that the hidden input field had the number value(for saving purpose)
if (this.options.singleField) {
var tags = this.assignedTags();
tags.push(value);
this._updateSingleTagsField(tags);
} else {
var escapedValue = value;
tag.append('<input type="hidden" style="display:none;" value="' + escapedValue + '" name="' + this.options.itemName + '[' + this.options.fieldName + '][]" />');
}
And finally i added the labelname to the autocomplete and focus
// Autocomplete.
if (this.options.availableTags || this.options.tagSource) {
this._tagInput.autocomplete({
source: this.options.tagSource,
select: function(event, ui) {
// Delete the last tag if we autocomplete something despite the input being empty
// This happens because the input's blur event causes the tag to be created when
// the user clicks an autocomplete item.
// The only artifact of this is that while the user holds down the mouse button
// on the selected autocomplete item, a tag is shown with the pre-autocompleted text,
// and is changed to the autocompleted text upon mouseup.
if (that._tagInput.val() === '') {
that.removeTag(that._lastTag(), false);
}
that.createTag(ui.item.label,ui.item.value);
// Preventing the tag input to be updated with the chosen value.
return false;
},
focus: function(event, ui) {
event.preventDefault();
that.createTag(ui.item.label,ui.item.value);
}
});
So whats missing, well you need to make sure it passes the labelname in all the createTag methods, but that shouldnt be too hard :)
UPDATED WITH FOCUS (INSPIRED BY @Edwin)
The easiest way I've found to solve this problem is to change this line in the tag-it Javascript source:
that.createTag(ui.item.value);
to
that.createTag(ui.item.label);
This is part of the Autocomplete section of code starting on line 216 in my editor:
// Autocomplete.
if (this.options.availableTags || this.options.tagSource) {
this._tagInput.autocomplete({
source: this.options.tagSource,
select: function(event, ui) {
// Lots of comments here
if (that._tagInput.val() === '') {
that.removeTag(that._lastTag(), false);
}
that.createTag(ui.item.value);
value.
return false;
}
});
}
Here's another workaround (assuming you want to use data-id attribute):
var clone = $('#tags').clone();
// important to clone before calling tagit()
$('#tags').tagit({
beforeTagRemoved: function(event, ui) {
var item_id = clone.find('li:contains('+ui.tagLabel+')').data('id');
// do something with item_id / tag ui
}
});
Accompanying HTML:
<ul id="tags">
<li data-id="38">Item A</li>
<li data-id="19">Item B</li>
</ul>
Hi I just done it for my project with PHP.
I modified plugins at some point so use script from jsfiddle script section.
Look here i have made full working key value pair script https://jsfiddle.net/656pnLsd/
<ul id="tag_list">
<li data-value="2">test2</li>
<ul>
<script>
var tag_sources = [{value:1,label:'test1'},{value:2,label:'test2'}];
console.log(tag_sources);
jQuery(document).ready(function() {
var eventTags = $('#tag_list');
eventTags.tagit({
availableTags: tag_sources,
fieldName: "bento4_tags",
singleField: true,
});
});
</script>
UPDATED WITH FOCUS (INSPIRED BY @Edwin and Marco Johannesen)