How to auto-resize width of DataTable after hide column/add filter?

How to auto-resize width of DataTable after hide column/add filter?

pansengtatpansengtat Posts: 66Questions: 26Answers: 1
edited September 2014 in DataTables 1.10

I have read some previous threads in the DataTables forums about how to prevent auto-resizing or manually resizing columns of a table after adding filters or hiding some columns. (Example thread: https://datatables.net/forums/discussion/20575/resize-columns-issue) However, with regards to the question that I am about to post, I tried using sScrollX, bAutoResize, and columns().adjust().draw, but using all of these either don't seem to set the width of the table to fit the width of the browser, or simply cause the filters to disappear at the footer.

Is there a way to force the width of the entire table to automatically-fit the width of the browser, after placing the filters and then hiding targeted columns?

Here are my codes used for attempting to both create filters and then hide columns:

Front-end:

<script type="text/javascript" language="javascript" charset="utf-8" src="js/jquery.min.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8" src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8" src="js/jquery.dataTables.min.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8" src="js/dataTables.tableTools.min.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8" src="js/dataTables.editor.min.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8" src="js/PlanEditor.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8" src="js/PlanEditor_DateRange.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8" src="js/cookie-plugin.js"></script>

<link rel="stylesheet" type="text/css" href="css/style.css" media="all">
<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="css/dataTables.tableTools.css">
<link rel="stylesheet" type="text/css" href="css/dataTables.editor.css">

<script type="text/javascript">
$(document).ready(function(){
          $('#plan').DataTable();
} );
</script>
...
<div class="dashboard">
    <table border="0" cellspacing="1" cellpadding="1">
        <tbody>
            <tr>
                <td>Starting Date:</td>
                <td><input type="text" id="date_starting" name="date_starting"></td>
                </tr>
                <tr>
                <td>Ending Date:</td>
                <td><input type="text" id="date_ending" name="date_ending"></td>
                </tr>
        </tbody>
    </table>
    <table id="plan" class="display dataTable" role="grid" width="100%" cellspacing="0">
    <?php
        echo "<thead>
                <tr>
                    <th>...</th>
                    ...
                </tr>
                </thead>
                <tbody></tbody>
                <tfoot>
                    <tr>
                        <th></th>
                        ...
                    </tr>
                </tfoot>";
    ?>
    </table>
</div>
...

External JS file "PlanEditor_DateRange.js":

$.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {
        if ($('#date_starting').val() == '' && $('#date_ending').val() == '') {
            return true;
        }

        if ($('#date_starting').val() != '' || $('#date_ending').val() != '') {
            var iMin_temp = $('#date_starting').val();
            
            if (iMin_temp == '') {
                iMin_temp = '01/01/2014';
            }
            
            var iMax_temp = $('#date_ending').val();
            
            if (iMax_temp == '') {
                iMax_temp = '31/12/2999';
            }
            
            var arr_min = iMin_temp.split("/");
            var arr_max = iMax_temp.split("/");

            // aData[column with dates]
            // 9 is the column where my dates are. Just replace it according to your needs. First column is 0.
            var arr_date = aData[9].split("-");                                         // Dates pulled from the database are in the format yyyy-mm-dd (separated by dashes)
            var iMin = new Date(arr_min[2], arr_min[0], arr_min[1], 0, 0, 0, 0);        // arr_min[2] = yyyy,   arr_min[0] = mm,    arr_min[1] = dd
            var iMax = new Date(arr_max[2], arr_max[0], arr_max[1], 0, 0, 0, 0);        // arr_max[2] = yyyy,   arr_max[0] = mm,    arr_max[1] = dd
            var iDate = new Date(arr_date[0], arr_date[1], arr_date[2], 0, 0, 0, 0);    // arr_date[0] = yyyy,  arr_date[1] = mm,   arr_date[2] = dd
            
            if ( iMin == "" && iMax == "" )
            {
                return true;
            }
            else if ( iMin == "" && iDate < iMax )
            {
                return true;
            }
            else if ( iMin <= iDate && "" == iMax )
            {
                return true;
            }
            else if ( iMin <= iDate && iDate <= iMax )
            {
                return true;
            }
            return false;
        }
    }
);

PlanEditor.js

var editor;

(function ($) {
    $(document).ready(function () {
        editor = new $.fn.dataTable.Editor( 
        {
            ajax: "php/PlanEditor.php",
            table: "#plan",
            fields: [...],
            i18n: 
            {   edit: {title:  "Plan"}
            }
        } );
        
        var table = $('#plan').DataTable( 
        {
            dom: "Tfrtip",
            ajax: "php/PlanEditor.php",
            columns: [...],
            "order": [[ 2, "desc" ]],
            tableTools: 
            {
                sRowSelect: "os",
                sSwfPath: "extensions/tabletools/swf/copy_csv_xls_pdf.swf",
                aButtons: 
                [
                    {   
                        sExtends:       "editor_edit",   
                        editor:         editor,
                        sButtonText:    "Plan"
                    },
                    {   
                        sExtends:       "xls",
                        sButtonText:    "Export as Excel",
                        sAction:        "flash_save"
                    },
                    {   
                        sExtends:       "csv",
                        sButtonText:    "Export as CSV",
                        sAction:        "flash_save"
                    },
                    {   
                        sExtends:       "pdf",
                        sButtonText:    "Export as PDF",
                        sPdfOrientation:"landscape"
                    },
                    "print"
                ]
            },
            "deferRender": true,
            initComplete: function(settings, json) 
            {
                editor.field('Plan.Approval').update(json.ApprovalMirror);
            }
        } );

        $(function() {
            $( "#date_starting" ).datepicker();
        });

        $(function() {
            $( "#date_ending" ).datepicker();
        });
        $('#date_starting').change( function() { table.draw(); } );
        $('#date_ending').change( function() { table.draw(); } );
        
        setTimeout(function() {
            $("#plan tfoot th").each( function ( i ) 
            {
                {
                    if (table.column(i).visible() === true)
                    {
                        var select = $('<select><option value=""></option></select>')
                            .appendTo( $(this).empty() )
                            .on( 'change', function () 
                            {
                                var val = $(this).val(); 
                 
                                table.column( i )
                                    .search( val ? '^'+$(this).val()+'$' : val, true, false )
                                    .draw();
                            } );
                        table.column( i ).data().unique().sort().each( function ( d, j ) 
                        {
                            select.append( '<option value="'+d+'">'+d+'</option>' );
                        } );
                    }
                }
            } );
            table.column(0).visible(false);
            table.column(1).visible(false);
            table.column(14).visible(false);
            table.column(17).visible(false);
            table.column(19).visible(false);
        }, 1);
    } );
}(jQuery));

This question has accepted answers - jump to:

Answers

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Answer ✓

    Is there a way to force the width of the entire table to automatically-fit the width of the browser

    Add width="100%" to your <table> tag.

    Allan

  • pansengtatpansengtat Posts: 66Questions: 26Answers: 1
    edited September 2014

    Add width="100%" to your <table> tag.

    Umm, @allan, that was already inside the code that I showed inside the Front End section of my post.

    The reason I asked is that despite doing that, the DataTable instance somehow managed to stretch the table across to the right side of the screen after triggering setTimeout(function() {}, 1); in the $(document).ready(function () {}) section, (if you have seen the code in the PlanEditor.js section, you will notice that that is where I placed the calls to add the filters and then hide columns after the document is finished loading. That might explain why the table itself is stretching to the right side, despite it being initially already fitting the browser width.)

    So I am thinking aloud if immediately after triggering setTimeout(function() {}, 1);, what jQuery calls/changes to the DataTable() instance is required to re-adjust the width?

    I circumvented this issue using the following modification on the way select is initialized, but this is not-so-elegant, because this causes the filters populating the footer to sometimes not show its options (I actually had to open F12 Dev Tools in Chrome, click Hard Reload to force correct loading; other browsers like FF and IE refuse to show the filters after making the modification to select):

    setTimeout(function() {
    $("#Plan tfoot th").each( function ( i ) 
        {
        //--- Rest of code is same except this next line ---//
        var select = $('<select style="width: 60px;"><option value=""></option></select>')
    ...
    
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Sorry - i was looking at the wrong table tag, which doesn't have it.

    I think I would need a link to a test page showing the issue to be able to offer any help.

    Allan

  • pansengtatpansengtat Posts: 66Questions: 26Answers: 1

    I am using JSFiddle, I was in a rush so I wasn't able to clean up the code to separate the PHP parts from the HTML parts inside this JSFiddle link (but all the code I used are inside that link): http://jsfiddle.net/pansengtat/vn7mjcz3/

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Answer ✓

    I'm afraid you are going to have to explain a little bit about your fiddle for me - specifically what actions I need to take in order to recreate the issue so I can see it myself.

    The table doesn't fit into the viewport when I start up the link simply from the fact that it can't. There is too much data in it to be visible without scrolling.

    Allan

  • pansengtatpansengtat Posts: 66Questions: 26Answers: 1

    I am not sure how to extract or explain in simple terms as much of the code was a mix of PHP and HTML, however I suspected that the reason it was not producing the correct behaviour was because I set the time in setTimeOut() function in the jQuery script to be too small.

    My workaround/hack is by increasing the time to around 2 or more seconds, the code that executes the filter creation will be delayed and allow time to resize the DataTable container accordingly.

This discussion has been closed.