-1

I have a jquery autocomplete that once a value is selected it loads a datatable with checkbox from an ajax call. Then while submitting the form I need to access the datatable variable to iterate each row to get the selected ones, but the datatable variable appears as undefined.

I'm doing the same as in this example, only difference is the data is coming from an Ajax request.

Can you please help me understand why is that happening?

$(document).ready(function() {
  var campId;
  var t_OmnitureCode;

  // Campaign input autocomplete
  $("#campaign").autocomplete({
    source: function(request, response) {
      $.ajax({
        url: "promotion",
        type: "GET",
        data: {
          term: request.term,
          action: "searchCampaign"
        },
        dataType: "json",
        success: function(data) {
          if (!data.length) {
            var result = [{
              label: "no match found",
              value: "-1"
            }];
            response(result);
          } else {
            response($.map(data, function(item) {
              return {
                label: item.name,
                value: item.campaignId
              }
            }));
          }
        }
      });
    },
    select: function(event, ui) {
      event.preventDefault();
      campId = ui.item.value;
      if (campId != "-1") {
        this.value = ui.item.label;

        // This will apply datatables getting the content from an Ajax call
        t_OmnitureCode = applyDataTableOmnitureCode(campId);
      }
    },
    focus: function(event, ui) {
      event.preventDefault();
      this.value = ui.item.label;
    }
  });

  // Handling form submission
  $("#frm_promotion").on("submit", function(e) {
    var form = this;
    // Variable for datatable "t_OmnitureCode" is undefined below
    var rows_selected = t_OmnitureCode.column(0).checkboxes.selected();

EDIT: Just realized that even while assigning the variable (t_OmnitureCode = applyDataTableOmnitureCode(campId);) it is undefined, not sure why.

Here is the applyDataTableOmnitureCode code:

function applyDataTableOmnitureCode(campId) {
    $("#tbl_omnitureCode").DataTable({
        destroy: true, 
        scrollX: true,                                      
        fixedColumns: {
            leftColumns: 1
        },
        "ajax": {
            "url": "promotion",
            "type": "GET",
            "data": {
                action: "searchOmnitureCodesByCampaignId",
                campaignId: campId
            },
            "dataSrc": ""
        },                  
        "columns": [                        
            { "data": "key" },
            { "data": "omnitureCode" },
            { "data": "urlAppName" },
            { "data": "language" },
            { "data": "channel" },
            { "data": "createDateTime", "defaultContent": "" },
            { "data": "updateDateTime", "defaultContent": "" }
        ],
        "columnDefs": [                     
            { "targets": 0, "checkboxes": { "selectRow": true } }
        ],
        "select": {
            "style": "multi"
        },
        "order": [[1, "asc"]],
        "fnInitComplete": function() {
            $("#omnitureCodeSection").show();
        }
    });
};
Somebody
  • 2,667
  • 14
  • 60
  • 100

2 Answers2

1

You may need to grab your DataTables object into a variable before using that:

var t_OmnitureCode = $("#tbl_omnitureCode").DataTable();
var rows_selected = t_OmnitureCode.column(0).checkboxes.selected();

And, by the way, your method of populating DataTable with external ajax-call is suboptimal. There's an ajax option for that purpose where you can specify all the necessary parameters and get better integration with DataTables API and better performance (as you don't really need to destroy and create your DataTable upon each refresh).

You would simply need to trigger .ajax.reload() whenever you need to refresh your table data.

Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42
  • I'm doing `destroy:true` because of `cannot reinitialise datatable` error, so I did what suggested in: `https://stackoverflow.com/questions/24545792/cannot-reinitialise-datatable-dynamic-data-for-datatable` – Somebody May 28 '19 at 14:37
  • And that is an extremely bad piece of advise as rather than point OP of that post to the root cause (populating DataTables with external ajax-call instead of using native option `ajax`) it was suggested workaround that eliminates the consequences and not the root-cause, hurting app performance and causing further problems (like yours) with using API methods. – Yevhen Horbunkov May 28 '19 at 14:39
  • no worries :) it was well deserved. Now what solved my issue was the comment made by KevinB, if he doesn't make it an answer I can't mark it as the answer. – Somebody May 28 '19 at 14:51
  • If you mean you have assigned `.DataTable()` output to the variable and have it returned within `applyDataTableOmnitureCode(campId)` body, you've hurted your app performance even more since you'll be destroying and creating your table each time you need to use that variable instead of using native getter as I suggested above and simply call your function upon ajax-call success. – Yevhen Horbunkov May 28 '19 at 14:59
-1

It's a matter of scope : You declare the variable table inside $(document).ready function. You may want to put it outside in the global scope :

var table;

$(document).ready(function() { table = $('#example').DataTable({
... });

PhilMaGeo
  • 551
  • 6
  • 8