SrAxi
SrAxi

Reputation: 20015

DataTables ajax.reload() with parameters

I am using DataTables serverSide in an Angular2 project.

I am trying to reload the table after making changes, and those changes I want to pass them as parameters in POST via AJAX.

The thing is that DataTables is always getting the options object from the initialization, and not an updated version with the new parameters.

So, what I need is, to use ajax.reload() passing a new set of parameters.

This is my current function:

filterData(tableParams) {
    console.log('reloading DT. tableparams received are: ' + JSON.stringify(tableParams));

    let element = $(this.el.nativeElement.children[0]);
    let table = element.find('table.dataTable');
    table.DataTable().ajax.reload();
}

At the moment, as you can see, I'm not using tableParams, this is because I wanted to show a clean version of my function, I tried many things and none of them worked.

DataTables always gets the initial options object, with the initial parameters.

This is one of my desperate attempts:

filterData(tableParams) {
    let element = $(this.el.nativeElement.children[0]);
    let table = element.find('table.dataTable');
    table.DataTable({
        ajax: {
            url: this.jsonApiService.buildURL('/test_getUsers.php'),
            type: 'POST',
            data: tableParams,
        },
    }).ajax.reload();
}

Some help would be much appreciated. If you need further explanations on how the DataTable is created, or more code snippets let me know. But I think that the issue is just with the ajax.reload() function, being able to send updated parameters will solve the issue.

Thanks very much!

Edit 1

This is my init options object:

            let data = {
                email: true,
                test: 'init',
            };

            this.options = {
                dom: 'Bfrtip',
                processing: true,
                serverSide: true,
                pageLength: 20,
                searchDelay: 1200,
                ajax: {
                    url: this.jsonApiService.buildURL('/test_getUsers.php'),
                    type: 'POST',
                    data: data,
                },
                columns: [
                    {data: 'userId'},
                    {data: 'userCode'},
                    {data: 'userName'},
                    {data: 'userRole'},
                    {data: 'userEmail'},
                ],
            };

And these are the parameters that DataTables is sending:

enter image description here

(Among other DataTables parameters)

When I call ajax.reload(), no matter the things I have tried, I end up sending these same parameters, therefore, sending the init parameters.

Upvotes: 8

Views: 30158

Answers (4)

Kyle Coots
Kyle Coots

Reputation: 2131

I was looking to send new parameters with each request and not have to destroy and rebuild the datatable every time as well. I heavily use datatables on my site and was wanting an easier method for handling my use case so I came up with this. Maybe it will be useful for someone else.

buildDT.js :

        ;(function (){ 
        
    'use strict';
    
    /**
     * dtReload is used for setting new param 
     * to send to the server with out having 
     * to reload the table
     */
    var dtReload = {};
    /**
     * This is the object containing
     * the param to be sent to the server 
     */
    dtReload.param = {};
    /**
     * Adds the param to the object used by datatables
     * for the request
     * @param param object datatables object
     * @param extra object extra params to send to the server
     * @return object
     */
    dtReload.proccParam = (param, extra) => {
      $.each(extra, function(i,e){
        param[i] = e;
      })
      return param;
    }
    
    class buildDataTable {
        
        #url = '';
        #method = 'POST';
        
        #dtOptions = {};
        #responsive = true;
        #pageLength = 10;
        #lengthMenu = [5, 10, 20];
        #processing = true;
        #serverSide = true;
        #language = {}; 
        #initComplete;
        #columns = [];
        #columnDefs = [];

        ajaxParam;
        
        constructor(){}
        
        setURL(url){
            this.#url = url
        }
        
        setPageLength(pageLengthInt){
            if(pageLengthInt == 'undeinfed'){
              this.#pageLength = 10;
            }else if(typeof pageLengthInt == "number"){
              this.#pageLength = pageLengthInt;
            }else{
              console.log('Colums should be of type Array');
            }
        }
        
        setColumns(columnsArray){
            if(columnsArray == 'undefined'){
              this.#columns = [];
            }else if(typeof columnsArray == "object" && true == Array.isArray(columnsArray)){
              this.#columns = columnsArray;
            }else{
              console.log('Colums should be of type Array');
            }
        }
        
        setColumnDefs(columnDefsArray){
            if(language == 'undefined'){    
                this.#columnDefs = [
                  { targets: 'no-sort', orderable: false }
                ]   
            }else if(typeof columnDefsArray == "object" && true == Array.isArray(columnDefsArray)){
                this.#columnDefs = columnDefsArray;
            }else{
                console.log('Coulmn Definitions should be of type Array');
            }
        }
        
        setLanguage(language){
            if(language == 'undefined'){
              this.#language = {
                infoEmpty: "No Data To Display",
                emptyTable: "No Data To Display",
                zeroRecords: "No Data To Display"
              }
            }else if(typeof language == "object" && false == Array.isArray(language)){
                this.#language = language;
            }else{
                console.log('Language should be of type object');
            }
        }
        
        setInitComplete(func){              
            this.#initComplete = function(settings, json){
                if(typeof func == "function"){
                  func(settings,json);
                }
            }
        }
        
        setParam(param){ 
          this.ajaxParam = param;
        }
        
        getParam(){     
            return this.ajaxParam;
        }
        
        makeAjax(param){
          dtReload.param = param;
          return {
            url:this.#url,
            dataSrc:'data.result',
            data:function(d){   
              dtReload.proccParam(d, dtReload.param)
            },
            method:this.#method
          }
        }   
        
        #setOptions(){      
            this.#dtOptions = {         
                responsive:this.#responsive,
                pageLength:this.#pageLength,
                lengthMenu:this.#lengthMenu,
                processing:this.#processing,
                serverSide:this.#serverSide,
                language:this.#language,
                ajax:this.makeAjax(this.getParam()),
                initComplete:this.#initComplete,
                columns:this.#columns,
                columnDef:this.#columnDefs          
            }   
        }
        
        getOptions(){
          this.#setOptions();
          return this.#dtOptions;
        }   
    }
    
    window.dtReload = dtReload;
    window.buildDataTable = buildDataTable;
    
    
    })();

Useage

    var builder = new buildDataTable();
    var myDTableObject;
    
    function doSomething(id){
    
      // Pass the param 
      builder.setParam({
         someParam : 'doSomething',
         id:id,
         token : token_value
      });
    
      // Set the server url
      builder.setURL('http://your/url')
      // Setup your columns
      builder.setColumns([
        { "data": function(data){return columnProcess(data).id} },
        { "data": "name" },
        { "data": function(data){return columnProcess(data).status} },
        { "data": "date" },
        { "data": "options" }   
      ])
      
      // Check if datatables is loaded and setup
      if($.fn.dataTable.isDataTable('#yourTable')){
          // Set the new param
          dtReload.param = builder.getParam();
          // Reload the table
          myDTableObject.ajax.reload();
      }else{
        // Init table setup
        myDTableObject = $('#yourTable').DataTable(
          builder.getOptions()
        );
      } 
    }

Thanks to @sraxi for the idea of using the function in the ajax request to process the param.

I created a GitHub Repo for this here: DataTableReload

Upvotes: 0

Ilker Burak
Ilker Burak

Reputation: 121

$('#example').dataTable({
  "ajax": {
    "url": "data.json",
    "data": function (d) {
        d.extra_search = $('#extra').val();
    }
  }
});

then simply call:

table.ajax.reload();

Upvotes: 12

Akmal
Akmal

Reputation: 563

In some cases you may want to change ajax url at runtime or apply any additional query parameters.

So you can do like this:

var dataTable = $('#example').DataTable({...});    
dataTable.ajax.url('/new-ajax-url?someParam=1').load();

It works with version v1.10.16 of the library.

Upvotes: 13

SrAxi
SrAxi

Reputation: 20015

I finally got the solution, the problem was that I was too focused on achieving my goal through DataTable().ajax.reload(). I wanted to pass the parameters through there in one way or another, and that was incorrect.

I had to change the construction of the options object. As you saw earlier, I was assigning my custom parameters to the options object like this:

ajax: {
  url: this.jsonApiService.buildURL('/test_getUsers.php'),
  type: 'POST',
  data: this.params,
}

Where data: this.params would get the data from somewhere, in my case, I had 2 listeners, one for init and another for updating that change this.params value. This, instead of a listener could be an onChange(), but the point is that the parameters change at runtime.

So I simply had to put this into a function, and merge DataTable's parameters to my own parameters.

This is my solution:

data: function (d) {
    Object.assign(d, myClass.params);
    return d;
}

With this options object, when I have to refresh the DataTable sending new parameters to the server, I simply call ajax.reload(). DataTables will get the options object with the latest data and reload itself.

I really hope this can help someone! Good work and happy coding!

Upvotes: 17

Related Questions