Repeating steps using Miracle method. How do I save boolean values for these rows?

So, I’m making an app that shows crochet instructions step-by-step. You can play with the app here or see a quick walkthrough here.

Essential features of the app are:

  • Show instructions step-by-step
  • Keep track of the progress by marking completed steps with a checkmark

All of this is working in the current prototype, but it’s a little “dumb and dirty.” A bunch is going on to enable “Next/Previous” functionality, which I was figuring out here.

Currently, all step-by-step instructions are written row-by-row literally. So each step of the instruction takes a row in a sheet. This is pretty straightforward but inefficient because many patterns require row repeats. Some of them, many, many, row repeats. And if we’re talking about paired items (for example, socks), you have to repeat the whole pattern twice. Not only does it take up many unnecessary rows of data, but it also makes it hard and inefficient to make changes to patterns. I have to remember all the repeat rows I have for each pattern and update the info in each of those rows. That’s obviously not ideal.

While working on adding sizing feature here, I discovered the Miracle method and had an idea. Instead of writing out all instructions row-by-row, including repeats, what if I had an array of unique row ids stored with my pattern, transpose it using the Miracle method, and only kept unique row instructions in the pattern_instructions table?

I made a quick prototype of my thinking here, and it works great for loading the correct instructions:

It most certainly saves me some rows in the pattern_instructions table, even though the row_ids_transposed table will have to be relatively large to accommodate various patterns that can get pretty long. Still, the savings in core tables are so significant that I’m willing to put up with this.

And although loading instructions works great, I lost the ability to save the user’s progress with the boolean column. So,

I’m looking for suggestions on saving users’ progress through the pattern.

Because the row_ids_transposed table is dynamic, its contents depend on user actions. And although each user can only be viewing one pattern at a time (which is why I think this method will work), they might be trying to keep track of progress on multiple patterns at a time. So my thinking is it needs to be stored in the patterns table, in a user-specific column.

How do I save the information from the dynamic row_ids_transposed table to the patterns table and load it when the user opens the same pattern again?

I am looking forward to some ideas! Let me know if you need more clarity.

You are making a big mistake by even thinning of dynamic Rows ID… that is against the concept of a Row ID or any ID… it has to be fixed and unique.
Create patterns by relating to rows ID, and create steps with row IDs, and simply mark which step or a pattern was open… that’s how you will get your progress

Absolutely. Definitely wasn’t thinking of dynamic row IDs. It’s the table/steps that’s dynamic that should load unique row ids applicable for this specific pattern (and size in the bigger app). The problem is that even if I use the “Row ID” column in the app, that same row may need to be open multiple times, which makes the boolean there useless.

I’m not sure I’m following you here. It’s either exactly what I’m doing right now (# of rows used = # of steps), which is not efficient, or I’m a bit lost =) Would love to hear more about this.

how many steps the whole project will have? and it will be a fixed number? (meaning, you create each step, or is generated)

Could be anything =) Depends on the project.
One of the patterns I have currently occupies 222 rows of data (which will have to be transposed in the row_ids_transposed table), but there are only 50 unique rows altogether. And I already have about a dozen of these. Seems like a huge waste of space =)

But there are other positives of keeping the instructions unique. For example, I can reduce the complexity of how my sizing works by not loading “skipped” rows at all.

so… the data structure should be…
steps table…
column 1 - step name…
column 2 - contains joined list of steps to repeat plus current step
column 3 - instructions…
column 4 - math column to calculate stitches.
column 5 - progress boolean

UI should have an inline list of steps… and the detail screen should have an inline list for steps to repeat including a current step… button to mark progress

Trying to think of some ideas. The problem is the boolean column and how to reset it the next time you reload the list. It should be doable to save the the last step to the pattern table, but it might be easier to handle if you skip the checklist layout and the switch in the details. Might be easier to use a button in the details screen with an action to set or unset the boolean.

Just trying to throw out some high level ideas.

Again, maybe I need more detail here… But I’m not sure how it solves anything.
Repeated steps are not always sequential, it’s not always “Repeat step 3 N times.”

Realistically, it could be anything, including but not limited to:

step_name repeat instructions
Step 1 - instructions
Step 2 repeat Step 1 instructions
Step 3 - instructions
Step 4 repeat Step 1 instructions
Step 5 repeat step 3 instructions

And any other wild combinations.


Yes, I’m not married to the boolean here. In the app, I’m actually using “Action text” to pass appropriate values since my detail page is loaded from a dynamic working_row table rather than the instructions table itself.

Here’s a more complex, but more accurate version of the prototype. It’s closer to the real app (there’s the working_row detail page with Prev/Next buttons and Action text to complete/not complete). Again, using boolean here, but it can also be “0/1,” or any other values, I think. Which should make it easier to store it as a joined list, but I haven’t figured out exactly how to store it, lol =)

Open to any ideas!

if repeat steps is a single step, then is even easier… no need to be a joined list…
you can mark the progress with action attached to a button, or to an inline list… depending on what you are marking… if the user clicked the step… or completed the step

I copied your other prototype and tweeked it a little bit. Take a look and see if that makes sense as far as marking a step complete or not. If you skip some beginning steps, it will mark all previous as complete regardless if the boolean is set or not. You can only undo the last step that was completed.

I’m think this would allow for some better actions to save the last completed step to the pattern. I’m not sure yet, if it would be better to save it when the step is completed, or save it when switching patterns.

Take a look and see what you think so far.

EDIT: Slight bug. Give me a sec to fix.

OK, I fixed a couple of things. There’s probably more bugs, but I wanted to give you a quick idea of a different way to mark steps completed or not. It’s a little convoluted and could be cleaned up, but I think it could be a way to allow you access to an action to save the last step to the pattern table, and then when opening the pattern again, a relation and lookup column could retrieve that last saved step and make it part of the logic for the checkmark.

1 Like

This is some kind of black magic :rofl:
My initial reaction was – but it wouldn’t save progress on two different patterns, but it does… How does it work??? :sweat_smile:

I definitely don’t mind this, just need to digest it so I can reproduce it with wider complexity, lol

Well, it isn’t really saving progress. When the transposed list reloads, it still has the user specific checkbox and It only appears to work if both patterns have one of the steps marked as true with the templatemarked column filled with the matching template. (I now realize that I should have set the templatemarked column as user specific, but forgot to do that.)

HOWEVER!!!
I thought about this a bit and I completely re-did my example. Now it’s a heck of a lot simpler and actually saves the progress for each pattern. Every time you mark a step as completed, it will directly write that step number to the pattern table. When you unmark a step, it will decrement 1 from the step number in the pattern table (I needed to do it like this so it would revert back to the last step as the last completed step).

So, instead of setting any boolean in the transpose step table, it’s writing the index number to the pattern table instead. In the transpose step table, I then pull in the saved last step for that pattern, from the pattern table, and set the emoji’s accordingly. This allowed me to easily add a reset button so you can reset all steps in the pattern.

I also made the reset button a two step process, so a user doesn’t accidentally reset a pattern without first confirming that they want to.

Also, I added RowID’s to the pattern table, which I write to the user table, and use for relations. This is safer than using the pattern name (in case you rename the pattern, or have two with the same name). Row ID is unique and guaranteed not to change.

Grab the latest copy and check it out. I tried to mark columns that are new or changed, so it should be easy to follow. And I deleted the boolean column that you had in there. Let me know if you have questions.

NOTE: For anybody else checking this out, this example only works if you sign into the app because of the way that it saves the selected pattern to the user table. This could be redone to use a separate table with a single row and user specific columns, but the user table makes things easier, and for something like this, it makes sense to have to sign into the app anyway. So, either sign into the app, or make a copy and try it in the builder.

3 Likes

This is great! I think it does what I need to do.
My only hesitation would be that it completes all the steps prior to the most recently completed one… I’ve been thinking about it a lot. Seems like a value-add at this time, but something about it bothers me :rofl: I guess I’ll release it this way and see how it goes. If it becomes a problem, I’ll have to think about what else I can do =)

I’ll keep this thread open for a minute just so I can make sure I understand your solution fully.

1 Like

Understandable. I guess my thought was that a user needs to complete all steps in logical order, and the prior steps need to happen before moving onto the next step. I figured that in some cases, a user could have jumped ahead and would have already completed steps 1 and 2, so rather than marking each individual step as completed, they could mark step 3 as completed, which would also mark the prior two as completed. It also made it easier to save a single last step into the pattern table instead of multiple completed steps.

If you still wanted it to save all steps that were completed, and only mark the ones completed with a green checkmark, I think that could be done with a comma delimited joined list that gets saved to the pattern table. Then the IF logic for the emoji could be changed to mark those that are in the list. I could maybe whip something together later today. I guess my question would be, does that mean that you would allow users to skip steps or complete them out of order?

2 Likes

Yes, this totally makes sense. This should usually be the case, but this app is still too new to the audience to say for sure. Currently, crocheters use PDFs to fulfill the need I’m trying to address here, and who knows how they jump around that.

I think my concern is less about that they will want to complete step 3 without completing steps 1 and 2 first. But, for example, many patterns have “parts.” And I’ve been learning that not everyone works on those in the same order. For example, socks might consist of: toe, heel, stocking. But since there are 2 socks needed, there are variations in how you could make those two. For example, one crocheter might go in order: toe 1, heel 1, stocking 1, toe 2, heel 2, stocking 2; while another will try to do: toe 1, toe 2, heel 1, heel 2, stocking 1, stocking 2. Stuff like that. Without overthinking the data structure and trying to let them select parts before they start working on them, listing all steps and allowing users to jump around seems like the leanest and most flexible option.

That said, I’m almost curious to release it the way you propose (prior steps get completed automatically) and see if anyone complains.

I’m assuming that “Reset” functionality won’t be that easy if I go the more flexible route?

Yes, saving joined list to patterns table was kind of what I was thinking of when I started this thread. I think I understand what the table structure needs to look like, where I’m wavering is at what point does it get saved? I think (correct me if I’m wrong), I can only “save” it using a custom action, which means that it probably needs to happen when user marks the row complete/not complete?

Here, try this version. I had to wrap the steps with < > to make sure the Replace column worked correctly and didn’t inadvertently remove the wrong saved step (replacing 1 could have replaced 1, 10, 11, 12, etc, but wrapping it prevents that). I tried wrapping with { } and [ ], but that gave weird results or didn’t work. Probably a javascript or regex issue.

There are two columns, a template and a replace column that are used to overwrite the saved steps in the pattern table based on which button is selected. But, now it tracks each step separately and none of them are dependent on any other steps being completed or not. Each step is marked independently, and all completed steps are saved to the pattern table.

1 Like

This definitely works! It sucks that I’m losing checkmarks on the pattern page, but maybe it’s a small price for saving some rows.

Thank you for your help!

1 Like

Yeah, the problem is things get complicated when you need to set or clear values in multiple rows at the same time. Glide doesn’t have any looping capability. And with the dynamic nature of your table, there would have to be a way to loop through all rows to set or unset any checkmark boolean columns.

Best of luck with your app!

Yes, sounds like another reason for Ability to “Set columns”, “Increment” and “Delete Rows” via multiple relations?

I’ll keep it in mind =)

1 Like