Datatable rows extend past table boundary, or are too narrow

Datatable rows extend past table boundary, or are too narrow

R_GR_G Posts: 31Questions: 10Answers: 0

Datatable rows extend past table boundary, or are too narrow. Hope formatting is right as it's my first post here...

DataTables debugging reference: azevaz

Ruby 2.0.0, Rails 4.0.3, jquery-datatables-rails 2.2.3 (w/DataTables 1.10.1), jquery-rails 3.1.1, jquery-ui-rails 5.0.0, lodash-rails 2.4.1, bootstrap-sass 3.2.0.1

I am having trouble getting Datatables to format correctly. Either the columns overrun the form, or the columns are too narrow. I've tried a myriead of fixes for this. I have set columnDefs and column width. I've set HTML width in the table headings. I've set autoWidth false and true. I've set the CSS width dynamically. I've installed various recommended CSS modifications. I've tried about everything I can find. The frustrating part is that nothing changes anything. The format is always exactly the same, like it is totally ignoring all my attempts. These forms are configured to be responsive. I've also disabled that. No dice.

Other than the formatting, the tables work perfectly. They sort. They search, They page. They just won't format correctly. Again, I've minimized this to one form and taken all extraneous information out to no avail.

All assistance is appreciated.

The page that references incorrectly:
Incorrect page

https://github.com/TechRsch/Screenshots/blob/master/datatable-formatting-issue.GIF As it won't seem to display correctly?

The partial form is:

<div class="span12">
  <p>
  <table id="carstable" class="display table-striped"  width="80%"
         data-source="<%= cars_path(format: "json") %>">
    <thead>
    <tr>
      <th data-class="expand">Stock No.</th>
      <th>Year</th>
      <th>Make</th>
      <th data-hide="phone">Model</th>
      <th data-hide="phone">Color</th>
      <th>Status</th>
      <th data-hide="phone,tablet">Mileage</th>
      <th data-hide="phone,tablet">MSRP</th>
      <th data-hide="phone,tablet">Aged</th>
    </tr>
    </thead>
    <tbody>
    </tbody>
  </table>
</div>

The datatable is initialized as:

$(document).ready(function () {
    var breakpointDefinition, tableElement;
    var rHelperCar;
    rHelperCar = void 0;
    breakpointDefinition = {
        tablet: 1300,
        phone: 480
    };
    tableElement = $("#carstable");
    tableElement.dataTable({
        responsive: false,
        autoWidth: false,
        pagingType: "full",
        jQueryUI: true,
        processing: true,
        serverSide: true,
        ajax: $('#carstable').data('source'),
        preDrawCallback: function () {
            if (!rHelperCar) {
                rHelperCar = new ResponsiveDatatablesHelper(tableElement, breakpointDefinition);
            }
        },
        rowCallback: function (nRow) {
            rHelperCar.createExpandIcon(nRow);
        },
        drawCallback: function (oSettings) {
            rHelperCar.respond();
        }
    });

The HTML page is:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="/images/favicon.ico" rel="icon" />
  <title>Car</title>
  <meta name="description" content="Car">

  <link data-turbolinks-track="true" href="/assets/application.css?body=1" media="all" rel="stylesheet" />
...
<script data-turbolinks-track="true" src="/assets/application.js?body=1"></script>
</head>
<body>
<header>
  <div class="navbar navbar-inverse navbar-fixed-top">
  <a class="navbar-brand" href="/"><h4>Car</h4></a>
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="/">Home</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
            <li><a href="/logout">Logout</a></li>
    <li><a href="/cars">Cars</a></li>

      </ul>
    </div>
  </div>
</div>

</header>
<main role="main">

  <div class="container-fluid">
    <div class="row">
        <div class="row">
  <div class="col-md-6">
  <div class="panel panel-primary">
    <div class="panel-heading">
        ---  This associate is: David Hanson
    </div>
    <div class="panel-body">
      <div class="span12">
  <p>
  <table id="carstable" class="display table-striped"  width="80%"
         data-source="/cars.json">
    <thead>
    <tr>
      <th data-class="expand">Stock No.</th>
      <th>Year</th>
      <th>Make</th>
      <th data-hide="phone">Model</th>
      <th data-hide="phone">Color</th>
      <th>Status</th>
      <th data-hide="phone,tablet">Mileage</th>
      <th data-hide="phone,tablet">MSRP</th>
      <th data-hide="phone,tablet">Aged</th>
    </tr>
    </thead>
    <tbody>
    </tbody>
  </table>
</div>

    </div>
  </div>
</div>

</div>
    </div>
  </div>
</main>
</body>
</html>

This question has accepted answers - jump to:

Answers

  • allanallan Posts: 63,576Questions: 1Answers: 10,483 Site admin
    Answer ✓

    Hi,

    Thanks for the image! From it it looks like the table might actually be as small (horizontally) as is it possible to make it there. The header cells appear to have left and right padding which is forcing the width of columns such as "Mileage" and "Aged", while the content is forcing the width on other columns such as "Stock No. and Make".

    Three options spring to mind:

    1. Alter the CSS to compact the table more.
    2. Use Responsive
    3. Enable x-scrolling with scrollX

    Do any of these sound attractive / possible?

    Regarding the paging control - that looks like it is getting a bit upset due to a width constraint on the div.dataTable_paging element. You could have a look at removing that, or using the pagingType option to have just the previous and next buttons.

    Regards,
    Allan

  • R_GR_G Posts: 31Questions: 10Answers: 0

    I am not sure those options would work very well, but CSS might?

    As I said in my note, I want/need responsive. That's how it was developed. But, table isn't displaying correctly whether I have responsive enabled or not. I just disabled it to simplify the problem for debugging.

    I really don't want scrolling as that seems anti-responsive? I have set up the table to drop columns as needed and display the information when selected.

    Every attempt to expand or contract the columns via CSS or HTML has been futile. I wouldn't mind if selected columns were a bit narrower. But, nothing I have done seems to make that happen.

    I've tried to narrow the columns using columnDefs.width and columns.width. That had no effect.

    I tried setting HTML element th width. That had no effect.

    I don't see how to use CSS to set the element td width. They don't have individual selectors. That would work for me, I guess. How would I do that?

    It does bother me that they table formats like this in the first place. Can you tell me what is causing that?

    On another note, I upgraded to jquery-datatables-rails 2.2.3 to get to DataTables 1.10. Reviewing http://www.datatables.net/upgrade/1.10-convert, I modified the JQuery parameter names even though I understood it wasn't necessary. However, I've just come to find out that the tables are no longer operating correctly after all. The params names all changed in Rails. I am trying to upgrade those too. However, I cannot find a reference for them. I guess I need to dig into jquery-rails-datatables to see what was changed to what? Or, would you know or know of a reference? Or, optionally, I could fall back to 2.2.1 and DataTables 1.9. Advice?

    To be accurate, I can figure out all the params, of course, just through debugging. But, it still doesn't work. I'm guess this code is the problem, but I'm not sure of what changes would have to be made:

      def as_json(options = {})
        {
            sEcho: params[:sEcho].to_i,
            iTotalRecords: Car.count,
            iTotalDisplayRecords: cars.total_entries,
            aaData: data
        }
      end
    

    I appreciate the help.

  • R_GR_G Posts: 31Questions: 10Answers: 0

    Thinking this over, when you said:

    The header cells appear to have left and right padding which is forcing the width of columns such as "Mileage" and "Aged", while the content is forcing the width on other columns such as "Stock No. and Make".

    I don't really care if the table is bigger, such that it spans the rows. I'm not concerned that the rows are too big, I am concerned that the table is too small to contain them reliably. Does that make sense?

  • R_GR_G Posts: 31Questions: 10Answers: 0

    Okay... I'm even more confused. I am working on correcting the params and other variable problems in the Rails code. Suddenly, the table started displaying correctly, in terms of row and table width. Why that confuses me is mostly because I didn't upgrade my gems until after I had the problem... So, why were they screwing up before the upgrade? I don't know... But, that problem could mostly be fixed.

    I say "mostly" because it still isn't right as my browser size changes. That's probably simply my breakpointDefinition. Advice?

    But, the table just isn't working right in that it doesn't page. It looks like it does, but it still displays the first rows when I hit last. It simply doesn't change. Sort works except for the last column, so that's probably my settings. Search doesn't work. Again, it appears to work and says "processing" but the display doesn't change. I am assuming its those variable settings. Would that be right? Can we fix those?

  • R_GR_G Posts: 31Questions: 10Answers: 0

    Regardless of the above, I'd like to understand how to use CSS to set the td element width. That would be useful. Sorry for a running dump, here. Just trying to get it working.

  • R_GR_G Posts: 31Questions: 10Answers: 0

    Found the variables to be:

      def as_json(options = {})
        {
            draw: params[:draw].to_i,
            recordsTotal: Car.count,
            recordsFiltered: cars.total_entries,
            data: data
        }
      end
    

    With that, the basic table operations are functioning and the primary formatting problem was fixed. Still not sorting on the last column, but I'm sure that's something I can fix.

    So, at the moment, these questions remain:

    1. How do I use CSS to specify the column width. I am assuming that is on the td element?
    2. Would you say that setting breakpointDefinition would resolve the resizing issue and, if so, what would you recommend.
    3. Also, I wanted to make sure that I was appropriately initializing multiple tables as the documentation is ambiguous.

    These tables are not on the same page. Even so, I am led to understand that they need separate ResponsiveDatatablesHelper's. Would initialization for multiple tables on separate pages be as follows?

        var breakpointDefinition, tableElement;
        var rHelperData, rHelperCar, rHelperAdminCar;
        rHelperData = void 0;
        rHelperAdminCar = void 0;
        rHelperCar = void 0;
        breakpointDefinition = {
            tablet: 1300,
            phone: 480
        };
        tableElement = $("#datatable");
        tableElement.dataTable({
            responsive: true,
            autoWidth: false,
            pagingType: "full",
            jQueryUI: true,
            preDrawCallback: function () {
                if (!rHelperData) {
                    rHelperData = new ResponsiveDatatablesHelper(tableElement, breakpointDefinition);
                }
            },
            rowCallback: function (nRow) {
                rHelperData.createExpandIcon(nRow);
            },
            drawCallback: function (oSettings) {
                rHelperData.respond();
            }
        });
        tableElement = $("#admincarstable");
        tableElement.dataTable({
            responsive: true,
            autoWidth: false,
            pagingType: "full",
            jQueryUI: true,
            processing: true,
            serverSide: true,
            ajax: $('#admincarstable').data('source'),
            preDrawCallback: function () {
                if (!rHelperAdminCar) {
                    rHelperAdminCar = new ResponsiveDatatablesHelper(tableElement, breakpointDefinition);
                }
            },
            rowCallback: function (nRow) {
                rHelperAdminCar.createExpandIcon(nRow);
            },
            drawCallback: function (oSettings) {
                rHelperAdminCar.respond();
            }
        });
        tableElement = $("#carstable");
        tableElement.dataTable({
            responsive: true,
            autoWidth: false,
            pagingType: "full",
            jQueryUI: true,
            processing: true,
            serverSide: true,
            ajax: $('#carstable').data('source'),
            preDrawCallback: function () {
                if (!rHelperCar) {
                    rHelperCar = new ResponsiveDatatablesHelper(tableElement, breakpointDefinition);
                }
            },
            rowCallback: function (nRow) {
                rHelperCar.createExpandIcon(nRow);
            },
            drawCallback: function (oSettings) {
                rHelperCar.respond();
            }
        });
    

    Thanks...

  • R_GR_G Posts: 31Questions: 10Answers: 0

    And...

    1. Okay, now it makes sense that the initial issue only disappeared due to data size variances. Is there someway to ensure that the table boundaries expand to span the row length?

    That should be it, I hope... <grin> Thanks...

  • allanallan Posts: 63,576Questions: 1Answers: 10,483 Site admin

    Heh - nice running commentary. Let me address the specific questions from your last two posts:

    How do I use CSS to specify the column width. I am assuming that is on the td element?

    That is one option. You can add width="..." as an attribute to the column's TH/TD element and DataTables will read that. Alternatively you could use columns.width and DataTables will also use that. Finally you can use a class name on the cell and apply that in your CSS - DataTables will not read that, but the browser will use it none-the-less.

    One very important point here is that the width assigned is to guide DataTables and the browser only. The browser can and will overrule your widths if they are not appropriate. For example if you assign 10px width to a column that has content that must be 100px then the content will win. That is simply how the browser table layout algorithm works.

    Would you say that setting breakpointDefinition would resolve the resizing issue and, if so, what would you recommend.

    I'm afraid I don't know what ResponsiveDatatablesHelper is (and therefore what the breakpointDefinition is). Is that third party software included in the Rails bundle or something?

    If you want responsive tables, the my Responsive extension is what I would recommend.

    Also, I wanted to make sure that I was appropriately initializing multiple tables as the documentation is ambiguous.

    Given that you require different callbacks for the different tables - what you have is fine (i.e. individual table initialisation). You could set defaults if you don't want to repeat the whole config object each time for common values.

    If you did want to initialise multiple tables with a single call it is based on the jQuery selector - just select multiple tables $('table.enhanceTables') for example.

    Okay, now it makes sense that the initial issue only disappeared due to data size variances. Is there someway to ensure that the table boundaries expand to span the row length?

    Remove the width constraint on the container. It looks like the container has a width of (for example) 600px, but the table rows can't be shown in smaller than 700px (again for example). The result is that the table looks like it is overflowing the container - which it is.

    Using Responsive would modify the hidden columns to make the table fix - try resizing the browser window for the Responsive examples.

    Regards,
    Allan

  • R_GR_G Posts: 31Questions: 10Answers: 0

    Resolving all the problems above has allowed columns.width to work for me, and that may be best. That, combined with setting a more expansive table width, really makes a difference.

    That is one option. You can add width="..." as an attribute to the column's TH/TD element and DataTables will read that. Alternatively you could use columns.widthDT and DataTables will also use that. Finally you can use a class name on the cell and apply that in your CSS - DataTables will not read that, but the browser will use it none-the-less.

    However, I remain unclear on how to set width using either CSS or HTML. Does setting the th element width suffice? Is there a way to set the td width, because I don't see it anywhere? I simply don't define a td using the tools I have, so there is no way to differentiate one from the other by setting class, id, attribute or otherwise. I ask this only so that I know should the need come to pass. Any reference or explanation would be appreciated.

    I'm afraid I don't know what ResponsiveDatatablesHelper is (and therefore what the breakpointDefinition is). Is that third party software included in the Rails bundle or something?

    Rails wrapper for DataTables is the Rails wrapper for DataTables that I am using. I had it at 2.2.1 and upgraded it to 2.2.3 to get to DataTables 1.10. That's where the variable names broke for me. But, that problem is fixed. This gem supports DataTables-Responsive, the compatible DataTables responsive extension option. It also provides full Ajax capability within Rails per RailsCasts or AsciiCasts 340. I followed that episode, though the variable names have been changed to protect the innocent. This all directly supports all the features provided in your Responsive extension

    I can't say I'm yet experienced enough to use DataTables directly from Rails, but I'd be interested in seeing how. Do you have any reference that would explain how to do that?

    Given that you require different callbacks for the different tables - what you have is fine (i.e. individual table initialisation). You could set defaults if you don't want to repeat the whole config object each time for common values.

    Thanks, that is very helpful. I just wasn't confident in what I had done, especially given all of the issues I've experienced.

    Remove the width constraint on the container. It looks like the container has a width of (for example) 600px, but the table rows can't be shown in smaller than 700px (again for example). The result is that the table looks like it is overflowing the container - which it is.

    That was the crux of the original problem. The partial was rendered with a layout containing a div element with col-md-6. Changing it to col-md-9 made a huge difference in all my tables. I could use col-md-12, the full Bootstrap 12-column width, if needed.

    Using Responsive would modify the hidden columns to make the table fix - try resizing the browser window for the Responsive examples.

    The data-hide="phone,tablet" reference in the HTML index partial does exactly that for me, based upon the breakpointDefinition in the ResponsiveDatatablesHelper, as discussed above. I just need to set the correct breakpointDefinition's

    Thanks for all your help. Please help me answer the few questions above.

  • R_GR_G Posts: 31Questions: 10Answers: 0

    Hello, back again.

    I just discovered that the expand icon is gone. How do I fix that?

  • R_GR_G Posts: 31Questions: 10Answers: 0

    This says it is an open problem. I know that this is not your gem. But, I'd appreciate any advice on how to resolve:

    Expand icon missing

  • R_GR_G Posts: 31Questions: 10Answers: 0

    Okay, the missing expand icon problem seems to show up in jquery-datatables-rails per jquery-datatables-rails missing expand icon, so please ignore that. I just need help answering the questions posted just before that. Thanks!

  • allanallan Posts: 63,576Questions: 1Answers: 10,483 Site admin

    Hi,

    However, I remain unclear on how to set width using either CSS or HTML. Does setting the th element width suffice? Is there a way to set the td width, because I don't see it anywhere? I simply don't define a td using the tools I have, so there is no way to differentiate one from the other by setting class, id, attribute or otherwise.

    The two basic methods for setting a column width are assigning it directly to the width attribute for the column header prior to the DataTables initialisation (example) and using columns.width (example). These are basically the same and the end result is the same.

    Could you use columns.className to assign a class name to the column header cell to provide CSS rules, but one of the two methods suggests just above is usually easier!

    Do you have any reference that would explain how to do that?

    Not directly for Rails I'm afraid. The DataTables documentation is all purely directly at "raw" DataTables and the Javascript around it, rather than platform specific integration. I suspect that way lies only madness as there are so many platforms available! Having said that, providing documentation on using DataTables with common package managers is something I am interested in doing in future.

    This gem supports DataTables-Responsive, the compatible DataTables responsive extension option.

    I don't think that is quite the case. The Rails package appears to use Comanche's Responsive plug-in which is which different from my own.

    I'm afraid I'm not familiar with how Comanche's plug-in operates so I might not be much help with that. Scanning the code, I'm spruced it doesn't provide default options for the breakpoints, but what you have look like it follows the documentation.

    Are you able to try my own Responsive extension - it is supported software as part of the DataTables project.

    Regards,
    Allan

  • R_GR_G Posts: 31Questions: 10Answers: 0

    Not directly for Rails I'm afraid. The DataTables documentation is all purely directly at "raw" DataTables and the Javascript around it, rather than platform specific integration.

    Thus, the confusion regarding td elements and html selectors. Going back to my original question, you can see I have no td elements at all. The table is built via json. My partial only has th elements in regards to table row definition. Your explanation, along with the various changes I described, resolve this question. I think all is working as it should be. All I need fixed is the expand icon, which problem is in another Rails gem from current appearances.

    This gem supports DataTables-Responsive, the compatible DataTables responsive extension option.

    I meant compatible with jquery-datatables-rails, actually.

    Are you able to try my own Responsive extension - it is supported software as part of the DataTables project.

    I'd be interested in that but it leaves the burning question of how best to work directly between Rails and DataTables. I guess I'll leave that one alone for now, but it'd really be a much stronger, if more intense, option.

    I may ping you shortly still, but thank you for your excellent service and for your wonderful software. I certainly appreciate and recommend it.

  • allanallan Posts: 63,576Questions: 1Answers: 10,483 Site admin
    Answer ✓

    No worries - good to hear that things are generally working now.

    I'm not sure how the rails packaging works exactly, given that these gems seem to be packaging Javascript rather than Ruby code. To my mind it should be able to simply include the raw Javascript and use it directly without any interaction from Rails. I'm going to have to get going with Rails soon I think - I've put it off far too long!

    Allan

This discussion has been closed.