Button to uncheck checklists

Does anyone know if it’s possible to create a button to uncheck a checklist within a table? (Not a checkbox column!)

image

I’d like to create a recipe repository with checklists for ingredients + steps (so I don’t lose my place when I’m cooking!) and be able to clear all steps before I start a new recipe – with the grain being a single recipe, rather than having to have a table with a checkbox column and row for each ingredient / step!

2 Likes

Hey @Marissa_Griffin ,
I only know a very “hacky” workaraound, that uses an experimental hidden formula of Coda. These formulas need to be used with caution, because they could also break one day. This is also probably more advanced, but I try to explain it in detail and step by step and provide a demo.

Click here to Show Demo

Approach
The use of the inline checkbox makes a complex object out of the normal text. That is why we can not just “replace” or “uncheck” the checkbox inside your textcolumn.

But with experimental formulas, we can have a look into the complex object, edit the object to our need and then put it into the column again with a button.

Step-by-step

  1. I made column called “Ingredients_raw” where I output the JSON of the “ingredients” list with the formula
    ingredients._merger()+"".
    When you have a look at the output now, you can spot our desired part: “isChecked”:true or “isChecked”:false. You will see that these values change when checking/unchecking a checkbox in ingredients.

  2. Now I make another column “ingredients_unchecked” with the goal to replace every checked checkbox to an unchecked one. I do this by using regex replace: thisRow.Ingredients_raw.regexreplace('"isChecked":true','"isChecked":false' )

  3. Now I need to make the output to something a human can read again. Therefor I made a column “Ingredients_reset” where I parse the raw JSON that we just produced in step 2 with the formula:
    ParseJSON('{"o":'+thisRow.Ingredients_unchecked+'}')
    Now you can already see our empty check boxes, but since this is a formula now, you can not interact with it.

  4. Last step is to make a button column. The button is a modifyrow button which fills in the content of our “ingredients_reset” into the “ingredients” column
    Bildschirmfoto 2021-08-17 um 07.36.18

  5. Repeat the steps for the “steps” column and hide the ugly helper columns…

From what I know right now, this is probably the only way of achieving what you want to achieve. Hope that helps for now :slight_smile:

P.S.:Thanks for the recipes! The pile of powder was a little bit dry, but I just added 2 pounds more sugar to make it work for me :crazy_face:

5 Likes

Thank you, Daniel!!! I see what you mean by this being workaroundy, but you totally found a way to do this and taught me something new! I didn’t know about these hidden formulas – I was trying to do regexreplace without converting to/from JSON and it couldn’t find the checkboxes! (I’m also a lil scared of them now after reading the post you linked, hehe.)

The only other idea I had was to create “base” columns that get copied to “live use” columns via a button (and hide the base columns) – you then need to either remember to edit the base columns if you want to edit the recipe or create another button that copies your “live use” column back to “base”. It’s roundabout :'D but generally works & maybe safer than hidden formulas?

P.S. Ahaha, I’m glad you appreciated all of the creativity my brain could get to last night for example recipes :joy:

5 Likes

@Marissa_Griffin
that is a wonderful solution and way simpler then mine!

The only downside is that you would have to make changes in two column, but depending on your “Edit Recipe” workflow, this could be managed with Pauls modal insert/edit workflow, you can easily automate this.

Btw, the doc looks very cool! Will this be a public recipe list/cookbook?

I’m thinking about it if this goes well! It’s more for fun, but if others can use it, I’ll share out!

I’m still debating where to focus the doc – 1) have a section for restaurants and a section for recipes, and then has a short quiz + random entry generator to help answer the question of “What should I eat?” :stuck_out_tongue: , or 2) focus more on the recipes and build functionality to generate meal plans + build shopping lists from the recipes you chose!

3 Likes

I’m having so much fun reading this thread :grinning:

Great workaround @Daniel_Stieber!

Marissa, both ideas sound super fun! In my case, I’d love to have a way to cook something based on a) what’s available and b) random ideas. Please share what you’ll be building, I’d love to learn more!

2 Likes

@Daniel_Stieber

I would not have figured this out, I used your solution but put the following formula in a button and got rid of helper columns:

ModifyRows(thisRow,
   [Table 1].[Ingredients],
   ParseJSON(
      '{"o":'+RegexReplace(thisRow.[Ingredients]._merge()+"",'"isChecked":true','"isChecked":false')+'}'
             )
          )

All credit goes to you!

1 Like

@Daniel_Stieber et al:

A very good practice is to ask oneself: do I really need to do something, or is there an easier way.

Or, “Do I need to resort to deep object modification” in this case :slight_smile:

If

  • you need to uncheck all checklist items in a text field
  • and every line in that text field is a checklist item

the task can be rephrased as “Turn each line of text into an unchecked checklist item”.

This can be solved much more easily by splitting the text down into lines and then concatenating all together with a checklist item format :slight_smile:

The format string should have an unchecked list item on a single line (no text) and a trailing newline so that items are properly joined together and formatting is not reset. Then we have to Concatenate() that format once again and Trim() the trailing space:

thisRow.Ingredients
  .Split(Character(10))
  .Join([Unchecked paragraph with newline].Format)
  .Concatenate([Unchecked paragraph with newline].Format).Trim(),

The trick here is knowing that when you do

  Concatenate([Text A], [Text B])
  or
  List([Text A1], [Text A2], ...).Join([Text B])

then the last line of Text A receives paragraph formatting of the first line of Text B.

3 Likes

Hey Paul,

Very smart, thank you, this is a lot more efficient and does not rely on undocumented formulas.

I can reproduce your formula, but I find it hard to exactly understand what is happening, it feels not very logical that split() on character(10) and joining with the ‘checkbox’ gives this result, because character(10) is a line feed. So I am wondering how a ‘checked box’ (or unchecked box for that matter) disappears in this scenario - even though I see it happen.
Is the checkbox in coda a format or object, rather than a character. And if so, can it not be referenced (other than in JSON)?

Correct, the checkbox is not a character on the line but a piece of metadata on the rich text field.

image

1 Like

Hey @joost_mineur that is a great reduction :slight_smile: I used to make a lot of helper columns to better describe processes and in some cases it even speeds up actions and buttons, because the results are cached in the column already.

E.g. in our case here (as far as I know) the reset button would execute faster with the helper column, as the RegexReplace result is already cached in there and not executed live at button click. With heavy actions, this could make a difference.

But in the end, I learned that all from @Paul_Danyliuk , and he even provided a so way without hidden formulas. so all credit to him :smiley:

Thank you all for the solutioning – I’m having a lot of fun learning new things from you all! I’ve tried all of your solutions and ultimately went with Paul’s split/join/concatenate solution!

Takeaways:

  • The extract JSON solution is elegant and I wanted to use it, but it seems to return results as a JSON – which Coda detects & display prettily on the column, but the button gets confused and can’t parse it a 2nd time it seems.
  • The split/join/concatenate solution totally works for a single checklist. I did have to do some funky things to make it work if there are “sections” of ingredients, i.e. Sauce Ingredients, Main Ingredients, Toppings/Garnishments, which I hope to streamline further when I get more time!

I’d love this to be natively supported one day, but I’m happy it works at all for now! I’ll likely share my doc on the gallery for those interested soon. Thanks again!

2 Likes