Search code examples
javascriptjqueryhtmlcssbackbone.js

Getting the calculated CSS attributes (ex: width) after view is rendered using Marionette Backbone.js


I've created a fixed header/footer table based on a pure javascript program logic.

Basically, after loading the page, what I do is to split the original table in 3 other tables, each one containing part of it, as follows: thead, tbody and tfoot.

As reference, working code can be found bellow: (sorry for the long code statement, but I though, as it is working fine, same could be useful for someone else)

$(window).load(function() {
  var mainTable = $('.table-scroll');

  // outer contrainer
  var tableOuterContainer = $('<div id="table-outer-container"></div>');
  $(mainTable).after(tableOuterContainer);

  // table header
  var theadCopy = detachTableHeader();
  $(tableOuterContainer).append(theadCopy);

  //table body
  var tableContainer = $('<div id="table-inner-container"></div>');
  $(tableContainer).css('height', '300px');
  $(tableContainer).css('overflow-y', 'auto');
  $(tableContainer).append(mainTable);
  $(tableOuterContainer).append(tableContainer);

  var tfootCopy = detachTableFooter();
  $(tableOuterContainer).append(tfootCopy);

  function detachTableHeader() {
    var clone = $(mainTable).clone();
    $(clone).find('tbody').remove();
    $(clone).find('tfoot').remove();
    $(mainTable).find('thead').remove();
    return clone;
  }

  function detachTableFooter() {
    var clone = $(mainTable).clone();
    $(clone).find('thead').remove();
    $(clone).find('tbody').remove();
    $(mainTable).find('tfoot').remove();
    return clone;
  }

  function adjustTableHeaderWidth() {
    var tbodyColumns = $(mainTable).find('tbody tr:first').children();
    var theadColumns = $(theadCopy).find('thead tr').children();

    var width;
    $(theadColumns).each(function(i, v) {
      width = Math.round($(tbodyColumns[i]).width());
      if (i + 1 < $(theadColumns).length) {
        $(v).width(width);
        $(tbodyColumns[i]).width(width);
      }
    });

    $(theadCopy).css('margin-bottom', '0');
    $(theadCopy).css('border-bottom', '0');
  }

  function adjustTableFooterWidth() {
    var tbodyColumns = $(mainTable).find('tbody tr:first').children();
    var tfootColumns = $(tfootCopy).find('tfoot tr').children();

    var width;
    $(tfootColumns).each(function(i, v) {
      width = Math.round($(tbodyColumns[i]).width());
      if (i + 1 < $(tfootColumns).length) {
        $(v).width(width);
        $(tbodyColumns[i]).width(width);
      }
    });

    $(mainTable).css('margin-bottom', '0');
    $(mainTable).css('border-bottom', '0');
    $(tfootCopy).css('border-top', '0');
  }

  // Adjust the width of thead cells when window resizes
  $(window).resize(function() {
    adjustTableHeaderWidth();
    adjustTableFooterWidth();
  }).resize(); // Trigger resize handler
}); //]]>

Problem is now, I'd like to migrate the code above for using it in a Marionette Backbone view, but can't do it, because I need widths to be got, in order to align the columns in the new tables created, but when I try doing it values are zero (0) in the render (onRender) function.

So, my question is: Is there any way for me to get the calculated CSS values, using Backbone, similar to what I have done above?


Solution

  • Solved the problem by adding a script tag inside the $el, forcing it to be executed after the view has been displayed, so the CSS is calculated already:

    onShow : function () {
        this.$el.append('<script>require(["table_fixedheader"], function () {jq.detachTableHeaderAndFooter();});');
    }
    

    Note script tag has not been closed. Did it intentionally as the framework is going to take care of closing it. Otherwise, it does not work as expected.