As of now, AppSheet does not natively support primary action buttons in table or deck views. I've already submitted a feature request, but until it arrives, we’ll have to get a bit creative… okay, a bit hacky too 😅.
This tip can be adapted to any use case, but the example we’ll use is: generating a PDF containing data from child records, selectively triggered from a button in the parent table. The trick lies in creating an intermediate form that acts as the launcher of an automated process.
From the parent table, the user taps a primary action button.
This button opens a form based on a minimalist slice of the same parent table.
The form includes an EnumList
field (base type Ref), where the user selects the parent records whose child records will be processed.
When the form is saved, a temporary helper row is created.
A Bot detects this row and launches a chain of actions.
Actions are executed on the selected child records.
Finally, the helper row is deleted.
[action_confirm]
[parents]
This slice will be the source for the form view. It must allow adding records, and include at least these columns:
[RowNumber]
[ID]
[parents]
Make sure only the [parents] field is visible (unless you want to show others).
Position: Ref
Event Actions - Auto assign: Go Back
Type: Go to another view within this app
Formula: LINKTOVIEW("items_slice_form")
Position: Primary
This action will appear as a primary button in table or deck views.
Event: App data change (Adds or updates)
Condition: [action_confirm] = true
Table: Parent
Action type: Execute an action on a set of rows
Target table: Child
Rows to execute on: FILTER(
"Children_Table",
IN([parent_id], [_THISROW].[parents])
)
Action to execute: Could be generate PDF, update rows, send emails, WhatsApp, etc.
Type: Delete
Table: Parent
Condition: Leave it blank if this comes after your main process — the record will simply be cleaned up.
This auxiliar row is not intended for end-users — it’s a purely internal trigger mechanism.
You can hide it from views or display it in a debug/admin view if needed.
With this method, we can simulate a primary action button that kicks off complex processes like document generation, multi-record updates, batch communications, and more — all without SELECT() and without unstable hacks. Just pure AppSheet logic.
This pattern also sets you up for even more advanced use cases like: sending batch emails or WhatsApp messages, generating grouped reports, flagging records for review, and much more.
The important thing is that you understand that the primary button takes us to a slice-based auxiliary form, and then, when you save, it creates a row in the base, triggers a series of actions, and then deletes the row.
I hope this helps, and I apologize for any previous misunderstandings.
This seems like an interesting idea but sadly the steps lack too much detail to follow. By step 2, there are already questions. For example for the line that reads:
I guess the reference to True is not needed and the Initial Value should simply be the Context statement? The "NewViewBasedOnSlice" should refer to the name of the form we are about to create in the next step? Perhaps?
It just got worse after that. @Gustavo_Eduardo it would be good if you could come back and edit this or provide a sample app to show what you intended. Thanks
Dear AppSheet community members, I sincerely apologize for uploading this tip without having fully reviewed it (perhaps I did review it, but at the time of uploading, I was very busy and must have pasted something that wasn't checked). In any case, I want to especially thank the user @alphacp because (although I received 4 likes, and those likes made me think things were going well), he is the only one who took the time to read it and saw that it didn't actually work.
Well, thank you very much @alphacp . I have corrected it now. Please let me know if it works for you, and if not, I will gladly help you solve the problem. Greetings from Argentina.
Thank you. I think I am making progress but still a little confused by the recommended actions in step 3:
The LinkToForm() that is called in Step 4, will open the form but will assume create a new record but in Step 1 you said to only allow updates on the slice. So this errors and perhaps this is where your tip regarding a label field comes in to play but I tried everything I could think of to get around this so maybe the last bullet is important but I could not get my head around that either, sorry.
I think I perhaps need I need to add a Row key, or perhaps there is a second table at play here?
Ok @alphacp I've modified it. Please take a look and let me know if you have any questions. Best regards, and again, thanks for letting me know.