3

I am trying to get the scrollTo plugin to work properly with what I am doing. When you click the green plus sign button on the table it opens up a div I am trying to have the scroll automatically scroll to show the div so that further down on the list you will automatically see the details instead of having them hidden like they are currently. Will someone please help assist me in this? I had this working with the dataTables scroller but that plugin was breaking all the other functions that I needed.

https://jsfiddle.net/nnb97rh9/7/

/* Formatting function for row details - modify as you need */
function format ( d ) {
    // `d` is the original data object for the row
    return '<div class="slider">'+
        '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
            '<tr>'+
                '<td>Full name:</td>'+
                '<td>'+d.name+'</td>'+
            '</tr>'+
            '<tr>'+
                '<td>Extension number:</td>'+
                '<td>'+d.extn+'</td>'+
            '</tr>'+
            '<tr>'+
                '<td>Extra info:</td>'+
                '<td>And any further details here (images etc)...</td>'+
            '</tr>'+
        '</table>'+
    '</div>';
}

$(document).ready(function() {
    var table = $('#example').DataTable( {
        "ajax": 'https://api.myjson.com/bins/16lp6',
        scrollY:        250,
        deferRender:    true,
        scroller:       true,
        scrollCollapse: true,
        "columns": [
            {
                "class":          'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent": ''
            },
            { "data": "name" },
            { "data": "position" },
            { "data": "office" },
            { "data": "salary" },
            { "data": "extn", "visible": false }

        ],
        "order": [[1, 'asc']]
    } );

    // Add event listener for opening and closing details
     $('table.display').on('click', 'tr', function() {

        var tr = $(this).closest('tr');
        var row = table.row( tr );
        var i = $(this).index();
         var target = $("table.display tr").eq( tr.index() );
         var duration = 300;

        if ( row.child.isShown() ) {
            // This row is already open - close it
            $('div.slider', row.child()).slideUp( function () {
                row.child.hide();
                tr.removeClass('shown');
            } );
        }
        else {
            // Open this row
            row.child( format(row.data()), 'no-padding' ).show();
            tr.addClass('shown');

            $('div.slider', row.child()).slideDown();
                $('div.slider').scrollTo(target, duration);
        }
    } );
} );

[![enter image description here][1]][1]

1 Answer 1

4

I have been acheiving this without the scroller plug-in (which give some serious problems) with simple jQuery code in $(document).ready() like this:

$(function () {
    $('#yourTableId').on('draw.dt', function () {
        $(".dataTables_scrollBody")
            .scrollTop($(".dataTables_scrollBody").scrollTop() + $("#yourTrId").position().top - 0);
    });
});

In fact you could give the position of any element instead of a tr, but I have been using a unique id for every tr. You might want to add/subtract some number to manually adjust the scrolling.

EDIT: In your case, you should not be setting $(".dataTables_scrollBody").scrollTop in $('#example').on('draw.dt', ...) when the table is created, because the tbody (which becomes div.dataTables_scrollBody) is not available yet.

I placed $(".dataTables_scrollBody").scrollTop in your event listener for opening and closing details, and it works fine: https://jsfiddle.net/nnb97rh9/14/.

// Add event listener for opening and closing details
$('table.display').on('click', 'tr', function() {
    ...

    // Open this row

    ...

    $(".dataTables_scrollBody")
            .scrollTop($(".dataTables_scrollBody").scrollTop() + $(".slider").position().top - 0);
});

The only problem remains is that you are using .slider class to set scrollTop which is not unique, and if a details row is open before and one opens another details row, the div is scrolled to the first .slider. It is, thus, advisable to use Id here or something unique.

Hope this helps, best of luck ...

EDIT 2: As in your case, data is being fetched from server side and you don't have unique ids for generated HTML elements. Then there exists a solution from DataTables authors: you can send unique ids from server side to be assigned to the tr elements in the data itself:

{
  ...
  "data": [
    {
      "DT_RowId": "row_5",
      "first_name": "Airi",
      ...
    },
    ...
}

https://www.datatables.net/examples/server_side/ids.html

EDIT 3: Or if it's not possible to edit the data from server side, just add the following code to your DataTable initialization:

$('#example').DataTable({
    ...
    fnCreatedRow: function( nRow, aData, iDataIndex ) {
        $(nRow).attr('id','tr_' + iDataIndex);
    }
});

Reference: Add html attribute to datatable row

This way every tr would get a unique id, and it would be possible to scroll to it --- working fiddle: https://jsfiddle.net/nnb97rh9/21/

Sign up to request clarification or add additional context in comments.

3 Comments

In my pages, I scroll to the tr element which become the header, with the details row following. Don't you have any way to assign ids to the tr elements??
Here is a working example to add unique ids to tr elements datatables.net/examples/server_side/ids.html. It works by sending an extra field DT_RowId from the server side.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.