How do I get the data of the current tab?

How do I get the data of the current tab?

JefryDJefryD Posts: 8Questions: 1Answers: 0

Hi friends, prepare this simple test case: http://live.datatables.net/becayaxu/1/edit

I have a table separated in several tabs, to separate them I use the answer of this discussion https://datatables.net/forums/discussion/26056/filtering-a-large-table-into-tabs it is something very simple, I set a "type" to the "tr" of the table and with that I show or hide them according to the selected tab.

I have a column "age",

     <thead>
              <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
              </tr>
     </thead>

I get all its values and sum them up showing it in the input "input-id",

<div>
      <h5>Age current tab: </h5>
      <input id="input-id"/>
</div>

but when I change tab, I don't sum up the values of the current tab. For example in tab Ait should be 245.

I know what my problem is, I get all the values and add them up,

$(document).ready( function () {
  var table = $('#example').DataTable({
    bInfo: false,
    bFilter: false,
    bSort:false,
    bPaginate:false,
    "scrollX": true,
    "paging": false,
    "scrollY": "500px",
    "drawCallback": function ( settings ) {
      var api = this.api();
      var rows = api.rows({page: 'current'}).nodes();

      var allage = api.column(3).data()
                    .each(function (value) {
                        return value;
                    });

      var age = Array.from(allage);

      var sumage = 0;

      for(let value of age){
        sumage += parseFloat(value) || 0;;
      }

      $('#input-id').val(sumage);

    }
  });

I know that my problem is in

var allage = api.column(3).data()
                    .each(function (value) {
                        return value;
                    });

how do I get only the visible values?

This question has accepted answers - jump to:

Answers

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

    The problem is that using .show() and .hide() to show/hide rows only changes the DOM display. Datatables doesn't know about these changes. Instead you will need to create a search plugin to show/hide the rows based on the row attribute. See this thread for information of how to access the row().node() in the plugin. From their you can use the row attributes to decide to show (return true) or hide (return false) each row.

    You may need to change the selector-modifier from {page: 'current'} to {search:'applied'} in drawCallback.

    Kevin

  • JefryDJefryD Posts: 8Questions: 1Answers: 0

    Hi, I made the changes you told me http://live.datatables.net/zavohiti/1/edit , I am no longer using api.column:

    var allage = api.column(3).data()
                        .each(function (value) {
                            return value;
                        }); 
    

    I am now using api.row and setting it to{search:'applied'}. The first thing I did was to create one more variable in the table which is going to be called group:

    <thead>
              <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
                <th>Group</th>
              </tr>
            </thead>
    

    this variable contains the groups set from 1 to 4, also to each element <tr> add a class with the same values from 1 to 4, for each element:

    <tr class="1" type="a">
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td>Edinburgh</td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$3,120</td>
                <td>1</td>
              </tr>
    

    Now I am also using the search plug-in and I am searching the data by row of the group:

    $.fn.dataTable.ext.search.push(
        function( settings, searchData, index, rowData, counter ) {
            var group = parseFloat( searchData[6] ) || 0; 
    
    
            var api = new $.fn.dataTable.Api( settings );
            var tr = api.row( counter ).node().classList[0];
            var cl = parseFloat( tr ) || 0;
    
            if((group == cl )){
              return true;
            }
    
            return false;
    
        }
    );
    

    When I get the class using row().node as you told me, if I get the class and match it to the group, but it doesn't work, it does filter but something important is missing.
    In the $.fn.dataTable.ext.search.push plug-in how do I call the ids of my tabs, I know now that it is not necessary to call the class of the <tr>, as I only need the tab id to compare it with the data of the group so I can show and hide according to the tab I select.

    I stress my question how do I call the ids of my tabs inside the search plugin?

    Thank you very much for the previous answer, it helped me a lot.

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

    Use settings.sTableId as shown by Allan in this thread.

    Kevin

  • JefryDJefryD Posts: 8Questions: 1Answers: 0

    I mean the id of my tabs (nav nav-tabs):

    <ul class="nav nav-tabs" role="tablist">
                <li class="active">
                    <a id="all" class="tab_button" href="#tab-table1" data-toggle="tab">ALL</a>
                </li>
                <li>
                    <a id="1" class="tab_button"href="#tab-table2" data-toggle="tab">A</a>
                </li>
                <li>
                    <a id="2" class="tab_button" href="#tab-table3" data-toggle="tab">B</a>
                </li>
                <li>
                    <a id="3" class="tab_button" href="#tab-table4" data-toggle="tab">C</a>
                </li>
                 <li>
                    <a id="4" class="tab_button" href="#tab-table5" data-toggle="tab">D</a>
                </li>
    </ul>
    
  • kthorngrenkthorngren Posts: 20,144Questions: 26Answers: 4,736
    edited November 2021 Answer ✓

    Looks like you are using Bootstrap tabs. Maybe use a global variable that you set when the tab is changed. See this SO thread for some options. Reference that global variable in the search plugin.

    Kevin

  • JefryDJefryD Posts: 8Questions: 1Answers: 0

    Thanks my friend, I can see the sum of each tab, http://live.datatables.net/vemikeju/1/edit

    var activeTab = null;
    
    $('a[data-toggle="tab"]').on('click', function (e) {
      activeTab = this.id;
    
    });
    
    
    
    $.fn.dataTable.ext.search.push(
        function( settings, searchData, index, rowData, counter ) {
            var group = parseFloat( searchData[6] ) || 0; 
            var idTab = parseFloat(activeTab) || 0; 
    
            if((group == idTab) || (idTab == "0")){
    
              return true;
            }
    
            return false;
    
        }
    );
    

    To show all the data, the tab all its id = 0, just match the idTab = 0 if it comes to touch that I return true, all because there are no values with 0 in the table.

    Thank you very much for your answers, you are a great help.

  • JefryDJefryD Posts: 8Questions: 1Answers: 0

    Hi, I am passing this code example to my project, but there is one thing, my datatable works server side serverSide: true, with this function activated the search plugin does not work anymore?

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

    That is true. The search plugin works with client side processing. With server side processing it is expected that the server script perform all the filtering.

    Do you need server side processing? In your test case you have "paging": false, which negates the paging functionality achieved with server side processing. If you have "paging": false, you might as well remove serverSide: true.

    With server side processing you could use ajax.data to pass the tab ID to the server and have the server script use that to update the table. See this example.

    Kevin

  • JefryDJefryD Posts: 8Questions: 1Answers: 0

    Is there not a way to manipulate the view according to a table field?

    For example I could group by the field "group". I have a field called "container" and I group it as follows:

    And I do it like this in the table:

    "drawCallback": function ( settings ) {
    
                    var last = null;
                    api.column(8, {page: 'current'}).data().each(function (group, i) {
                        if (last !== group) {
                            var name = null;
                            if (group == '1') {
                                name = 'Diseño'
                            } else if (group == '2') {
                                name = 'Carpintería y Pintura'
                            } else if (group == '3') {
                                name = 'Soldadura'
                            } else if (group == '4') {
                                name = 'Electricidad'
                            } else if (group == '5') {
                                name = 'Impresiones, Cortes y Pegados'
                            } else if (group == '6') {
                                name = 'Instalación y Desinstalación'
                            } else if (group == '7') {
                                name = 'Otros'
                            } else if (group == '8') {
                                name = 'Horas Extras'
                            }
    
                            $(rows).eq(i).before(
                                '<tr class="group" style="background-color: #ddd !important;"><td colspan="10">' + name + '</td></tr>'
                            );
    
                            last = group;
                        }
                    });
    

    The view of my project is in Spanish, sorry.

    The point is that I can group the data with a field, so is there a way to group them and show them in tabs (nav-tabs)?

    That is to say to be able to call the id of a tab inside the function drawCallback and to make that the group selected by that id is shown?

    It would be something like:

     "drawCallback": function ( settings ) {
    
       $('a[data-toggle="tab"]').on('click', function (e) {
           idTab= this.id;
            api.column(9, {page: 'current'}).data().each(function (group, i) {
                            if (last !== group) {
    
                                 if(group == idTab){
                                       $(this).tab('show');                                   
                                       // Here add to show only those data grouped in one tab
                                      // Depending on the selected tab
                                     }                                  
    
                            }
    
         });
    }
    

    Could this be a solution?

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

    Take a look at the RowGroup extension. Sounds like this is exactly what you describe.

    Kevin

  • JefryDJefryD Posts: 8Questions: 1Answers: 0

    Hello, do you know how to hide those that are not groups?

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

    You could remove those rows as they come in from the Ajax data, or later when making the groups. It depends really on what a "no group" is - as technically that could still be a group!

    Cheers,

    Colin

  • JefryDJefryD Posts: 8Questions: 1Answers: 0

    Hello, I end this discussion with the following information, the best way to show by groups is the one in this thread: https://datatables.net/forums/discussion/65968/dynamic-idisplaylength-row-group-items#Comment_183782

    It was everything I needed, with a little tweaking. The search plugin doesn't work with the serverSide true, so I used a column filter to search the data.

    Before:

    var select = $('<select></select>')
            .appendTo( $('div.group-selector').empty() )
            .on( 'change', function () {
              var dataSrc = api.rowGroup().dataSrc();
    
              api.groupSearch($(this).val(), dataSrc).draw();
            });
    

    After:

    var select = $('<select class="form-select col-md-2" ></select>')
                        .appendTo( $('div.group-selector').empty() )
                        .on( 'change', function () {
                            api.column(9).search($(this).val()).draw();
                        });
    

    With that change, it worked correctly, of course I did not use the search plugin, everything else I kept.

    Thank you very much for your comments and support.

Sign In or Register to comment.