Building a JavaScript Component for Conditional Formatting in HTML Tables
This is my study of conditional formatting for HTML table cells without jQuery. After looking for a simple visual solution to table cell conditioning with vanilla JavaScript failed, I decided to create my own. While this will forever be a draft, I hope it can be the seed for a community initiative to bring better data representation to HTML tables.
Introduction
While working for a financial company, I spent a great deal of time staring at HTML tables filled with numbers. There was no way around this, as the main product for this company revolved around comparative performance of their products against its benchmark – all represented in numbers. However, being the visual person that I am, I often found it hard to compare hard numbers against each other. I needed to have the comparison visually represented, ideally through bold colors.
After spending some time searching for a simple solution to conditional formatting of table cells, I found that all of the solutions I came across, though simple, relied heavily upon jQuery. Furthermore, the solutions were not very flexible and required multiple instantiations when the same code could be reused. This led me to explore my own solution to this problem without relying on jQuery.
My first draft of this code relied much too heavily on if statements. It required me to take a step back and look at what the core functionality required. After some thought, I realized that I needed to rely more on scalable parsers. My ultimate goal is to provide a fully customizable solution to conditional formatting of HTML tables; the current solution is a step in that direction.
The Final Result
Data Group
Sorted Numbers
Numbers with Ties
Some Numbers, Some Not
Set 1
-6.73
-7.82
-12.16
Set 1
7.22
-7.82
text
Set 2
99.89
-4.75
8.33
Set 2
85.88
-4.75
4.79
Set 2
63.24
-4.75
text
Set 2
9.12
-4.75
2.30
Set 2
-8.22
-4.75
text
Set 3
-6.59
-10.92
9.32
Set 3
-5.67
-10.92
-2.99
Set 3
-4.68
5.06
text
Set 3
-3.87
5.00
4.21
Set 3
2.22
5.06
-3.89
Set 3
5.22
-4.38
text
Set 3
9.323
5.00
100.241
Set 3
11.54
5.06
0.11
Set 3
14.229
-4.38
4.5
The HTML
One of my goals was to modify the HTML as little as possible. To achieve this, I used the HTML5 ‘data’ attribute. This attribute allows the flexibility of grouping the elements while also not adding too much weight or obscure classes and identifiers. The developed component uses just one ‘data’ attribute with multiple associations to group together sets of comparable data. This allows the JavaScript to focus on core functionality and not worry about grouping together the rows of a table.
The CSS
While the CSS for the output above appears simple, the challenge here was determining how the JavaScript would use CSS to implement the changes. For certain results where blending of colors was needed and the number of rows was unknown, creating classes for each table cell would not be possible. With cell color blending as my basis for this project, I did not originally develop this to handle custom classes for certain attributes. This is an area where I hope the community can add value.
The JavaScript
The JavaScript is the backbone of the whole component. My desired pattern was to mimic a typical jQuery plugin, without the jQuery. This required some workarounds, although the final result is a lighter weight than including the jQuery library in its entirety.
I began with creating the default settings for the component. This helped to create a foundation from which I could build functions without worrying about variables changing or being overwritten. Once the core functions were written, I started pulling them apart to create functions that were reused within each of the more general functions to create a simpler appearance and more modularity. Lastly, I focused on customizing the experience for the user, with jQuery in mind. This required me to define certain features directly in the object passed through the function declaration. The challenge was to then make sure these customizations were passed to the settings and, more importantly, were overwriting the defaults.
Changes I Hope to Make
While this code is still a working draft, I do have some changes I would ultimately like to make to see this code be even further customizable.
Modify the parser function to allow further customization
Add a sort customization, similar to a parser, so the two can be paired together
Add some built-in parsers, such as date, alphabetical text, and a simple text-to-range