Is it possible to enable horizontal scrolling if filters are used at the Table's bottom?

Is it possible to enable horizontal scrolling if filters are used at the Table's bottom?

pansengtatpansengtat Posts: 66Questions: 26Answers: 1
edited March 2015 in Editor

I have some code carried over from the previous year and it seems to be working all fine.
However, recently a feature request was placed to have horizontally-scrolling for a Datatables/Editor instance, so naturally I used "scrollX": true as part of my DataTable variable. Unfortunately, there is code interrupting this that requires to create input filters dynamically onto the footer of the DataTable.

As such, I will post the code that includes the input filter creation via JavaScript as follows:

var table = $('#myWebPage').DataTable({
    dom: "Tflrtip",
    ajax: "php/myEditor.php",
    columns: [
        { data: "myTable.myColumn" },
        // Include all data columns
    ],
    "order": [[ 0, "desc" ]],
    tableTools: {
        sRowSelect: "os",
        sSwfPath: "extensions/tabletools/swf/copy_csv_xls_pdf.swf",
        aButtons: [
            {
                sExtends:        "editor_edit",
                editor:          editor,
                sButtonText:     "Make arrangements"
            }, {
                sExtends:        "xls",
                sButtonText:     "Export as Excel",
                sAction:         "flash_save",
                // This indicates whether you want to export all data or only currently-selected data.
                "oSelectorOpts": {
                    page: 'current'
                },
                // This indicates which columns do you wish to be visible when exported.
                "mColumns": [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18 ]
            }, {
                sExtends:        "pdf",
                sButtonText:     "Export as PDF",
                sPdfOrientation: "landscape",
                // This indicates whether you want to export all data or only currently-selected data.
                "oSelectorOpts": {
                    page: 'current'
                },
                // This indicates which columns do you wish to be visible when exported.
                "mColumns": [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18 ]
            },
            "print", {
                sExtends:        'select_single',
                sButtonClass:    'marginLeft',
                sButtonText:     'Approve Arrangement',
                fnClick: function () {
                    if (table.row('.selected').length !== 0) {
                        editor_approveArrange
                            .title('Approve Arrangement?')
                            .buttons({ label: 'Confirm', fn: function () { this.submit(); } })
                            .edit(table.row('.selected').node());
                    }
                }
            }
        ]
    },
    initComplete: function (settings, json) {    //    This map to show dropdown options when using 'Edit' function
        editor_approveOvertime.field('myTable.myMirror').update(json.MyMirror);
    },
    "scrollX": true,
    "drawCallback": function (settings) {
        var api = this.api(),
            rows = api.rows({page: 'current'}).nodes(),
            last = null;
        api.column(2, {page: 'current'}).data().each(function (Username, i) {
            if (last !== Username) {
                $(rows).eq(i).before(
                    '<tr class="Username"><td colspan="20">' + Username + '</td></tr>'
                );

                last = Username;
            }
        });
    }
});

//--- START: Footer - Individual column searching (free-text inputs) ---//
    //--- START: Footer - Individual column searching (select inputs) ---//
    setTimeout(function () { //--- Call your code that you want to run after all $(document).ready() calls have run, here. ---//
        $("#myWebTable tfoot th").each(function (i) {
            if (table.column(i).visible() === true) {
                var select = $('<select style="width: 60px;"><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);
    }, 2000);
    //--- END: Footer - Individual column searching (select inputs) ---//
});

Do note that the columns meant to be hidden will be hidden within 2 seconds (2000 milliseconds), which is also at that time where the input filter should appear. What happens is that if scrollX is used, the input filters will no longer be generated.

EDIT: I have read this link (https://datatables.net/forums/discussion/13841/horizontal-scrolling-with-filters-work-around) and also attempted to use sScrollX and set it to 100%, but that too also introduces the issue that I mentioned here. Is there really no way to have both column filtering and horizontal scrolling?

EDIT 2: I just read (http://www.datatables.net/forums/discussion/4010/set-options-programmatically-after-table-initialization) that it is not recommended to change the initialization options once an instance of DataTables is loaded. I also read from the documentation that scrollX is an option and is set once the DataTable is finished loading. Maybe if there is a way to modify scrollX once the input filters are created?

EDIT 3: Went back to both front-end code/CSS files and modified the table.datatables element to have a width of less than 90% (or used a fixed number like 640px), as well as used this in either HTML code or CSS:

table.datables, table.datatables tr {
    overflow-x: scroll;
}

If this were to be applied to table.datatable all cells will have a greyed-out scroll bar, but the table itself won't scroll or have its scrollbar. Apparently, the table can detect if each cell exceeds a certain width, but not the DataTable instance itself. Which still points back to the scrollX initialization in the JS file. Welp~?

This question has accepted answers - jump to:

Answers

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin
    Answer ✓

    Two issues with the above code:

    1. use initComplete rather than a setTimeout - far more reliable and accruate
    2. $("#myWebTable tfoot th") is wrong when using a scrolling table. The table is split into 3 sections when scrolling, so you need to use the column().footer() method to get the footer element.

    Based on this example I've just put together this - which is exactly the same as the original example but with scrollX enabled.

    Allan

  • pansengtatpansengtat Posts: 66Questions: 26Answers: 1
    edited March 2015

    I have removed entire the section on setTimeOut and then inserted the sample code into the section for initComplete. However, my concern is that I have this prior to making changes:

    initComplete: function (settings, json) {    //    This map to show dropdown options when using 'Edit' function
                            editor.field('myTimetable.IsApproved').update(json.ApprovalMirror);
                        }
    

    Now that I can see the dropdown section at the footer, but I am facing an issue: that whenever I change the dropdown selection, the entries aren't filtered. Another thing is that the dropdown filter width doesn't change to the width of the column header but instead the length of the longest content.

    I also see this in console:

    Cannot read property 'escapeRegex' of undefined
    

    EDIT: Turns out that I am running DataTables v1.10.2 while if I swapped out the jquery.datatables.min.js file to the v1.10.5 version, it works. Though I am afraid that I might break other parts of my web application by just swapping out this file.

  • daniel_rdaniel_r Posts: 460Questions: 4Answers: 67
    edited March 2015 Answer ✓

    You can try my yadcf support scrolx/y with footer location of the filters, see showcase samples

  • pansengtatpansengtat Posts: 66Questions: 26Answers: 1

    I think it's ok for now, I'll just swap out the old minified jQuery file for DataTables with the new and re-factor my JS file. :)

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin
    Answer ✓

    EDIT: Turns out that I am running DataTables v1.10.2 while if I swapped out the jquery.datatables.min.js file to the v1.10.5 version, it works. Though I am afraid that I might break other parts of my web application by just swapping out this file.

    The theory is that all minor releases (the last number) should be completely safe updates and can just be dropped in. It is of course possible I've inadvertently introduced a bug into a new release, but if so then that is a bug that needs to be fixed and there have been a lot of bug fixes (such as this one) since 1.10.2! 1.10.6 should be released later this week - all being well.

    Allan

This discussion has been closed.