Select to view content in your preferred language

Make use of HTML in your Dashboard Tables, Too!

2104
4
02-14-2023 09:12 AM
Labels (2)
jcarlson
MVP Esteemed Contributor
4 4 2,104

So, late last year, @JenniferAcunto wrote up an excellent post on using HTML in Dashboards to get a super slick, dynamic design in a List widget. If you haven't read that, make sure you do! Worth your time.

Lists are really great for the way you can work directly in the HTML source and combine it with Arcade to make something fancy. I've posted about it a couple times before.

Sometimes, though, someone really wants that table widget. Yes, you could get close to a table with the right HTML, but if it's a big table, maybe you don't want to mess with HTML so much, or maybe you need to pack the information in a little more densely. The table widget is great for that, but doesn't exactly "pop" the way Jennifer's examples do.

jcarlson_1-1676390382779.png

Now sure, I could use Arcade to change the font and cell colors, add little Icons, all that. But the point of this post is that the table widget also respects certain HTML tags, even though you don't see the source button!

So for the screenshotted example data above, I want the following:

  • Permit Number bigger and bolder
  • Dynamic messages in the "last routine inspection" field based on the date
  • Establishment names not truncated

Adjusting Fonts

This one is simple. Just stick <span> tags around the displayText item in your Advanced formatting window, add your desired style attributes.

permit_number: {
displayText: `<span style="font-size:24px"; font-family:monospace">${$datapoint['permit_number']}</span>`
...
P}

jcarlson_3-1676390985212.png

Adjusting Fonts Dynamically (and line breaks!)

This is a bit more complicated, but it doesn't have to be. For my Last Routine Inspection field, there is a lot going on with respect to inspection scheduling. The cell background is already changing based on conditional values, but I have a few "flags" that I want to appear based on other conditions.

I don't know how many of the flags might show up on a given row, and I don't want to create a bunch of empty space for nothing. I also don't like writing out lots of separate if blocks, so I use a dictionary of conditions and resulting flag messages to build the output string. Here's a generalized version:

// create array for output string; date always at top
var flags = [$datapoint['last_routine_inspection']

// array of conditions. these evaluate to true or false
var conditions: [
    {condition: condition_a, message: '<span style="font-color:red">Some message!</span>'},
    {condition: condition_b, message: 'Some other warning!'}
    ...
    {condition: condition_n, message: '<span style="font-weight:bold">Another message</span>'}
]

for (c in conditions) {
    if(conditions[c][condition]) {
        Push(flags, conditions[c][message])
    }
}

// concatenate flags with line breaks into single string
var flag_str = Concatenate(flags, '<br>')

// include flag string with output
return {
    cells: {
        last_routine_inspection: {
            displayText: flag_str
            ...
        }
    }
}

 And that gives us something like this:

jcarlson_7-1676392737289.png

So, you can have the font adjust its color, style size, etc., for specific portions of a cell's contents, not just the entire thing. And it confirms that yes, rows in the table widget can be different heights!

Line-Breaking Long Strings

Last item: I want to break up my establishment names into multiple lines of text, but only if they exceed a certain length. Again, I don't need empty lines to show up everywhere, just where it counts. But how do you know where to cut the string? Enter a custom function!

textBreak Function

Here's the text version. Given an arbitrarily chosen character limit (parameter l), I want to take a string (parameter n) that exceeds the limit and find the closest space character, then break the text there and stick the leading text into an array.

If the remainder still exceeds the text limit, repeat the process as needed.

Once our remainder is under the limit (or if the initial string was under the limit already) we put the remainder into the array, then concatenate it with "<br>" separators.

function textBreak(n, l) {
    var c = Count(n)
    var out_arr = []

    while (c > l){
        var nearest_break = Find(' ', n, l-2)
        Push(out_arr, Left(n, nearest_break))
        n = Right(n, c - nearest_break)
        c = Count(n)
    }

    Push(out_arr, n)
    return Concatenate(out_arr, '<br>')
}

textBreak, Portal Edition

As of writing this, sorry Portal folks. You don't get to play with fun new toys like the while loop in Arcade. For now, you're stuck with a couple options. One is to just do a single break and hope for the best. The other is to hard-code additional if statements to evaluate the remainder, and just hope that you added enough iterations to achieve the same thing as a while.

I opted for the single break, since the code is a bit cleaner, and I don't have many values that would need a third (or more) line.

function textBreak(n, l){
    if (Count(n) > l) {
        var nearest_break = Find(' ', n, l-2)
        n = `${Left(n, nearest_break)}<br>${Right(n, Count(n)-nearest_break)}`
    }
    return n
}

 

And the result of all this?

jcarlson_8-1676393554837.png

Excellent!

Other Things?

Honestly, I can't find a good piece of documentation about what HTML tags are or are not supported in the table. Lists appear to be, as well as SVGs. Go forth, and make some fancy tables! Comment below if you find something interesting!

4 Comments
About the Author
I'm a GIS Analyst for Kendall County, IL. When I'm not on the clock, you can usually find me contributing to OpenStreetMap, knitting, or nattering on to my family about any and all of the above.