This week, I looked into alternative options for some of the functionalities, fixed a few bugs with the code, and finished up the Table Refactoring.

Table of Contents

Alternative options

The first article I found about how to check when an element comes into view was the new Intersection Observer API. This is a fairly new way and has better performance than the scroll event functions. Another Stack Overflow post had the same question where Intersection API was the third most upvoted answer (Second most upvoted being the getBoundingClientRect()). Here’s another article that explains why Intersection API has better performance.

I did end up adding it and testing how it works. But a major fallback was the fact that it cannot change selected elements. This means, that once it’s selected the load-next-set row, it wouldn’t change to observing another element. To explain it better, once the row has been selected, even removing the selection criteria, which is the load-next-set class and adding it to some other row wouldn’t force the API to observe the new row instead. It would still be observing the first row to ever have the load-next-set class irrespective of whether it still has that class. This would not work when we add the class to a new row every time the next set of rows are loaded. Therefore, right now, in order to keep the project moving, this has been kept on hold until we finish the prototype and find a way to fix this problem.

Bugs

  • The first problem was that the scrollbar height did not work for records mode. The sizeTotal variable only kept in check the total number of rows in row mode. And hence when the mode was changed to record, the height reflected the huge reduction in the number of records (from total rows). This was easy to fix by changing the this._sizeRowsTotal = this._sizeRowFirst * theProject.rowModel.total; to this._sizeRowsTotal = this._sizeRowFirst * theProject.metadata.rowCount;. This ensured that the total height only depends on the total number of rows and not the mode.

  • The second problem was the adding of the last row. The last row was added to the table even if all the rows were already loaded and there was no requirement for a row to provide additional height. This was solved by adding an if condition to check if the total number of rows is already present before inserting a new last row.

if(self._totalSize < theProject.rowModel.total) {
  document.querySelector('.data-table').insertRow(self._totalSize);
  $('tr:last').css('height', heightToAdd);
  $('tr:last').addClass('last-row');
}
  • The next bug was that reaching the end of the dataset, kept deleting rows from the end. This was pretty weird, but I soon realized it’s because of the delete row operation to delete the last-row provided for additional height. There wasn’t a check placed to make sure that there even was a last-row class row. This was solved by not calling the showRowsBottom() once all the rows were loaded.
DataTableView.prototype._onBottomTable = function(table, elmt, evt) {
  if(this._totalSize < theProject.rowModel.total) {
    this._showRowsBottom(table, theProject.rowModel.start + this._pageSize);
  }
};

Table Refactor

The first PR for Table Refactoring had dealt with most of the work that was required. Which was to move the header container and the table body into the same table using <thead>. This refactoring solves issues around some reflow events caused by resizing the columns and rows. It also keeps these columns in sync with the data table. This also ensures that any changes applied to the table body are automatically reflected in the header.

I finished off this PR here. There were some styling issues, most pertaining to Firefox bugs that needed to be fixed in addition to including a fixed header. Right now only the columns with the column-header class or the one with the column names are fixed. The entire group of columns that are rendered in XML/JSON file types (for the node structure) is not fixed. This is something that I am thinking of adding in a separate PR, so as to move ahead with the changes that the project code requires once the table moves into a single container.