Confusion on how to search column data instead of rendered output

Confusion on how to search column data instead of rendered output

Chilly TeeChilly Tee Posts: 3Questions: 1Answers: 0

I have a table column that is rendered to display no more than 30 characters from its data source. I have a footer for each table column that does a search in its column as the user types in the search term. What I have found is that the search is performed on the rendered values in the column instead of the underlying data.

The code is on an intranet, so I can't provide a link. Here are some code snippets of the table initialization, column definitions, footer input definitions, and footer listener code (there may be typos). The column of specific interest is column 1 (Item Title):

``` // part of the table initialization
var iTable = $('#portalItemTable').DataTable({
'autoWidth': true,
'data': data,
'order': [[3, 'asc'], [4, 'asc'],
'columns': [
{'title': 'Item ID', 'data': 'ItemId', 'render': function (data, type, row) { return returnPortalUserItemLink(data, type, row); } }, // a function that creates a hyper link to the item's details in another web site
{'title': 'Item Title', 'data': 'ItemTitle', 'render': function (data, type, row) { return formatPortalUserItemTitle(data, type, row, 30); } }, // a function that takes the column data and truncates it with an ellipsis if the data is more than 30 characters; function code is below
{'title': 'Item Type', 'data': 'ItemType', },
...
{'title': 'Row ID', 'data': rid}
],
'columnDefs': [
{'targets': 0, 'searchable': false, 'width': '110px' },
{'targets': 1, 'createdCell': function (td, cellData, rowData, row, col) {
if (cellData.length > 30) td.title = cellData; } },
...
$('.dataTables_scrollFoot tfoot th').each(function (idx) {
if (idx > 0) { // first column doesn't need an input footer
$(this).html('<input class = "srchFtr" type = "text" if = "ftr' + idx + '" placeholder="Search ' + $(this).text() + '" />');
}
});

iTable.columns().each(function () {
$('.srchFtr', this.footer()).on('keyup change', function () {
var idx = this.id.substring(3);
var srchCol = $('#portalItemTable').DataTable().columns(idx);
if (srchCol.search() !== this.value) {
srchCol.search(this.value).draw();
}
});
});
...

// function to format item title for display
function formatPortalUserItemTitle(data, type, row, titleLength) {
if (data) {
return data.length > titleLength ? data.substring (0, (titleLength - 3)) + '...' : data;
}
}
```

In the portion of the code where I init the event listener for each column footer, I have tried the following:
srchCol.cache().search(this.value).draw()
- and also -
srchCol.data().search(this.value).draw()

When I tried those, whenever I typed in a search term in any column footer, the same term would appear in the table's search input box, which of course would perform a search on the entire table.

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,393Questions: 26Answers: 4,786
    Answer ✓

    You will want to update your render function to use "orthogonal" data as described here:
    https://datatables.net/manual/data/orthogonal-data

    I think you will only want to render if it of type "display", something like this:

    'render': function (data, type, row) { 
        if (type === 'display') {
          return formatPortalUserItemTitle(data, type, row, 30); 
        }
    } 
    

    The original data will then be used for searching and sorting.

    Kevin

  • Chilly TeeChilly Tee Posts: 3Questions: 1Answers: 0

    I had to move the comparison into the 'formatPortalUserItemTitle' function to get it to work, but it works.

  • Chilly TeeChilly Tee Posts: 3Questions: 1Answers: 0

    I had to move the comparison into the 'formatPortalUserItemTitle' function to get it to work, but it works.

This discussion has been closed.