This is the last of my series about adjusting columns of nested tables. It answers the question
DIV tables? Tables can be built not only by HTML TABLE elements, but also by DIV elements when using specific CSS display styles. Here is an example:
1 | <!DOCTYPE html> |
This displays like a normal HTML TABLE. The only difference is that DIV tables do not support certain features like e.g. the colspan attribute, and do not have browser-defaults for padding, margin etc.
How can I reuse the JS code for TABLE elements to do the same for DIV tables?
By implementing new categorizer and adjuster modules, both extending their already provided abstractions.
As you may remember, I implemented modules with different responsibilities:
They were finally built together to create the adjuster fitting to the requirements.
Now here is the new categorizer module implementation for DIV tables:
1 | "use strict"; |
This module extends abstractCategorizer. It then implements getSpan() to return 1 (does not support colspan), and isElementToCategorize() to identify table-cells of DIV tables.
Now I need to write an adjuster that can find nested DIV tables.
1 | "use strict"; |
This module extends its predecessor module nestedTablesColumnAdjuster. It overwrites the getNestedContainers() function to call the private findNestedDivTables() implementation. Unfortunately the JS built-in querySelector() function can not be used here, because there is no CSS selector that can target CSS styles like display: table. So we need to loop through children and read their styles.
Here comes the code to integrate the two new modules:
var categorizer = divTableColumnCategorizer();
var abstractAdjuster = abstractLayoutAdjuster(categorizer);
var columnAdjuster = nestedDivTablesColumnAdjuster(categorizer, abstractAdjuster);
columnAdjuster.init(tables);
Remember that I provided an abstract module that provides pre-defined columns widths. To be able to integrate that module into the build-chain, I needed to specify the abstractAdjuster parameter separately.
Of course also both the elastic-column and predefined-column-widths modules can be reused for DIV tables. Just the build chain changes:
var categorizer = divTableColumnCategorizer();
var abstractAdjuster = predefinedSizes ?
abstractPredefinedSizeAdjuster(categorizer, predefinedSizes) :
abstractLayoutAdjuster(categorizer);
var adjuster = nestedDivTablesColumnAdjuster(categorizer, abstractAdjuster);
var columnAdjuster = elasticColumn ?
elasticColumnAdjuster(categorizer, adjuster, elasticColumn) :
adjuster;
columnAdjuster.init(tables);
That's all! You can go to my homepage to see this working.
The beauty of code reuse by inheritance is that you are mostly done by overwriting only a few things. All object-oriented languages provide inheritance. Although JS is not object-oriented, similar can be provided by using functional inheritance.
Generally JS provides several kinds of inheritance(would we have needed so much?). There are prototypal, classical, .... I wrote about this in one of my past Blogs.
I recommend functional inheritance, because it is easy to use and understand, and avoids the risks of the prototype chain and the this pointer, and does not require understanding the new operator. And private instance variables work fine.
Keep it simple, and you will win!
ɔ⃝ Fritz Ritzberger, 2016-03-06