In select2 I have tags loaded by AJAX, if the tag is not found in the db then the user has the option to create a new one. The issue is that the new tag is listed in the select2 box as a term and not as the id (what select to wants - especially becomes a problem when loading the tags again if the user wants to update since only the term and not the id is stored in the db). How can I, on success of adding the term, make it so that select2 recieves the ID and submits the ID instead of the tag name/term?
$(document).ready(function() {
var lastResults = [];
$("#project_tags").select2({
multiple: true,
placeholder: "Please enter tags",
tokenSeparators: [","],
initSelection : function (element, callback) {
var data = [];
$(element.val().split(",")).each(function () {
data.push({id: this, text: this});
});
callback(data);
},
ajax: {
multiple: true,
url: "framework/helpers/tags.php",
dataType: "json",
data: function(term) {
return {
term: term
};
},
results: function(data) {
return {
results: data
};
}
},
createSearchChoice: function(term) {
var text = term + (lastResults.some(function(r) {
return r.text == term
}) ? "" : " (new)");
return {
id: term,
text: text
};
},
});
$('#project_tags').on("change", function(e) {
if (e.added) {
if (/ \(new\)$/.test(e.added.text)) {
var response = confirm("Do you want to add the new tag " + e.added.id + "?");
if (response == true) {
alert("Will now send new tag to server: " + e.added.id);
$.ajax({
url: 'framework/helpers/tags.php',
data: {
action: 'add',
term: e.added.id
},
success: function(data) {
},
error: function() {
alert("error");
}
});
} else {
console.log("Removing the tag");
var selectedTags = $("#project_tags").select2("val");
var index = selectedTags.indexOf(e.added.id);
selectedTags.splice(index, 1);
if (selectedTags.length == 0) {
$("#project_tags").select2("val", "");
} else {
$("#project_tags").select2("val", selectedTags);
}
}
}
}
});
});
Heres part of the switch that does the adding
case 'add':
if (isset($_GET['term'])) {
$new_tag = escape($_GET['term']);
if (Nemesis::insert('tags', 'tag_id, tag_content', "NULL, '{$new_tag}'")) {
// we need to send back the ID for the newly created tag
$search = Nemesis::select('tag_id', 'tags', "tag_content = '{$new_tag}'");
list($tag_id) = $search->fetch_row();
echo $tag_id;
} else {
echo 'Failure';
}
exit();
}
break;
UPDATE: I've done a bit of digging, and what confuses me is that the select2 input does not seem to store the associated ID for the tag/term (see below). I know I could change the attribute with the success callback, but I don't know what to change!
data: { term: e.added.id, action: 'add' }
and then remove the?action=add&term=' + e.added.id + ''
portion of the url option. – mathewbergttype: "POST"
which means the variables will NOT be added to the end of the URL. Instead, in Chrome Dev Tools look under the 'Headers' tab of the ajax call and expand the 'Form Data' section to view the term and action variables passed in the POST. If you want to see the variables in the URL, usetype: "GET"
. Also, it looks like in your PHP code you are testing whether the request is of type GET, so you will want to make your AJAX call and that logic match. – mathewbergt