A simple DataTable server-side search doesn't work

A simple DataTable server-side search doesn't work

klee777klee777 Posts: 12Questions: 2Answers: 0

Hi, I followed this video ("Part 2 - jQuery Datatable server side pagination and sorting in ASP.NET MVC application") in YouTube (https://www.youtube.com/watch?v=oCouA3tuA3o)
As I need to enable the search, I changed "filter" to true, but filter (search) didn't work. As I am new to datatable, I searched all server-side questions but I I didn't understand how they made it work.understand how they made it work.
Would you help me to make it work?

This is a javascript code:

var table;
$(document).ready(function () {
    table = $("#myTable").DataTable({
        "processing": true,     // for show progress bar
        "serverSide": true,     // for process server side
        "filter": true,         // enable/disable search box
        "orderMulti": false,    // enable/disable multiple columns at once
        "ajax": {
            "url": "/home/LoadData",
            "type": "POST",
            "datatype": "json"
        },
        "columns": [
            { "data": "ID_ACCOUNT", "name": "Account #" },
            { "data": "TXT_NAME", "name": "Customer" },
            { "data": "TXT_COMPANY", "name": "Company" },
        ]
    });

    // Although I added this because Filter didn't work, this didn't work either.
    $("input[aria-controls=myTable]").change(function () {
        table.columns(2).search(this.value).draw();
        //var jqTable = $("#myTable").dataTable();
        //jqTable.fnFilter(this.value);
    });
});

And this is ASP.NET MVC controller C# code:

[HttpPost]
public ActionResult LoadData()
{
    ...
    using (BTEntities dc = new BTEntities())
    {
        var v = (from item in dc.BT select item);
        // sorting
        if(sortColumnDir == "desc")
            v = v.OrderByDescending(item => item.ID_ACCOUNT);
        else
            v = v.OrderBy(item => item.ID_ACCOUNT);

        totalRecords = v.Count();
        var data = v.Skip(skip).Take(pageSize).ToList();

        return Json(new { draw = draw, recordsFiltered = totalRecords, recordsTotal = totalRecords, data = data }, JsonRequestBehavior.AllowGet);
    }
}

Answers

  • allanallan Posts: 63,288Questions: 1Answers: 10,427 Site admin

    At the server-side you need to read the search[value] parameter that is sent to the server and apply that as the condition to your data source. I don't see any use of the search information submitted to the server-side in your C# code.

    Allan

  • klee777klee777 Posts: 12Questions: 2Answers: 0

    @allan Thank you for your prompt reply. I didn't know how but now I know and it's working.

  • klee777klee777 Posts: 12Questions: 2Answers: 0

    @allan When I added the DateTime column, its value is like, "/Date(1648785600000)" instead of any normal ISO format.

    Should I correct this at the server side or in the client side using render function?

  • klee777klee777 Posts: 12Questions: 2Answers: 0

    Except the incorrect Date display (/Date(1648785600000)), here is the solution for server-side searching to help someone who has the same problem.

    a javascript code:

            var table;
            $(document).ready(function () {
                table = $("#myTable").DataTable({
                    "processing": true,     // for show progress bar
                    "serverSide": true,     // for process server side
                    "filter": true,         // enable/disable search box
                    "orderMulti": false,    // enable/disable multiple columns at once
                    "ajax": {
                        "url": "/home/LoadData",
                        "type": "POST",
                        "datatype": "json"
                    },
                    "columns": [
                        { "data": "ID_ACCOUNT", "name": "Account #" },
                        { "data": "TXT_NAME", "name": "Customer" },
                        { "data": "TXT_COMPANY", "name": "Company" },
                        { "data": "DTE_NOTICE", "name": "Notice 1", "type": "date", "authwidth": true }
                        ]
                });
                $("input[aria-controls=myTable]").change(function () {
                    // The following call will invoke the ajax "url": "/home/LoadData" used in DataTable creation.
                    table.columns().search(this.value).draw();
                });
            });
    

    MVC controller:

            [HttpPost]
            public ActionResult LoadData()
            {
                ...
                string searchTerm = Request.Form.GetValues("search[value]").FirstOrDefault();
                using (BTEntities dc = new BTEntities())
                {
                    IQueryable<BT> v;
                    if (searchTerm == "")
                        v = (from item in dc.BT select item);
                    else
                    {
                        v = (from item in dc.BT
                                where (item.TXT_NAME.Contains(searchTerm) || item.TXT_COMPANY.Contains(searchTerm))
                                select item);
                    }
                    // sorting
                    if(sortColumnDir == "desc")
                        v = v.OrderByDescending(item => item.ID_ACCOUNT);
                    else
                        v = v.OrderBy(item => item.ID_ACCOUNT);
                    totalRecords = v.Count();
                    var data = v.Skip(skip).Take(pageSize).ToList();
                    return Json(new { draw = draw, recordsFiltered = totalRecords, recordsTotal = totalRecords, data = data }, JsonRequestBehavior.AllowGet);
                }
            }
    
  • klee777klee777 Posts: 12Questions: 2Answers: 0

    I decided to parse it in the client side, and here is the solution:

    "columnDefs": [
        {
            "targets": 5,
            "render": function (data, type, row) {
                if (data != null) {
                    // e.g. data="/Date(1648785601234)";
                    var idxLParen = data.indexOf("(");
                    var idxRParen = data.indexOf(")");
                    var miliString = data.substr(idxLParen + 1, idxRParen - idxLParen - 1);
                    var miliNum = parseInt(miliString);
                    var date = new Date(miliNum);
                    return date.toLocaleDateString('en-US');
                } else {
                    return "";  // this field can be null.
                }
            }
        }
    ],
    
  • allanallan Posts: 63,288Questions: 1Answers: 10,427 Site admin

    Yes, that's the text representation of a .NET DateTime instance. Personally I would have the server return ISO8601 formatted strings rather than the .NET style string, but either will work.

    Allan

  • klee777klee777 Posts: 12Questions: 2Answers: 0

    @allan Thank you for your advice. I've tried to convert it on the server side, but don't know how to do it using the existing LINQ:

    v = (from item in dc.BT
         where (item.TXT_NAME.Contains(searchTerm) 
             || item.TXT_COMPANY.Contains(searchTerm))
         select item);
    

    Whatever I tried, I got the syntax error. So, I couldn't do it.

    I hope someone can show me the way.

  • allanallan Posts: 63,288Questions: 1Answers: 10,427 Site admin

    For LINQ you'd need to ask on StackOverflow or a C# specific forum. I'm afraid I don't know enough about LINQ to help with that.

    Allan

Sign In or Register to comment.