Dynamically name repeated {formtext}

The repeated formtext is already populated and any input, in any of the repeated forms, changes the input in every formtext.

Items: {formtext: name=itemName}
Price: {formtext: name=itemPrice}
{formtoggle: name=add item(s); default=no}{note}{formtext: name=numLines; default=1}{if: numLines<1}{error: Should be >=1; block=yes}{endif}{endnote}
{repeat: for i in seq(1,numlines,1)}
Item {=i+1}:
Items: {formtext: name=itemName}
Price: {formtext: name=itemPrice}
{endrepeat}{endformtoggle}.

My solution is to change the name (i.e. itemName1 & itemPrice1) of the repeated formtext, but my actual snippet is more intricate than the above example and requires a lot of duplicating and renaming.

Items: {formtext: name=itemName}
Price: {formtext: name=itemPrice}
{formtoggle: name=add item(s); default=no}{note}{formtext: name=numLines; default=1}{if: numLines<1}{error: Should be >=1; block=yes}{endif}{endnote}
{repeat: for i in seq(1,numlines,1)}
Item {=i+1}:
Items: {formtext: name=itemName1}
Price: {formtext: name=itemPrice1}
{endrepeat}{endformtoggle}.

I'm wondering if there's a simpler solution and if my current solution has any issues?

Hi @latetotheparty, as a simpler solution(as you are not using the formtext value anywhere else) you can avoid setting the name property of the formtext.

Let me know if this works for you.

Items: {formtext}
Price: {formtext}
{formtoggle: name=add item(s); default=no}{note}{formtext: name=numLines; default=1}{if: numLines<1}{error: Should be >=1; block=yes}{endif}{endnote}
{repeat: for i in seq(1,numlines,1)}
Item {=i+1}:
Items: {formtext}
Price: {formtext}
{endrepeat}{endformtoggle}.

This solution works only in this instance.

As previously stated, my actual snippet is quite intricate with several formtext, formtoggle and formmenu being imported from other snippets.

Ideally, I would like to use repeat to import the snippet but be able to set the name dynamically.

If that is the case then your second solution is good to go. All the variables you create inside {repeat} is scoped to each instance of repeat and is not linked with other instances. You can read more about it here.

If you need more help shoot me an email at aditya@blaze.today and jump on a call to understand your actual use case.

Updating this thread because we (me and @latetotheparty) recently had a call to discuss the problem. The aim of the thread is to avoid conflicts between items with the same name.

The solution is to use the {repeat} over all the fields of the snippet. The modified working snippet is like this:

{formtext: name=numLines; default=1}{if: numLines<1}{error: Should be >=1; block=yes}{else}{repeat: for i in seq(1,numlines,1)}
Entry {=i}:
Items: {formtext: name=itemName}
Price: {formtext: name=itemPrice}
{endrepeat}{endif}

In the snippet above, you will notice that items and prices from each entry don't conflict with each other.

This also works when you have {import: /snippet} commands inside the {repeat} block. They all work independently instead of conflicting with each other.

2 Likes