Child rows with data directly from HTML

Child rows with data directly from HTML

artemvaartemva Posts: 3Questions: 1Answers: 0
edited March 2020 in Free community support

I am generating HTML document using a server-side program with the Flask framework (Python) and output table in the proper form for datatables.

The reason I would like to have child rows feature is that the content in one column (out of 7 columns) is too big and it totally screwes up the appearance of the table. That's why I would like to show 6 columns as rows and the content of the 7th column as a child row.

In the example here the data for child row is fetched with the help of AJAX. This method is not suitable for me since the data for a DataTable comes directly from HTML. So when DataTables starts up, it will automatically check for data that already exists inside it and use it for the table.

Is it possible to somehow specify for DataTables to show 6 columns as a table and the 7th column as a child row?

What are other ways how I can implement "child row" if my data for a DataTable come directly from HTML (without using AJAX)?

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    The source of the data doesn't matter. You can use Datatables to hide the 7th column with columns.visible. You can use the format(d) function like the example. d is the data for that row which will include the hidden column 7. d will be either an array or object depending on your data structure, ie, if using columns.data then d is an object.

    Kevin

  • artemvaartemva Posts: 3Questions: 1Answers: 0
    edited March 2020

    @kthorngren Kevin, Thanks for the answer!

    I am trying to implement what you have mentioned. However, I do not have a desired output with the following code. All I want now is just to have a child row with a constant message.

    Do you know what the problem is?

    <script>
                /* Formatting function for row details - modify as you need */
                function format (d) {
                    // `d` is the original data object for the row
                    return 'I can see the CHILD ROW!!!';
                }
    
                $(document).ready(function() {
                    var table = $('#table_id').DataTable({
                        "columnDefs": [
                            // hide the needed column
                            { "visible": false, "targets": 5 }
                        ]
                    });
    
                    // Add event listener for opening and closing details
                    $('#table_id tbody').on('click', 'td.details-control', function () {
                        var tr = $(this).closest('tr');
                        var row = table.row( tr );
    
                        if ( row.child.isShown() ) {
                            // This row is already open - close it
                            row.child.hide();
                            tr.removeClass('shown');
                        }
                        else {
                            // Open this row
                            row.child( format(row.data()) ).show();
                            tr.addClass('shown');
                        }
                    } );
                } );
    </script>
    

    Screenshot of the table

    There are no child rows and even "a button to open child row".

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954
    edited March 2020

    You need to add a column for the plus icon then use columnDefs to add the details-control class, etc as shown in the example. Something like this:

          "columnDefs": [
                // hide the needed column
                { "visible": false, "targets": 5 },
                {
                    "className":      'details-control',
                    "orderable":      false,
                    "data":           null,
                    "defaultContent": '',
                    "targets": 0
                },
          ]
    

    Kevin

  • artemvaartemva Posts: 3Questions: 1Answers: 0

    @kthorngren Keven, thanks a lot for your hints! With the help of your answers, I was able to create child rows! :)

    The only tiny question left is whether it is possible to "limit the width of the child row to the size of the screen"?

    To show what I mean, please have a look at the screenshot
    Table with child rows

    There are so many columns that there is a "horizontal scroll" which is fine. However, when I add child rows, the content of the child row is also extended to the size of the table. It would be really nice to fit the content of the child row to the size of the screen.
    Is this possible to do?

    In case needed, here is my code:

    <script>
                /* Formatting function for row details - modify as you need */
                function format (d) {
                    // `d` is the original data object for the row
    
                    return '<table cellpadding="5" cellspacing="0" border="0">'+
                            '<tr>'+
                                '<td>Body:</td>'+
                                '<td>' + d["6"] + '</td>'+
                            '</tr>'+
                            '</table>';
                }
    
                $(document).ready( function () {
                    var table = $('#table_id').DataTable({
                        "columnDefs": [
                            { "visible": false, "targets": 6 },
                            {
                                "className":      'details-control',
                                "orderable":      false,
                                "data":           null,
                                "defaultContent": '',
                                "targets": 0
                            },
                        ]
                    });
    
                    // Add event listener for opening and closing details
                    $('#table_id tbody').on('click', 'td.details-control', function () {
                        var tr = $(this).closest('tr');
                        var row = table.row( tr );
    
                        if ( row.child.isShown() ) {
                            // This row is already open - close it
                            row.child.hide();
                            tr.removeClass('shown');
                        }
                        else {
                            // Open this row
                            row.child( format(row.data()) ).show();
                            tr.addClass('shown');
                        }
                    });
                });
    </script>
    
    
  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954
    Answer ✓

    The only tiny question left is whether it is possible to "limit the width of the child row to the size of the screen"?

    Not so tiny of a question I'm afraid :smile: I'm not a CSS expert but you could wrap the child table in a div that helps control the width. Your updated example here:
    http://live.datatables.net/silevara/1/edit

    Added a div with the class inner to the child table and add the class child-cell to the td with the long text. Note the corresponding CSS in the CSS tab. This may need adjusting depending on your specific environment. For more details see Allan's response at the end of this thread.

    Kevin

This discussion has been closed.