DataTable thinks it is using DOM data source when using ajax

DataTable thinks it is using DOM data source when using ajax

erikcwerikcw Posts: 6Questions: 1Answers: 0

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, '&#39;') } (#{ 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

  • erikcwerikcw Posts: 6Questions: 1Answers: 0
    edited August 2014

    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.

  • erikcwerikcw Posts: 6Questions: 1Answers: 0

    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.

  • erikcwerikcw Posts: 6Questions: 1Answers: 0
    edited August 2014

    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

  • allanallan Posts: 63,522Questions: 1Answers: 10,473 Site admin

    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

This discussion has been closed.