multi-filter-select table row not appears when performed ajax call

multi-filter-select table row not appears when performed ajax call

suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0

Hi Allen,

I am using datatable for loading data (ServerSide Processing), so i have dropdown list <Departments>, by default first option selected when page loads so using ajax call I will pull the data from db related department employees.

On the first load, I am sending json data from server where i am use initcomplete function to form the Multi select dropdown and populate the data into list

It works well.

when I make another select from dropdownlist <departments> data getting populated but I am seeing row (multi select row) and initcomplete not hitting

I went across multiple Q&A, i found ajax.table.reload to use and initcomplete will fire only once

Can you please provide me working example where I can load and show data when i performed ajax call as well?

Answers

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    The initComplete callback runs only once after Datatables initializes. Without knowing when you need to update the dropdown list its hard to provide a specific answer.

    i have dropdown list <Departments>,

    Does this list contain all the options in the DB?

    How are you building the options list?

    The -option drawCallback` runs each time the table draws and in the case of server side processing runs each time data is fetched from the server. Maybe you need to use this instead.

    Please post your code so we can see what you are doing. Better is to provide a link to your page or a test case so we can actually see the script in action.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0
    edited April 2020

    Hi Kevin,

    Thank you quick feedback, I have created a test using js bin but it is not working example as I dont have data to populate

    https://jsbin.com/qeleledunu/edit?html,js,output

    I am using MVC5, HTML, Javascript,

    1. on view Index

    I will populate the data

    Html code :

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>JS Bin</title>
    </head>
    <body>
        <div class="col-md-10" >
                <select class="form-control" id="ddlDepts" name="ddlDepts"><option value="">Depart (Select)</option>
                <option selected="selected" value="1">Physics</option>
                <option value="2">Mathematics</option>
                <option value="3">Computer Science</option>
                </select>
        </div>
      
        <div class="col-md-2 text-right">
            <input type="button" class="btn btn-primary btnAdd" value="ADD" />
        </div>
    
        <div class="col-md-12">
            <table class="table table-bordered table-responsive table-oddEven-rows table-hover table-striped" style="width:100%;" id="tblAcwThresholdsList">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Age</th>
                        <th>Address</th>
                        <th>City</th>
                        <th class="text-right">Action</th>
                    </tr>
                </thead>
                <thead>
                    <tr class="customDropdown">
                        <th class="Name">Name</th>
                        <th class="Age">Age</th>
                        <th class="Address">Address</th>
                        <th class="City">City</th>
                        <th class="text-right btnAction">Action</th>
                    </tr>
                </thead>
            </table>
        </div>
      
    </body>
    </html>
    
    Javascript code 
    var datatable;
    
    $(document).ready(function () {
        $('#ddlDepts').off('change').on('change', function () {
            if ($('#ddlDepts').val() == "" || $('#ddlDepts').val() == null) {
                alert("select Dept");
                return;
            }
            
            getEmpList($('#ddlDepts').val() == "" ? $('#ddlDepts')[0]['1'].value : $('#ddlDepts').val());
        });
    
        //on document ready it will controller method and initilize
        getEmpList($('#ddlDepts').val() == "" ? $('#ddlDepts')[0]['1'].value : $('#ddlDepts').val());
    });
    
    
    function getEmpList(paramDeptID) {
    
        if (datatable != null) {
            datatable.destroy();
        }
    
        // This is for single Search button....
        $("#tblDeptList").one("preInit.dt", function () {
            // remove the current handler.
            $(".dataTables_filter input[type='search']").off();
    
            // replace the current search with bootstrap styled search
            $(".dataTables_filter").html(
                '<div style="width:320px" class="input-group">' +
                '<input type="search" class="form-control" placeholder="Search for...">' +
                '<span class="input-group-btn">' +
                '<button class="btn btn-primary" type="button">' +
                '<i class="glyphicon glyphicon-search"></i></button>' +
                '</span>' +
                '</div>'
            );
            // set variable for ease below
            var sbox = $(".dataTables_filter input[type='search']")
    
            // button event handler
            $(".dataTables_filter button").on("click", function () {
                $("#tblDeptList").DataTable().search(sbox.val()).draw();
            });
    
            // Enter key  handler 
            sbox.on("keydown", function (evtObj) {
                if (evtObj.keyCode == 13) {
                    $("#tblDeptList").DataTable().search(sbox.val()).draw();
                }
            });
    
        });
        
        datatable = $("#tblDeptList").DataTable({
            "scrollY": '60vh',
            "scrollCollapse": true,
            "language":
            {
                "search": "",
                "searchPlaceholder": "Search...",
                "processing": "<div class='overlay custom-loader-background'><i class='fa fa-cog fa-spin custom-loader-color'></i></div>"
            },
            "processing": true,
            "serverSide": true,
            "info": true,
            "searching": true,
            "orderCellsTop": true,
            "fixedHeader": true,
            "stateSave": false, //set it to true if table state needs to be restored on page reload, otherwise set it to false.
            "lengthMenu": [[10, 15, 20, 25, -1], [10, 15, 20, 25, "All"]],
            "pagingType": "full_numbers",
            "ajax": {
                "url": "/Department/GetEmployeesByDeptId",
                "type": "GET",
                "data": function (d) {
                    //Search Text Value
                    d.strSearchText = $(".dataTables_filter input[type='search']").val();
    
                    if (paramDeptID != undefined || paramDeptID != null) {
                        d.departmentId = paramDeptID;
                    }
                    else {
                        d.departmentId = $('#ddlDepts').val() == "" ? $('#ddlDepts')[0]['1'].value : $('#ddlDepts').val();
                    }
                }
            },
            "columns": [
                { "data": "Name", "orderable": true },
                { "data": "Age", "orderable": true },
                { "data": "Address", "orderable": true },
                { "data": "City", "orderable": false },
                {
                    "className": "text-right", "orderable": false, "render": function (data, type, row) {
                        return '<button class="btn-xs btn-primary editEmp">Edit</button>' +
                            '  <button class="btn-xs btn-danger removeEmp"  type="button">Remove</button>';
                    }
                }
            ],
            "order": [[0, "asc"]],
            "fnDrawCallback": function (oSettings) {
                //debugger;
                //alert('DataTables has finished its DrawCallBack.');
                $('.editEmp').on('click', function () {
                    editEmpFunction(datatable.row($(this).parents('tr')).data());
                });
    
                $('.removeEmp').on('click', function () {
                    removeEmpFunction(datatable.row($(this).parents('tr')).data());
                });
            },
            "fnInitComplete": function (oSettings, json) {
                //alert('DataTables has finished its initialisation.');
                //debugger;
    
                var names = json.GetNamesData;
                var nameSelect = $('<select id=selectNameId></select>')
                var nameOptions = "";
                for (var i = 0; i < names.length; i++) {
                    nameOptions += "<option value='" + names[i].Value + "'>" + names[i].Text + "</option>";
                }
                nameSelect.append(nameOptions);
                $('.customDropdown .name').html(nameSelect);
    
                var ages = json.GetAgesData;
                var ageSelect = $('<select id=selectAgeId></select>')
                var ageOptions = "";
                for (var i = 0; i < ages.length; i++) {
                    ageOptions += "<option value='" + ages[i].Value + "'>" + ages[i].Text + "</option>";
                }
                ageSelect.append(ageOptions);
                $('.customDropdown .age').html(ageSelect);
    
                var citylobs = json.GetcitiesData;
                var citiesSelect = $('<select id=selectCityId></select>')
                var cityoptions = "";
                for (var i = 0; i < citylobs.length; i++) {
                    cityoptions += "<option value='" + citylobs[i].Value + "'>" + citylobs[i].Text + "</option>";
                }
                citiesSelect.append(cityoptions);
                $('.customDropdown .sublob').html(citiesSelect);
    
                var ntypesSelect = $('<button  class="btn-xs btn-warning btnFilter" type="button"><i class="glyphicon glyphicon-filter"></i></button>')
                $('.customDropdown .btnAction').html(ntypesSelect);
    
                // button event handler
                $(".btnFilter").on("click", function () {
                    //debugger;
                    if ($(".dataTables_filter input[type='search']").val() != '') {
                        $(".dataTables_filter input[type='search']").val('');
                    }
    
                    datatable.columns(0).search($('#selectNameId').val());
                    datatable.columns(1).search($('#selectAgeId').val());
                    datatable.columns(2).search($('#selectCityId').val());
                    datatable.draw();
                });
            }
    
        });
    }
    

    Edited by Colin - Syntax highlighting. Details on how to highlight code using markdown can be found in this guide.

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    The fiddle doesn't run. We would also need to see the issue occurring - you can load data with data so you don't need to link to your data source.

    Colin

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0

    Yeah, I know sample I tried to create is now working as I not able to load the data as expected and I want to show exact code what i am using so i provided snippet of my code if you see where i am going wrong

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    Maybe you can explain a bit more about what you are trying to achieve. You have server side processing enabled and are sending search parameters to the server script. Sounds like what you want to do is update the dropdown lists when the filter values change, correct? Or do you want to update the dropdown list each time the server side script responds with table data, each search, sort or page of the table?

    Basically the answer of when you want to update the dropdown lists will dictate where the code to rebuild the DDL will need to be.

    Kevin

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0

    Let me explain

    1. MVC Index View, I have initiated as below

      <table class="table table-bordered table-responsive table-oddEven-rows table-hover table-striped" style="width:100%;" id="tblAcwThresholdsList">
          <thead>
              <tr>
                  <th>Name</th>
                  <th>Age</th>
                  <th>Address</th>
                  <th>City</th>
                  <th class="text-right">Action</th>
              </tr>
          </thead>
          <thead>
              <tr class="customDropdown">
                  <th class="Name">Name</th>
                  <th class="Age">Age</th>
                  <th class="Address">Address</th>
                  <th class="City">City</th>
                  <th class="text-right btnAction">Action</th>
              </tr>
          </thead>
      </table>
      

    when Index page loaded (starting / Initial page) I have dropdown List which will be populated by Departments

    <div class="col-md-10" >
            <select class="form-control" id="ddlDepts" name="ddlDepts"><option value="">Depart (Select)</option>
            <option selected="selected" value="1">Physics</option>
            <option value="2">Mathematics</option>
            <option value="3">Computer Science</option>
            </select>
    </div>
    

    Physics
    Mathematics
    etc.

    On document.ready() for the first time I am calling, passing default one selected item.

    getEmpList($('#ddlDepts').val() == "" ? $('#ddlDepts')[0]['1'].value : $('#ddlDepts').val());
    

    in the getEmpList()

    I will detroy and recreate datatable.

    I am using function drawCallBack and fnInitiComplete where i am converting

            <thead>
                <tr class="customDropdown">
                    <th class="Name">Name</th>
                    <th class="Age">Age</th>
                    <th class="Address">Address</th>
                    <th class="City">City</th>
                    <th class="text-right btnAction">Action</th>
                </tr>
            </thead>
    

    "fnInitComplete": function (oSettings, json) {
    //alert('DataTables has finished its initialisation.');
    //debugger;

            var names = json.GetNamesData;
            var nameSelect = $('<select id=selectNameId></select>')
            var nameOptions = "";
            for (var i = 0; i < names.length; i++) {
                nameOptions += "<option value='" + names[i].Value + "'>" + names[i].Text + "</option>";
            }
            nameSelect.append(nameOptions);
            $('.customDropdown .name').html(nameSelect);
    
            var ages = json.GetAgesData;
            var ageSelect = $('<select id=selectAgeId></select>')
            var ageOptions = "";
            for (var i = 0; i < ages.length; i++) {
                ageOptions += "<option value='" + ages[i].Value + "'>" + ages[i].Text + "</option>";
            }
            ageSelect.append(ageOptions);
            $('.customDropdown .age').html(ageSelect);
    
            var citylobs = json.GetcitiesData;
            var citiesSelect = $('<select id=selectCityId></select>')
            var cityoptions = "";
            for (var i = 0; i < citylobs.length; i++) {
                cityoptions += "<option value='" + citylobs[i].Value + "'>" + citylobs[i].Text + "</option>";
            }
            citiesSelect.append(cityoptions);
            $('.customDropdown .sublob').html(citiesSelect);
    
            var ntypesSelect = $('<button  class="btn-xs btn-warning btnFilter" type="button"><i class="glyphicon glyphicon-filter"></i></button>')
            $('.customDropdown .btnAction').html(ntypesSelect);
    
            // button event handler
            $(".btnFilter").on("click", function () {
                //debugger;
                if ($(".dataTables_filter input[type='search']").val() != '') {
                    $(".dataTables_filter input[type='search']").val('');
                }
    
                datatable.columns(0).search($('#selectNameId').val());
                datatable.columns(1).search($('#selectAgeId').val());
                datatable.columns(2).search($('#selectCityId').val());
                datatable.draw();
            });
        }
    

    when the page loads initially for the first time, i am seeing below the header there are dropdown boxes filled with data and am able to do filter without any issue.

    but If I change / select new value from the select item list, i,e, Physics is default selection if I change to Mathematics.

    <div class="col-md-10" >
            <select class="form-control" id="ddlDepts" name="ddlDepts"><option value="">Depart (Select)</option>
            <option selected="selected" value="1">Physics</option>
            <option value="2">Mathematics</option>
            <option value="3">Computer Science</option>
            </select>
    </div>
    

    In onChange i am calling getEmpList($('#ddlDepts').val());

    $('#ddlDepts').off('change').on('change', function () {
       getEmpList($('#ddlDepts').val() == "" ? $('#ddlDepts')[0]['1'].value : $('#ddlDepts').val());
    });
    

    which will call getEmpList which will destroy the current table and recreate it.

    I See initiComplete being hit but I am not seeing dropdowns in the view

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0

    Basically when I change the Dropdown, I am not seeing the multi-select column displayed apart from the first time.

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0
    edited April 2020

    if we change the selection or while recreating i am losing the dropdown filters

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954
    edited April 2020

    When the Datatable is destroyed and rebuilt you say you aren't seeing the column dropdown list. Do you see the second header?

    You are appending using this:

        nameSelect.append(nameOptions);
        $('.customDropdown .name').html(nameSelect);
    

    Maybe you need to use jQuery empty first. If this doesn't help inspect the second header to see what it contains after the destroy() and reinitialize.

    If you still have difficulties the test case can be narrowed down to the process you are using to initially build the selects and the destroy and rebuild of the Datatable. The actual data doesn't matter. This page contains templates for ajax and server side loaded data if you want. But you can probably just fake the options list to demonstrate the issue.

    Kevin

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0
    edited April 2020

    I am not seeing second header at all (not displayed)

    Link above provide shows me 404

    404 - Page not found
    Sorry, the page you are looking for does not exist. Please feel free to get in touch if you feel you have reached this page in error.

    If you typed the url yourself please check the address and spelling
    It is possible that the page you are looking for has been removed

  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395

    Remove the closing bracket from the url.

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    Sorry, mistyped the link. Fixed above. It had an extra ) at the end.

    Kevin

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0
    edited April 2020

    do you have any sample which loads data from array or text file using server side processing so that I can modify that test to replicate mine which have some options where i can select or display required data

    That will be easy for me

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    Did you look at the link I provided?
    https://datatables.net/manual/tech-notes/9

    There are starter templates for ajax and server side sourced data using either arrays or objects.

    Kevin

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0

    Thanks Kevin,

    If i call table.destroy() is the thead and tfoot will be deleted?

    As shown in below, if I created in html and before calling can I clone the thead with class customdropdown?

    Name Age Address City Action
    Name Age Address City Action
  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    The destroy() docs explain this:

    DataTables adds a number of HTML elements, event listeners and other modifications in order to enhance the original HTML table with the features of DataTables. This method can be used to remove those enhancements and return the table to its original un-enhanced state, with the data shown in the table.

    Kevin

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0

    Thanks Kevin, I have fixed issue myself

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954
    edited April 2020

    Glad you fixed it! Do you mind passing along what you fixed in case others have the issue?

    Kevin

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0
    edited April 2020

    Sure Kevin,

    First Time when we load page, HTML content is formed in View is been considering as shown below.

    ** **
    Name Age Address City Action
    Name Age Address City Action

    So
    1. Filter row being added below the Header row with dropdowns

    1. Filter Dropdowns are getting populated with Server Data as did in InitCompleted provided in above code

    when we do any ajax calls in the page, after reload in the function getEmpList() first we are destroying the table

    if (datatable != null) {
        datatable.destroy();
    }
    

    Once we call the destroy(), it is been destroyed the thead settings which we defined in HTML View (not sure why it happens as it remembers Thead column definitions). So we need to recreate the header part by using the clone function

        $('#tblDeptListthead').clone(true).appendTo('#tblDeptList');
    

    and replicated the filter row as specified in Index view

    </thead>
    

    ** <thead>
    <tr class="customDropdown">
    <th class="Name">Name</th>
    <th class="Age">Age</th>
    <th class="Address">Address</th>
    <th class="City">City</th>
    <th class="text-right btnAction">Action</th>
    </tr>
    </thead>**

    As the table is destroyed, and recreated InitiComplete is called and populating the data which I am passing from server using json.

    Thanks
    Suresh

  • suresh9sbsuresh9sb Posts: 12Questions: 1Answers: 0

    Kevin,

    with this I have few questions.

    1. when we destroy the table, why it is loosing the HTML content which is defined in the HTML view is lost ?

    ** <thead>
    <tr class="customDropdown">
    <th class="Name">Name</th>
    <th class="Age">Age</th>
    <th class="Address">Address</th>
    <th class="City">City</th>
    <th class="text-right btnAction">Action</th>
    </tr>
    </thead>**

    As it holds the HTML view defined for Table header, is this a bug?

    Note:
    I can understand if we loose the theader information if we clone it but this is set from Index

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    Not sure I understand your question. Can you provide a simple example using http://live.datatables.net/ ?

    Kevin

This discussion has been closed.