how to pass search data to the serverside

how to pass search data to the serverside

Lorenzo00Lorenzo00 Posts: 12Questions: 2Answers: 0

Sorry, I haven't a link to the Test Case.

I have created an input tag for each column in the table, I would like to use them to perform searches by filtering on the individual field. My problem is that with the javascript code of the call I can't fill the given column[n][search][value] of the call payload. How should I do this?

My JS code:

$.ajax({
    url: "/WebServiceDataTable.asmx/GetColumnData",
    type: "post",
    data: JSON.stringify({ url: `${window.location.href}` }),
    success: function (columnData) {
        setTheadTfoot(columnData);
        dataTable = $('#tblDataTable').DataTable({
            "processing": true,
            "serverSide": true,
            "info": getParamsValue("INFO"),
            "ordering": getParamsValue("ORDERING"),
            "searching": getParamsValue("SEARCH"),
            "paging": getParamsValue("PAGING"),
            "ajax": {
                url: "/WebServiceDataTable.asmx/GetDataForDataTable",
                type: "POST"
            },
            "columns": JSON.parse(columnData)
        });
        setSearchingField();
    }
});

function setSearchingField() {
    if (!getParamsValue("SEARCH") && getParamsValue("COLUMNSSEARCH")) {
        const headers = document.getElementById("tblDataTable").getElementsByTagName("thead")[0].getElementsByTagName("th");
        for (let i = 0; i < headers.length; i++) {
            const input = document.createElement("input");
            input.setAttribute("type", "text");
            input.classList.add("w-100");
            input.setAttribute("placeholder", "Search...");
            input.addEventListener("keyup", function () {
                customSearch(i, this.value);
            });
            input.addEventListener("click", function (event) {
                event.stopPropagation();
            });
            headers[i].appendChild(input);
        }
    }
}

function customSearch(columnIndex, searchValue) {
    dataTable.columns(columnIndex).search(searchValue).draw();
}

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,672Questions: 1Answers: 10,098 Site admin

    Using column().search() should do it. I suspect it isn't working for you as you have a closure issue - the value of i is resolved only after the loop is complete - so it will be headers.length - not the index!

    What I would do in this case is:

    input.setAttribute('data-index', i);
    input.addEventListener("keyup", function () {
      var idx = input.getAttribute('data-index') * 1;
      customSearch(idx, this.value);
    });
    

    There are other ways such as using a closure function, but that's the one with the least changes to your code.

    If I ever interview for a Javascript job, this is almost exactly the question I ask candidates :). Its worth reading up on it as it is an important part of Javascript.

    Allan

  • Lorenzo00Lorenzo00 Posts: 12Questions: 2Answers: 0

    @allan thanks for the modification and and explanation. I made the changes to the code but it still doesn't seem to work.

    function setSearchingField() {
        if (!getParamsValue("SEARCH") && getParamsValue("COLUMNSSEARCH")) {
            const headers = document.getElementById("tblDataTable").getElementsByTagName("thead")[0].getElementsByTagName("th");
            for (let i = 0; i < headers.length; i++) {
                const input = document.createElement("input");
                input.setAttribute("type", "text");
                input.classList.add("w-100");
                input.setAttribute("placeholder", "Search...");
                input.setAttribute("data-index", i);
                input.addEventListener("keyup", function () {
                    var idx = input.getAttribute("data-index") * 1;
                    customSearch(idx, this.value);
                });
                input.addEventListener("click", function (event) {
                    event.stopPropagation();
                });
                headers[i].appendChild(input);
            }
        }
    }
    
  • allanallan Posts: 61,672Questions: 1Answers: 10,098 Site admin

    Can you give me a link to your page so I can take a look please?

    Allan

  • Lorenzo00Lorenzo00 Posts: 12Questions: 2Answers: 0

    @allan unfortunately i don't have the possibility to do that, the web application works to me only locally. if you want i'll share you all the frontend code, the problem is in sending the payload. In the formData.

  • allanallan Posts: 61,672Questions: 1Answers: 10,098 Site admin

    There is nothing immediately obvious from the code above. Try adding:

    console.log(columnIndex, searchValue);
    

    in your custom search function and see what is output on the console.

    Allan

  • Lorenzo00Lorenzo00 Posts: 12Questions: 2Answers: 0

    @allan I did some tests but could not come to a conclusion. When I run column.search(input.value).draw() should the input data be passed in payload automatically from datatable? I expect columns[1][search][value] to be compiled to then be processed server side. Isn't It?

  • kthorngrenkthorngren Posts: 20,282Questions: 26Answers: 4,767

    Did you use the console log statement Allan suggested?

    console.log(columnIndex, searchValue);
    

    What is the output?

    I copied most of your code into this test case and its working:
    https://live.datatables.net/wuvabetu/1/edit

    Debugging of your page will need to take place to track down the issue. I would place browser breakpoints on the first statement in both the setSearchingField() and customSearch() functions to step through the code. Or possibly use console log statements to verify the code flow and values you are expecting.

    If you need help with this please post a link to your page or a test case (update mine if you want) to show the issue.

    Kevin

  • Lorenzo00Lorenzo00 Posts: 12Questions: 2Answers: 0

    I found the problem, thank @allan and @kthorngren for the time you spent helping me.
    I had set search: false, which I thought only disabled searching via the default datatable label, but instead it disables you from searching at all.

  • kthorngrenkthorngren Posts: 20,282Questions: 26Answers: 4,767
    Answer ✓

    Good find. You can use the dom option to remove the global search input. Or, inside initComplete use jQuery to hide the elelment. Use the browser's inspect tool to find the selector to use.

    Kevin

Sign In or Register to comment.