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