Letter to Santa Claus, cc Coda

Dear Coda and users,
Here is my wishlist for Santa this year. I want full-size clickable image buttons, PreviousRow(), Function calls, and Editable values. More details here:

Hope to get them granted soon! I was nice this year, promise!
Mikaël Mayer

I’m no Santa, but here’s Tic Tac Toe with images within button labels:


Oh that’s interesting. I’m curious. I just asked for request access to this doc.

Oh sorry, didn’t set the doc to be viewable by link.

Buttons are not borderless though. But I’d argue that buttons shouldn’t be borderless. It is important that a button looks like an affordance, not just an inline image.

That’s a great example, thanks for sharing. I cannot duplicate it though to understand how you formatted the first table. It looks like it’s not grouping, since there is no Row/Column fields, what is it?

I’d argue for some cases, a button stops to be a button and becomes a clickable zone.
I mean, if Coda had borderless buttons, we would be able to recreate experiences such as the famous Chips Challenge, but possibly multiplayer.
I know Coda was not designed for these kinds of experiences, but there could be plenty of other experiences where buttons could just become 2D sprites and that would enable prototyping of fun collaborative games.


Agree with all of these!

As you may know though, there is a formula to find the previous row.

RowId column formula is thisTable.Sort().Find(thisRow) and PrevRow formula is thisTable.Filter(thisRow.RowId-1=RowId).IfBlank("")

Make sure the RowId formula sorts based on some column that is meaningful to you. There is no “canonical sort order” for a table. This one is sorting based on the Display Column, which is Name

1 Like

Thanks for this trick, it’s still good to recall it for new readers. I would even add .Last() to get theh last row instead of a singleton list of one previous row - but then it would not work with IfBlank.
I did not know about the IfBlank trick though, it’s nice to have it.

Your idea of using Concatenate, _Button, and other formulas was awesome.
I was able to create a multiplayer Rollit game following the same concept:

did you consider an approach by which you replace the RowId by a flex variable via:


building the previous value goes then as follows for natural numbers:

thisTable.[column you refer to].Nth(Find(thisRow,thisTable )-1).

Cheers, Christiaan


Right, this is a better approach since Nth() does not create a new collection. Thank you, I did not know Nth().


#3 - you can accomplish a similar result with buttons; make the button perform the function and then you can call the button in another formula. This is also great for cleaning up your doc/code.

#4 - you can accomplish this by making the text string that is being displayed a canvas formula or a row reference using the @[DisplayColumnValue] which calls a value in a row. I will create a Variables table and then @RowReference.Value to get the value. An advantage of using a table>canvas formula is that you can modify table values.

Good luck! :santa:

1 Like

Once again, the problem with Find(thisRow, thisTable) is that there is no canonical updating order to a table, so this will just be the visual order. The benefit of the Sort() based method is that you can be assured of the order of the inputs.

Imagine you have an order that’s governed by a table level sort (like Date Descending), but then someone wants to see the data in a different way (Date Ascending) and changes that sort—it would mess your formula up. It’s better to perform the sort in the formula where it’s needed than to on external table states.

If you really wanted to do it in one formula you could with:

  thisTable.Sort().Find(thisRow) - 1 = thisTable.Sort().Find(thisRow)

But since there is no variable aliasing (yet), this means that you will end up calculating thisTable.Sort().Find(thisRow) twice, which is why I cached it in a row (RowId) in the prior solution

@cnr, what are the use cases you have in mind for the ‘previous row logic’?

Use case for previous row Id are simulations of iterative formulas: Mortgage financement, savings estimations, Intermediate sums checkups.

Another useful idea for that would be to have a Fold operator, that can iterate a formula a number of times:

Fold(list, formula, VarLisr, VarCumul, StartCumul)

e.g. to compute savings of a 1% yearly plus 100 added every year, over 20 years


Sequence(1,20).Fold(s*1.01+100, i, s,0)

But again, we would need to pass a formula for argument, not a value, like Call should do.

thanks @Mikael_Mayer,

in this post you find the Power() formula that might be useful for some of these cases :

I use the PrevRow logic to create complex timetables and I do a bit of financial work as well

cheers, christiaan

So, in the case that you use PrevRow logic for timetables, you’re probably sorting each row by datetime (I’m guessing). In that case, you really want to be doing that sort in your formula itself, that way to can change the order of the underlying table and not have any problems.

However, if what you want is the visual order of the table, then Find(thisRow, thisTable is the correct approach

yep, timetables are not date based, but based on hours (max 24 due to driver time restrictions), in this case I use the Find Logic

I tested the Prev Row based on RowId, but once you delete or change the order of rows, it breaks.

Yeah, don’t actually use RowId, I should have given the column a different name like ‘RowIndicator’ or something of the sort.

the formula thisTable.Sort().Find(thisRow) should always work, even after deleting rows