Alternating row colors

A user recently asked about how to create alternating row colors in Coda. This isn’t a display option we support out of the box, but it’s easy to implement this yourself using conditional formatting:

This works as follows:

  1. Get the ID for each row:
    Row IDRowId(thisRow)

  2. Get the “rank” for each row in the view:
    RankRank([Row ID], thisTable.[Row ID], true)

  3. Highlight even rows:
    Conditional format → Rank.IsEven()

Copy this example to add rows and play with this!

8 Likes

Hi. I’m curious why do you construct Rank?

Would there be any disadvantage to this?

Conditional format: RowId(thisRow).IsEven()

Oh. The id’s can get out of sort. Of course.

This is still useful for quick and dirty coloring that will be turned off later anyway.

thisTable.find(thisRow).IsEven() is also a one-formula solution that’s immune to reordering. :slightly_smiling_face:

3 Likes

Nice! Haha.
We’ve come a full circle.

This is the ultimate one.

1 Like

I don’t have the time to investigate now, but thisTable.find(thisRow).IsEven() is NOT the ultimate one :frowning:

I have a table where it clearly got alternating out of position with some sorts of something…

But I also discovered even the solution with Rank gets out of position. It’s no better than the other solutions on this page.

Searching this forum, I’ve found that a visual rank (immutable ‘row numbers’) is a huge issue in the community, and one that is not necessarily resolved even though there are many recipes.

With that, I’m off. Sorry for the bumpy thread of posts.

Indeed, when applying sorting on a table, the data (.First(), .Nth(…) etc) remains in the same order.

But if you go this way :point_down: then you’ll have your sorting applied on always that one helping column, and you can use that column in a formula to determine sort-agnostic rank: thisTable.Sort(true, Sort).Find(thisRow)

P.S. Just updated the example to reflect this

Yes, a better way to rank rows formulaically is definitely on our list. Today the most reliable option that I know of is to create a Row ID column and then rank by row ID instead of by row.

Why by Row ID and not just by row? What advantage does it give?

The reason you sometimes get stale results is that updating formulas when views re-order isn’t an officially supported feature. In our current implementation, the row ID happens to trigger a re-evaluation while the row reference does not. Longer-term we need a first-class solution for this scenario, so consider the row ID hack an undocumented workaround. :slight_smile:

Pfff… Thanks for the info.

Indeed, a first class solution is needed :slight_smile:

But I tested, and the formula for Find(thisRow) updates when the row is dragged. Or are you just saying that it’s unreliable and may not work in the future?

@cblock see my solution, it’s the closest one, I believe.

Is there a way to stripe that is immune to sorting?

Sorry @alden, I still don’t get it… Could you please illustrate what’s the difference between using thisTable.Find(thisRow) and thisTable.RowID.Find(thisRow.RowID) and what doesn’t work correctly in the former approach?

Hi Paul, not a lot to explain here. In principle there shouldn’t be a difference, but I noticed at some point that there were cases when thisTable.Find(thisRow) gave a stale result after a resort and we haven’t been able to staff the work to look into yet.

If thisTable.Find(thisRow) is working for you I’d say go with that.

Alden

Interesting. I’d really like to catch that issue with stale results.

I know this. If a row is not yet saved to Coda backend, it doesn’t get a Row ID. This is noticeable when many (>10) rows are added at once, or multiple tables are copied into another doc. At this point Find(rowID) doesn’t return proper results until all rows are saved (more here). It does recalculate eventually, but IIRC this doesn’t happen with Find(thisRow), since references are available right away.