DataTable thinks it is using DOM data source when using ajax
DataTable thinks it is using DOM data source when using ajax
Hi,
I have a DataTable that I've upgraded to 1.10.2 (from 1.9.4). I'm using server side processing and have a custom function for the ajax
setting (I need to set recordsTotal from the AJAX result).
When I try to access the table's data from the API, It keeps returning an array of results which are formatted according to columns[n].render
instead of the original source object from the ajax request.
Here are my debug results:
http://debug.datatables.net/ubocib
Here is my init block (coffeescript)
@$el.find('table').DataTable({
dom: "r<'row toolbar'<'col-lg-9'><'col-lg-3 text-right'f>>t<'row'<'col-lg-6'i><'col-lg-6 text-right'p>>",
retrieve: true,
pagingType: "simple"
processing: true
serverSide: true
ajax: (data, callback, settings) ->
console.log "ajax", settings
url = "/api/v1/audience/?stats=false&shared_audiences=true"
ajax_data = {
'limit' : data.length
'offset': data.start
'draw': data.draw #request order
}
current_query = data.search.value
ajax_data['query'] = current_query if current_query isnt ''
sorting_column_names = []
if data.order.length > 0
for sorting_obj in data.order
column = data.columns[sorting_obj.column]
continue unless column.orderable
direction = if sorting_obj.dir is 'desc' then '-' else ''
sorting_column_names.push direction + column.data
ajax_data['order_by'] = sorting_column_names.join ',' if sorting_column_names.length > 0
if ajax_data['order_by'] == ''
delete ajax_data.order_by
$.get(url, ajax_data, (json) ->
output = {
recordsTotal: json.meta.total_count
recordsFiltered: json.meta.total_count
data: json.objects
}
callback(output)
)
language: {
lengthMenu: "_MENU_ records per page",
emptyTable: "No data providers loaded.",
processing: '<div class="progress progress-striped active"><div class="progress-bar" style="width: 100%">Processing...</div></div>',
search: "",
searchPlaceholder: "Erik",
},
columns: [
{ title: "Segments", data: 'description', render: (val, type, source) =>
display_name = source.description
icon = 'glyphicon glyphicon-file'
return "<span title='#{ source.description.replace(/'/g, ''') } (#{ source.slug })'><span class='#{ icon }'></span> #{ display_name }</span>"
},
{ title: "blah", width: "40px", className: "target_segment", orderable: false, data: (seg) ->
return "<a class='add_segment' href='#'>Add</a>"
},
{ title: "slug", width: "40px", className: "target_segment", orderable: false, data: 'slug'
},
],
rowCallback: ( row, data ) =>
# aData is what we want to use
if @options.segments_draggable
$(row).data('resource_uri', data.resource_uri)
$(row).draggable({
opacity: 0.45
cursorAt: { left: 50 }
cursor: "move"
#containment: ".booleanGroupContainer"
revert: "invalid"
stop: (event, ui) =>
console.log( "stopped dragging available row", event, ui, @ )
helper: "clone",
})
console.log("fnRowCallback", arguments)
})
Seems like it may be a bug.
Erik
Answers
I created a jsFiddle to try to duplicate the issue, but it seems to work fine there. I'm not sure why it would work in jsFiddle and not on my dev box. Thoughts?
http://jsfiddle.net/erikcw/vsdcbf5k/6/
Additionally, I'm able to get it to work as expected if I remove the second datatable from the page. This page has two tables -- each are instantiated by there own
$('selector').DataTable({...})
calls.Adding a second datatable to jsFiddle doesn't not cause the to surface there.
UPDATE:
So both tables are in a bootstap accordian - one per accordian panel. If I search with jQuery for the tables on the page (
$('table')
), I get an array with 2 table elements. However, if I use the dataTables API to find all the tables, I only get one of them ($.fn.dataTable.tables()
).It looks like the two tables are clobbering each other somehow.
Looks like it was some sort of race condition. I fixed it by ensuring that both tables aren't loaded at the same time -- which isn't an issue because of the use of the accordion for the UI.
Looks like I found the issue. Just wanted to record it here in case anyone else runs across a similar problem.
Both tables had the same
id
attribute (ie<table id="same_id_both_tables"></table>
). This came from using the same Handlebars template to generate the tables.It seems that DataTables version 1.9.x was able to tolerate this, but 1.10 silently fails. Obviously using the same id attribute twice on a page is a bad practice, however it would be nice if DataTables wrote a warning to the console or something to ease debugging.
Here is an example:
http://jsfiddle.net/vsdcbf5k/8/
I've opened an issue here: https://github.com/DataTables/DataTables/issues/409
Hi,
I just commented on your github issue that the issue is invalid since it isn't valid HTML to have the same ID on multiple elements in a document.
You note that it would be good to log a warning for this, but I don't think it should fall to DataTables to pick up such errors as it would lead to a considerable amount of extra code to catch errors like this I think. For example, if you have a document which has shared IDs for two elements, and use jQuery to access it, it doesn't return a list of two elements, it just picks the first since it is using querySelectorAll or getElementById under the hood and that is how the DOM is meant to operate.
As I noted in the github issue, DataTables assumes that the HTML it is processing is valid. I think anything else would lead to madness - and I'm teetering on the edge of that even with that assumption ;-)
Allan