Loading multiple tags into Select2 field using AJAX
Loading multiple tags into Select2 field using AJAX
I'm using the select2 plugin for two of my columns, they both allow multiple tags, with a hidden ID behind the text shown. I can succesfully create rows, and send the data back to the server, in the form of a string of Guids, but when I try to show it in the table, I only see the string of Guids, not the labels.
I've tried a few different things to get it to work, currently I'm trying to send back back both the Id and the text, but this throws a "Requested unknown parameter" error.
I've uploaded debug data here:
http://debug.datatables.net/eqeguc
I'm not entirely sure what the correct way to go about fixing this is. I thought about editing the datatables.editor.js file to allow you to show all fields as inline editable all the time, but I don't think that's the right way either. Here's my current code:
var editor;
var SurveyDefaultGrid = SurveyDefaultGrid || {};
SurveyDefaultGrid.initGrid = function (id, tableElement) {
editor = new $.fn.dataTable.Editor({
ajax: {
create: {
type: "POST",
url: "/surveys/surveydefaultcalculation/create/" + id,
},
edit: {
type: "POST",
url: "/surveys/surveydefaultcalculation/edit/_id_"
},
remove: {
type: "GET",
url: "/surveys/surveydefaultcalculation/delete"
}
},
legacyAjax:true,
table: tableElement,
idSrc: "Id",
fields: [
{
label: 'Element Group Reference', name: 'CompositionGroupIds', type: 'select2',
opts: {
multiple: true,
minimumInputLength: 1,
ajax:{
url: "/api/internal/surveys/compositiongroup/search/mandate/" + id + "?format=json",
dataType: "JSON",
data: function (params) {
return {
Query: params.term, // search term
Page: params.page
};
},
processResults: function (data, page) {
var results = [];
$.each(data.Results, function (k, group) {
results.push({ text: group.Name, id: group.Id });
});
return {
results: results
};
},
cache: true
}
}
},
{
label: 'Element Reference', name: 'MandateElementTypeIds', type: 'select2',
opts: {
multiple: true,
minimumInputLength: 1,
ajax: {
url: "/api/internal/surveys/mandateelementtype/search/mandate/" + id + "?format=json",
dataType: "JSON",
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, page) {
var results = [];
$.each(data.Results, function (k, group) {
results.push({ text: group.Name, id: group.Id });
});
return {
results: results
};
},
cache: true
}
}
},
{ label: 'Expression', name: 'Expression' },
],
});
editor
.on('open', function (e, type) {
if (type === 'inline') {
// Listen for a tab key event when inline editing
$(document).on('keydown.editor', function (e) {
if (e.keyCode === 9) {
e.preventDefault();
// Find the cell that is currently being edited
var cell = $('div.DTE').parent();
if (e.shiftKey && cell.prev().length && cell.prev().index() !== 0) {
// One cell to the left (skipping the first column)
cell.prev().click();
}
else if (e.shiftKey) {
// Up to the previous row
cell.parent().prev().children().last(0).click();
}
else if (cell.next().length) {
// One cell to the right
cell.next().click();
}
else {
// Down to the next row
cell.parent().next().children().eq(1).click();
}
}
});
}
})
.on('close', function () {
$(document).off('keydown.editor');
});
$(tableElement).on('click', 'tbody td', function (e) {
editor.inline(this, {
submitOnBlur: true
});
});
var table = $(tableElement).DataTable({
ajax: '/surveys/surveydefaultcalculation/data?id=' + id,
dom: 'Bfrtip',
columns: [
{
data: 'CompositionGroupIds',
},
{
data: 'MandateElementTypeIds',
},
{ data: 'Expression' }
],
select: 'single',
buttons : [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
]
});
};
This question has an accepted answers - jump to answer
Answers
I don't know much about Select2,. but it looks like there were some syntax changes with v4.
The last two entries in this post should help.
http://stackoverflow.com/questions/25428361/dynamically-add-item-to-jquery-select2-control-that-uses-ajax
I don't think select2 is my main problem. It manages to both search and pass data back fine. It's more the way datatables displays the data that comes back.
If I just use the Guids that it's stored as, then that's all that comes up.
If I pass an array of {text:..., id:...} all that is shown is [object Object].
I'm not sure what I need to pass back to the text value is shown on the table, and the tags shown when inline editing
On the Select2 plugin docs, it shows using "label" and "value" as the key/value tags. You are using "text" and "id".
http://editor.datatables.net/plug-ins/field-type/editor.select2
Hi,
If you reload the page, does it correctly show the text rather than the guid? If that is the case then the issue would be that the Ajax response from the edit is different from that when loading the initial data for the table.
However, for the
[Object object]
part - you have:Which points to an object:
Simply using:
will resolve that
Allan
Using
shows the label, but when I click into the edit window, the select2 input is empty. This is whether I use {label:..., value:...} or {id:...,text:...}. Also, I don't seem to be able to do inline editing this way?
What version of Select2?
4.0.0
It looks like there might be a type - in the Editor initialisation you have
name: 'MandateElementTypeIds'
(note that Type has a p).In the JSON return from your server (from the debug trace) it is:
"MandateElementTyeIds": ...
- no p.Additionally, the Editor field name should be:
MandateElementTypeIds.id
- i.e. the database column name that you want it to edit.Allan
Does type sometimes not come with a p? lol
Allan, yes I'd noticed that typo and fixed it in a later version, cheers for pointing it out.
I apologise, I must be explaining the bug poorly. I've made a video of the specific problem and have have taken a more recent debug snapshot of the table.
Debug: http://debug.datatables.net/ifoduf
Video: https://youtu.be/SaRXBKxGqeI
I illustrate the problem at the beginning of the video. Even though id's are sent down from the server
When I click on the field to put it into inline edit mode, the tag doesn't show up. The same happens in the edit window.
After I have entered a new value into the field, it's cached by select2 and I can click in and out and the tag is shown whenever I'm in edit mode (please ignore how the label stays as labeltest after submit, this is just a mock I've sent down without doing the conversion on the server, the id is still sent though)
In terms of using multiple as well, I still can't get it to work either as a list of objects with 'id' and 'text' or joining the strings into id:"id1,id2,id3..." etc.
Are you able to give me a link to the page please. I'll need to be able to access it in order to provide any assistance in this case I think as it is going to involve debugging.
Allan
I'm not unfortunately, it's on my dev machine and it can't go on to the live site. I'd be willing to change how I'm doing it if you have advice, I can change stuff on the server to get different output and stuff.
Can you see in general what I'm trying to do?
I think so - although it is a little difficult to follow properly without being able to use the page.
What should happen normally is that your JSON would include both the labels and the values. The labels are the values that are seen in the DataTable while the values are what Editor will edit (although it may also show the label!).
Assuming we are using
MandateElementTypeIds
you would typically want your DataTable to use:and Editor to use:
Now assuming that Select2 has a similar list of options available to it (i.e. the list of options) if you give it a specific id, it should show the label for that value. That is how the
select
field works, and how I think Select2 should also be working.What might be making it more complicated here is that your video appears to show that Select2 might be able to accept multiple tags. I don't know if that is the case or not here, but if it is, then it would need to use an array - but your data above shows an object.
Allan
I am trying to get it to accept multiple tags. I've redone the server side to pass down an array, in the form of
Is this correct? Would I still want my Datatable to use
and Editor to use:
Because this doesn't seem to work. I tried looking through http://datatables.net/reference/option/columns.data to see how to handle arrays of objects, but couldn't see.
So, I'm using
To display the text in the datatable, but using a similar notation for the editor throws a few different errors
Invalid regular expression: /(^|.)select2.(?:.*.)?select2-DTE_Field_MandateElementTypeIds[,(.|$)/: Unterminated character class
and
The select2('val') method was called on an element that is not using Select2.
Should I use different notation?
I've used
under editor fields. But this still doesn't make the tags come up, and the inline editor doesn't close after submit.
Have you tried simply
name: 'MandateElementTypeIds'
(with nodata
option) for the Editor confirmation? I wonder if Select2 would handle this correctly - it depends if it wants an array of the object tags or an array of ids.Your approach for the DataTables display is spot on and I'll take a look locally as to why the array syntax is throwing an error - that's slightly surprising.
Regards,
Allan
Using just
is the same, nothing comes up in edit mode. Also inline edit mode complains about no knowing which field it is
Uncaught Unable to automatically determine field from source. Please specify the field name. For more information, please refer to
This is what's currently happening with the setup I mentioned.
Video: https://youtu.be/1DZOYsXDBQk
Okay - the first thing we need to do is determine what values Select2 expects.
Looking at the select2 examples ("Tagging support" specifically) if I enter
$(".js-example-tags").select2('val')
into the console I get an array back. So presumably it is looking for an array (although frustratingly there doesn't appear to be an example that uses an array of objects, so I'm not 100% certain).So let's try:
in the Editor field. That will give it an array of id values.
If you want inline editing support you'll need to use the
columns.editField
option like the tech note the error message links to suggests, but let's cross that bridge when we come to it.Allan
OK, I've disabled inline editing for now. It still isn't working so I've done some debugging to see what the problem might be.
I'm getting a simple
Uncaught TypeError: Cannot read property 'length' of null
error in the jquery.datatables.js file when I try to create or edit an element. Its happening to
val
in this loop underfunction _fnSetObjectDataFn( mSource )
I worked back through and noticed where val was getting set to null, in multiGet:
this.val()
was null.The main problem with the tags not showing up when I open the edit window still exists. I'm not 100% sure if it's related to this error.
Just a note: if I go back to
name: 'MandateElementTypeIds'
I get a similar error. wheredata
isundefined
in this loop.I think this is from
data[ a[i] ]
returning undefined hereAn example of the data
a = ["CompositionGroupIds", "text"], i = 0
data[ a[i] ]
still returns undefined even if there is adata.CompositionGroupIds
I think to make any progress with being able to help here I'm going to need to set up a test page so I can experiment myself if you aren't able to give me a working test case. Unfortunately it is going to be at least a week before I have a gap to be able to do that due to a huge backlog and a release I wanted to make this week (and probably won't happen until next unfortunately).
Allan
That's ok,I'm going to hit my sprint deadline before that, so I think I'll end up doing it a simpler, but less usable way without select2. You've been incredibly helpful, and I definitely understand more about some of the underlying features of datatables now.
I'll still look into this as I'd like to understand what is happening myself. It almost certainly won't be this week now I'm afraid - but I'll post back here when done (even if it is too late for yourself - sorry!).
Allan