Hide Column Search Boxes

Hide Column Search Boxes

arosnerarosner Posts: 35Questions: 8Answers: 1

I am developing an ASP.NET MVC application and would like to hide the search boxes for columns that should not be searchable.

I include the following css CDNs
<link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.8.3.js"></script>
<link href="@Url.Content("https://cdn.datatables.net/2.0.3/css/dataTables.dataTables.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("https://cdn.datatables.net/fixedheader/3.4.0/css/fixedHeader.dataTables.min.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("https://cdn.datatables.net/buttons/3.0.1/css/buttons.dataTables.css")" rel="stylesheet" type="text/css" />

I include the following js CDNs

<script src="/Scripts/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.2/umd/popper.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/fixedheader/3.4.0/js/dataTables.fixedHeader.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/2.0.3/js/dataTables.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/3.0.1/js/dataTables.buttons.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/3.0.1/js/buttons.dataTables.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/3.0.1/js/buttons.html5.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/3.0.1/js/buttons.print.min.js"></script>

In the column definitions, the columns that should not be searchable are marked searchable: false

    function bindDatatableBPCouncilSearch() {
        $('#tableDataBPCouncilSearch thead tr').clone(true).addClass('filters').appendTo('#tableDataBPCouncilSearch thead');
        datatable = $('#tableDataBPCouncilSearch')
            .DataTable({
                "orderCellsTop": true,
                "fixedHeader": true,
                "processing": true, // for show progress bar
                "serverSide": false, // for process server side
                "filter": true, // this is to enable filter (search box)
                "pageLength": 25,
                "layout": {
                    "topEnd": null, //remove generic search box
                    "topStart": {
                        "buttons": [
                            {
                                "extend": "csvHtml5",
                                "footer": false,
                                "exportOptions": {
                                    "columns": [3, 4, 5, 6, 7, 8],
                                    "customizeData": function (data) {
                                        data.headerStructure.pop();
                                        },
                                },
                            },
                            'colvis'
                        ]
                    }
                },
                "ajax": {
                    "url": "/Home/LoadBPCouncilSearch",
                    "type": "POST",
                    "datatype": "json"
                },
                "language": {
                    "emptyTable": "No record found.",
                    "processing":
                        '<i class="fa fa-spinner fa-spin fa-3x fa-fw" style="color:#2a2b2b;"></i><span class="sr-only">Loading...</span> '
                },
                initComplete: function () {
                    var api = this.api();
                    // For each column
                    api.columns().eq(0).each(function (colIdx) {
                        // Set the header cell to contain the input element
                        var cell = $('.filters th').eq($(api.column(colIdx).header()).index());
                        var title = $(cell).text();
                        $(cell).html('<input type="text" placeholder="' + title + '" />');
                        // On every keypress in this input
                        $('input', $('.filters th').eq($(api.column(colIdx).header()).index()))
                            .off('keyup change')
                            .on('keyup change', function (e) {
                                e.stopPropagation();
                                // Get the search value
                                $(this).attr('title', $(this).val());
                                var regexr = '({search})'; //$(this).parents('th').find('select').val();
                                var cursorPosition = this.selectionStart;
                                // Search the column for that value
                                api
                                    .column(colIdx)
                                    .search((this.value != "") ? regexr.replace('{search}', '(((' + this.value + ')))') : "", this.value != "", this.value == "")
                                    .draw();
                                $(this).focus()[0].setSelectionRange(cursorPosition, cursorPosition);
                            });
                    });
                },
                "columns": [
                    {
                        "data": "PROJECT",
                        "autoWidth": true,
                        "searchable": false,
                        "visible": false
                    },
                    {
                        "data": "POLBORO",
                        "autoWidth": true,
                        "searchable": false,
                        "visible": false
                    },
                    {
                        "data": "MAYRLCAT",
                        "autoWidth": true,
                        "searchable": false,
                        "visible": false
                    },
                    {
                        "data": "SUBNO",
                        "autoWidth": true,
                        "searchable": true,
                    },
                    {
                        "data": "PROJECTTYPE",
                        "autoWidth": true,
                        "searchable": true,
                    },
                    {
                        "data": "PROJECTTITLE",
                        "autoWidth": true,
                        "searchable": false,
                    },
                    {
                        "data": "SPONSORS",
                        "autoWidth": true,
                        "searchable": false,
                    },
                    {
                        "data": "AGREEDSTATUS",
                        "autoWidth": true,
                        "searchable": true,
                    },
                    {
                        "data": "LASTUPDATE",
                        "autoWidth": true,
                        "searchable": true,
                    },
                    {
                        "data": null,
                        "searchable": false,
                        render: function (data, type, row) {
                            return '<a href="/Home/EditBPCouncil?project=' + row.PROJECT + '&polBoro=' + row.POLBORO + '&category=' + row.MAYRLCAT + '" target="_blank">Edit</a>';
                        }
                    },
                ]
            });
    }

The columns with searchable: false still have textboxes under the headers.

This question has an accepted answers - jump to answer

Answers

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

    See if this thread helps.

    Kevin

  • arosnerarosner Posts: 35Questions: 8Answers: 1

    Looks like I need to modify the InitComplete property. Not sure how.

  • allanallan Posts: 63,538Questions: 1Answers: 10,476 Site admin

    DataTables doesn't have a column().searchable() method to be able to tell if a column is searchable or not. Maybe it should...

    What I would suggest you do as add a class of "searchable" (or whatever you want) to all columns that you want to be searchable, and then use:

    api.columns('.searchable').eq(0).each(function (colIdx) {
    

    to have the text input element added only on those columns (note the use of .searchable as the column-selector.

    Allan

  • arosnerarosner Posts: 35Questions: 8Answers: 1
                    initComplete: function () {
                        var api = this.api();
                        // For each column
                        api.columns().eq(0).each(function (colIdx) {
                            // Set the header cell to contain the input element
                            var cell = $('.filters th').eq($(api.column(colIdx).header()).index());
                            var title = $(cell).text();
                            api.columns('.searchable').eq(0).each(function (colIdx) {
                                $(cell).html('<input type="text" placeholder="' + title + '" />');
                            });
                            // On every keypress in this input
                            $('input', $('.filters th').eq($(api.column(colIdx).header()).index()))
                                .off('keyup change')
                                .on('keyup change', function (e) {
                                    e.stopPropagation();
                                    // Get the search value
                                    $(this).attr('title', $(this).val());
                                    var regexr = '({search})'; //$(this).parents('th').find('select').val();
                                    var cursorPosition = this.selectionStart;
                                    // Search the column for that value
                                    api
                                        .column(colIdx)
                                        .search((this.value != "") ? regexr.replace('{search}', '(((' + this.value + ')))') : "", this.value != "", this.value == "")
                                        .draw();
                                    $(this).focus()[0].setSelectionRange(cursorPosition, cursorPosition);
                                });
                        });
                    },
    
    <thead>
        <tr>
            <th>PROJECT</th>
            <th>POLBORO</th>
            <th>MAYRLCAT</th>
            <th class="searchable">SUB NO</th>
            <th class="searchable">PROJ TYPE</th>
            <th>PROJ TITLE</th>
            <th>SPONSOR(s)</th>
            <th class="searchable">AGREED</th>
            <th>LAST UPDATED</th>
            <th>ACTION</th>
        </tr>
    </thead>
    

    I am seeing a console error:

    ncaught TypeError: Cannot set properties of undefined (setting 'FixedHeader')

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

    Looks like you are loading fixheader.js before datatables.js. I'm guessing fixedheader.js requires datatables.js to be loaded first or it won't load correctly. Swap the two statements.

    To help debug we will need to see the issue. If swapping the statements doesn't help then please provide a link to a test case replicating the issue.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • arosnerarosner Posts: 35Questions: 8Answers: 1

    Hi Kevin,

    Switching the js cdn declarations removed the fixedheader error.

    I don't think I am implementing Allan's suggestion correctly and would appreciate help.

    As I mentioned earlier, I added a searchable class to the desired header. For example,

       <th class="searchable">SUB NO</th>
    

    I added debugging to the javascript snippet below:

                            api.columns('.searchable').eq(0).each(function (colIdx) {
                                console.log("title=" + title);
                                if (title == "SUB NO")
                                    $(cell).html('<input type="text" placeholder="' + title + '" />');
                                else
                                    $(cell).html('<label/>');
                            });
    

    The result is visually what I am looking for.

    The issue is that the loop executes for all header items whether they contain the searchable class or not. I would like eq(0) to return header elements without the searchable class and eq(1) to return header elements with the searchable class. The desired code should look like:

                            api.columns('.searchable').eq(0).each(function (colIdx) {
                                    $(cell).html('<label/>');
                            });
                            api.columns('.searchable').eq(1).each(function (colIdx) {
                                    $(cell).html('<input type="text" placeholder="' + title + '" />');
                            });
    

    If there is a simpler solution by writing code that enables the setting of the searchable property in the columns array, that would suffice as well. For example,

                    "columns": [
                        {
                            "data": "PROJECT",
                            "autoWidth": true,
                            "searchable": false,
                        },
    

    Thank you!

  • arosnerarosner Posts: 35Questions: 8Answers: 1

    This solution is working:

                            // Set the header cell to contain the input element
                            var cell = $('.filters th').eq($(api.column(colIdx).header()).index());
                            var title = $(cell).text();
    
                            $('tr:eq(1) th', api.table().header()).each(function (i) {
                                if ($(cell).hasClass('searchable')) {
                                    $(cell).html('<input type="text" placeholder="' + title + '" />');
                                }
                                else { 
                                    $(cell).html('<label/>');
                                }
                            });
    

    The case can be closed.

    Thank you!

  • kthorngrenkthorngren Posts: 21,344Questions: 26Answers: 4,954
    Answer ✓

    Take a look at this example from the thread I linked to earlier. It checks the class of the column to. see if the search input should be appleid.

    If there is a simpler solution by writing code that enables the setting of the searchable property in the columns array

    Now that you mention it I remember this example that checks if the column is searchable. It registers its own custom column().searchable() API.
    https://live.datatables.net/cusologu/7/edit

    Both examples use select lists but you can use the search inputs or a mixture of both.

    Kevin

Sign In or Register to comment.