Search code examples
javascriptjquerydatatable

Datatable custom filter to remove rows with duplicate data on button click


I am creating a comparison table and want to be able to hide all of the rows in a datatable that have the same column 2 & and column 3 value. I have created a custom button that runs the below js:

action: function ( e, dt, node, config ) {                           
   var rows = $("#compare").find("tbody tr"); //find all rows

   rows.each(function() {
     var thisRow = $(this),
     value1 = thisRow.find("#1"),
     value2 = thisRow.find("#2");

     if(value1.text() == value2.text()){
       thisRow.hide();
     }

   });
}

This does hide the rows on the current dataTable page that are duplicates, but still shows 10 results for that page even though all 10 are hidden. I read a few other questions, most of the answers recommended that a custom filter be applied to the rows due to serverside paging?

I would like the button to regenerate the table with only values where value1 !== value2, so if there are 25 results and 20 of them are duplicates, the table would be reloaded with showing results 1 to 5 of 5 entries.

datatable creation ->

success: function(data){
        var Table = document.getElementById("compare");
        Table.innerHTML = "";
        $("#compare").append(data);
        $("#compare").DataTable({
            dom: 'Bfrtip',                
            buttons: [
                {
                    text: 'My button',
                    action: function ( e, dt, node, config ) {                           
                        
                        var rows = $("#compare").find("tbody tr"); //find all rows

                        rows.each(function() {
                            var thisRow = $(this),
                            value1 = thisRow.find("#1"),
                            value2 = thisRow.find("#2");

                            if(value1.text() == value2.text()){
                                $(this).hide();
                            }

                        });

                        //$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
                        //    return table.row(dataIndex).nodes().to$().attr('excluded') != 'true'
                        //})
                        
                        
                    }
                }
            ]
        });

    }

Solution

  • As @charlietfl already told you, you should go for the jQuery DataTable filter approach.

    Something like this:

    var table = $('#example').DataTable({
        ordering: false
    });
    
    $.fn.dataTableExt.afnFiltering.push(function(settings, data, dataIndex) {
        
         if(data[2] == data[3])
            return false;
         else
            return true;
    });
    
    function removeDuplicates() {
       table.draw();
    }
    <link href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" rel="stylesheet"/>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
    
    <button onclick="removeDuplicates()">Remove Duplicates</button>
    <br><br>
    <table id="example" class="display" style="width: 100%;">
        <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Age 1</th>
                <th>Age 2</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Angelica Ramos</td>
                <td>Chief Executive Officer (CEO)</td>
                <td>47</td>
                <td>47</td>
            </tr>
            <tr>
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td>61</td>
                <td>42</td>
            </tr>
            <tr>
                <td>Garrett Winters</td>
                <td>Accountant</td>
                <td>63</td>
                <td>28</td>
            </tr>
            <tr>
                <td>Ashton Cox</td>
                <td>Junior Technical Author</td>            
                <td>66</td>
                <td>66</td>
            </tr>
            <tr>
                <td>Bradley Greer</td>
                <td>Software Engineer</td>
                <td>41</td>
                <td>20</td>
            </tr>
            <tr>
                <td>Dai Rios</td>
                <td>Personnel Lead</td>
                <td>35</td>
                <td>37</td>
            </tr>
            <tr>
                <td>Jenette Caldwell</td>
                <td>New York</td>
                <td>30</td>
                <td>30</td>
            </tr>
            <tr>
                <td>Yuri Berry</td>
                <td>Chief Marketing Officer (CMO)</td>
                <td>40</td>
                <td>27</td>
            </tr>
            <tr>
                <td>Caesar Vance</td>
                <td>Pre-Sales Support</td>
                <td>21</td>
                <td>22</td>
            </tr>
            <tr>
                <td>Doris Wilder</td>
                <td>Sales Assistant</td>
                <td>23</td>
                <td>23</td>
            </tr>
        </tbody>
    </table>