Hide / Show columns doesn't take into account my second "tr" header

Hide / Show columns doesn't take into account my second "tr" header

yinyangyinyang Posts: 25Questions: 3Answers: 0
edited August 2020 in Free community support

Hi,

I added to my datatable a second tr in my header, to be able to add a search field for each column. (I didn't want it down in the footer.) Everything works perfectly fine. I then implemented the 'columnsToggle' to be able to see / hide columns. It also works, except ... it doesn't take my research cell into consideration. Let me explain: if I hide the status, it removes the status column, but not the associated search field! So it gives me a shift on the other columns ...

Screenshot of my table :

Then when I click on "Statut" :

As you can see, the "status" column has disappeared but not the associated empty cell ... and suddenly my "title" column now has the associated empty field instead of its search field.

Here is my code :

<script>
    $('#events').initDataTables({{ datatable_settings(datatable) }}, { 
        processing: true,
        serverSide: true,
        searching: true, 
        ordering: false,
        searchDelay: 200,
        dom: 'Bfrtip',
        buttons: [
            {
                text: 'Réinitialiser',
                action: function (e, dt, node, config) {
                    location.reload();
                }
            },
            {
                "extend": 'columnsToggle',
                "columns": [0, 1, 2, 3, 4, 5, 6, 7, 8]
            }
        ],
        initComplete: function(settings, json) {
            var api = this.api();
            var recordsTotal = api.context[0].fnRecordsTotal();
            $('#events_list h5 span').text(recordsTotal);

            // Create tr filter
            var tr = $('<tr id="filter_search"></tr>');
            // Count number of cells in a row
            var nbCells = document.getElementById('dt').rows[0].cells.length;
            // Generate cells to #filter_search row 
            for (var i = 0; i < nbCells; i++) {
                if (i == 1 || i == 7 || i == 9) {
                    tr.append('<th></th>');
                } else {
                    tr.append('<th><input type="search" onclick="stopPropagation(event);" placeholder="Rechercher"></th>');
                }

            }

            var firstHeaderRow = $('tr', api.table().header());
            tr.insertAfter(firstHeaderRow);

            $("#filter_search input").on('keyup change', function(e) {
                if (e.keyCode == 13) {
                    api
                        .column($(this).parent().index()+':visible')
                        .search(this.value)
                        .draw();
                }
            });
        },
        drawCallback: function(settings) {
            var api = this.api();
            var info = api.page.info();
            var recordsDisplay = info.recordsDisplay;
            $('#events_list h5 span').text(recordsDisplay);
        },
        language: {
            emptyTable:     "Aucune donnée disponible",
            info:           "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
            infoEmpty:      "Affichage de 0 à 0 sur 0 entrées",
            infoFiltered:   "(filtré de _MAX_ entrées au total)",
            lengthMenu:     "Affichage de _MENU_ entrées",
            loadingRecords: "Chargement...",
            processing:     "En traitement...",
            search:         "Recherche : ",
            searchPlaceholder: "Chercher un id, un titre, une ville, ...",
            zeroRecords:    "Aucun enregistrements correspondants trouvés",
            paginate: {
                first:      "Premier",
                last:       "Dernier",
                next:       "Suivant",
                previous:   "Précédent"
            },
        }
    });

    function stopPropagation(evt) {
        if (evt.stopPropagation !== undefined) {
            evt.stopPropagation();
        } else {
            evt.cancelBubble = true;
        }
    }
</script>

I use Symfony DataTables Bundle from Omines.

The table is generated automatically via this bundle.

Here is the html structure :

Replies

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • kthorngrenkthorngren Posts: 20,144Questions: 26Answers: 4,736

    Sounds like you need to do something like the suggestion in this thread.

    Kevin

  • yinyangyinyang Posts: 25Questions: 3Answers: 0
    edited August 2020

    I try on live.datatables.net : http://live.datatables.net/nurupese/2/edit

    But I cannot reproduce my example above...

  • yinyangyinyang Posts: 25Questions: 3Answers: 0

    Hi @kthorngren,

    I adapted the example of the link you gave me, but it always shifts my fields without taking into account my search input ...

    The "statut" column is hidden, the "titre" column has shifted to the left but not its search field ... (with the value "test" inside)

    My code :

    processing: true,
    serverSide: true,
    searching: true, 
    ordering: false,
    searchDelay: 200,
    dom: 'Bfrtip',
    buttons: [
        {
            text: 'Réinitialiser',
            action: function (e, dt, node, config) {
                location.reload();
            }
        },
        {
            "extend": 'columnsToggle',
            "columns": [0, 1, 2, 3, 4, 5, 6, 7, 8]
        }
    ],
    initComplete: function(settings, json) {
        var api = this.api();
        var recordsTotal = api.context[0].fnRecordsTotal();
        $('#events_list h5 span').text(recordsTotal);
    
        // Create tr filter
        var tr = $('<tr id="filter_search"></tr>');
        // Count number of cells in a row
        var nbCells = document.getElementById('dt').rows[0].cells.length;
        // Generate cells to #filter_search row 
        for (var i = 0; i < nbCells; i++) {
            // if (i == 1 || i == 7 || i == 9) {
            //     tr.append('<th></th>');
            // } else {
            //     tr.append('<th class="filterhead"></th>');
            // }
            tr.append('<th class="filterhead"></th>');
        }
    
        var firstHeaderRow = $('tr', api.table().header());
        tr.insertAfter(firstHeaderRow);
    
        $('.filterhead', api.table().header()).each(function(i) {
            var column = api.column(i);
            var input = $('<input type="search" onclick="stopPropagation(event);" placeholder="Rechercher">')
                .appendTo($(this).empty())
                .on('keyup change', function(e) {
                    if (e.keyCode == 13) {
                        column
                            .search(this.value)
                            .draw();
                    }
                });
        });
    },
    
  • yinyangyinyang Posts: 25Questions: 3Answers: 0

    In the end I opted for this solution in the initComplete:

    $('.buttons-columnVisibility').each(function(index, element) {
                    $(element).click(function() {
                        if (api.column(index).visible() === true) {
                            $('#filter_search th').eq(index).show();
                        } else {
                            $('#filter_search th').eq(index).hide();
                        }
                    });
                });
    

    I think there is less complicated, if anyone has an idea

This discussion has been closed.