on "Draw"

on "Draw"

Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10

I'm revisiting the card view from this discussion: https://datatables.net/forums/discussion/37132

The last version of the table from that discussion is here: https://ghsfha.org/datatables_cards_labels.html

On that version, the table starts in the normal table view and then changes to a card view when the button in the upper right is clicked, primarily by toggling the "cards" class on the table and using the Draw event to adjust the height of each tr element so that the heights are the equal to the tallest tr element.

However, if I start the page out in card view by including "cards" class in the table to begin with, the tr elements are not adjusted properly: https://ghsfha.org/tests/datables_cards_labels_height.html

Once I click the button for the table view and then click it again to go back to card view, the heights are properly adjusted, but I'm not clear why it wouldn't do so on the first draw of the table.

Wouldn't the Draw event occur on the first draw of the table, or am I calling the wrong event?

This question has an accepted answers - jump to answer

Answers

  • colincolin Posts: 15,143Questions: 1Answers: 2,586

    Hi @Loren Maxwell ,

    It would be worth creating a test case for this, or linking to your page, so we can see what's going on. There's so much styling it's hard to see what's happening without having it up and running.

    Cheers,

    Colin

  • Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10
    edited October 2019

    Hey @colin, I included a link to the page,:
    https://ghsfha.org/tests/datables_cards_labels_height.html

    The first card (really a tr) is the one that should have the tallest height and all the others should be matched to. When the table first renders it's not working, but after switching to regular view and back using the button on the upper right it works.

  • colincolin Posts: 15,143Questions: 1Answers: 2,586

    Ah sorry, I didn't realise that link was yours - I thought it pointed to the original thread :)

  • allanallan Posts: 61,716Questions: 1Answers: 10,108 Site admin

    Nice to see this being used!

    The issue here is that you are listening for the draw event after the initial draw has already happened - hence why it is missed.

    To fix that do:

    var table = $("#register")
      .on("draw.dt", function (e, dt, type, indexes) {
        ...
      })
      .DataTable({
        ...
      })
      ...
    

    i.e. listen for the draw event first, then initialise the table. Also note that you need to add the .dt namespace since we are using the jQuery.on method there.

    The other option would be to call table.draw() after your initialisation code, or put your resize code into another function and call that after the init code and from the draw event handler.

    Allan

  • Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10

    Thanks, @allan,

    I've updated the code to what you have and it works 95% great :-)

    However, there's a small hiccup at the bottom of the first card (the tallest) for the last field. It's resolved if I click the button to switch views from card to regular and back.

    The initial height when loading the page is height: 412.156px; but after switching views it becomes the correct height: 436.156px;.

    Any idea what causes that discrepancy?

  • Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10

    Also, I just noticed the data-labels aren't attaching to rows on the other pages (i.e., click page 2).

    Probably because the html doesn't actually exist when I switch to card view except for the current page?

    For my actual use case I'll only have one page, but others may expect to use the pagination feature.

    Maybe this should just be another thread . . .

  • allanallan Posts: 61,716Questions: 1Answers: 10,108 Site admin

    I've just been trying to debug this but I'm not able to set any breakpoints in your Javascript for some reason. I wonder if it is related to the type="ba40d9a3ce7f7fb69ecec948-text/javascript" in the script attribute. Are you able to change the type to just be text/javascript?

    Allan

  • Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10

    If I can change that I'm not sure how. I use Cloudflare and it adds that to script tag for some reason.

    In the raw code I just have <script>.

  • Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10

    @allan. I turned off the auto minify feature in Cloudflare.

    Let me know if that helps with the breakpoints.

  • allanallan Posts: 61,716Questions: 1Answers: 10,108 Site admin

    I'm still seeing the <script type="d63fba4e8de3d4a5f476ca20-text/javascript"> I'm afraid.

    I don't know if it is that which is stopping the breakpoints from working, but I can't get any to break on the code in either Firefox or Chrome and that seems like the most obvious difference.

    Are you able to put a breakpoint on your page and have to break?

    Allan

  • Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10

    Thanks for looking again, @allan.

    I'm not following you here: "Are you able to put a breakpoint on your page and have to break?"

    You mean like add a breakpoint into the code . . . ?

    I'm in new territory for me, but after some quick reading I added a debugger; line in there.

    Let me know if that's what you're looking for!

    Also, I'm not sure what I can do about the <script type="d63fba4e8de3d4a5f476ca20-text/javascript"> part. I've tried to set a page rule in Cloudflare to avoid this page from being touched, but there must be some other option I'm not familiar with.

    If the debugger; line doesn't work I'll just set up a different test case.

  • allanallan Posts: 61,716Questions: 1Answers: 10,108 Site admin
    Answer ✓

    Yup that's enough to let me put in custom breakpoints - thanks! This is a good overview of adding breakpoints into live code if you are interested.

    So the issue is caused by the labels. The sequence of events is:

    1. Table is initialised and drawn
    2. The draw event handler kicks in and measures the heights and applies them.
    3. The initComplete function is then run (after the first draw)
    4. That adds the labels which causes extra space to be used.
    5. The content of the first card no longer fits.

    So the fix is to run the heights function after initComplete. Here's what I would do:

    var cardHeights = function () {
      if($("#register").hasClass("cards")){
        var max = 0;
        $("#register tbody tr").each(function() {
          max = Math.max($(this).height(), max);
        }).height(max);
      } else {
        $("#register tbody tr").each(function(){
          $(this).height("auto");
      })
    };
    
    var table = $("#register")
      .DataTable({
        ...,
        initComplete: function () {
          // ... labels
          // then
          cardHeights();
        }
      })
      .on("draw.dt", function (e, dt, type, indexes) {
        cardHeights();
      })
      ...
    

    Allan

  • Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10
    edited October 2019

    Thanks, @allan,

    Here's the link again for easy reference:
    https://ghsfha.org/tests/datables_cards_labels_height.html

    But perhaps the biggest lesson for me was how to add a breakpoint into my code!!! :smiley:

  • allanallan Posts: 61,716Questions: 1Answers: 10,108 Site admin

    Looks great! Seriously considering if we should do some kind of formal Cards extension for DataTables... :).

    Allan

  • Loren MaxwellLoren Maxwell Posts: 387Questions: 94Answers: 10

    @allan, yes!

This discussion has been closed.