Home / Blog / FileMaker / Easy FileMaker modal edit dialogs with full rollback support
25Aug 2012

Easy FileMaker modal edit dialogs with full rollback support

About the Author

Artie Brosius

Artie holds current certifications in both FileMaker and Salesforce, but also works with a number of other languages and technologies. When not at work, you can usually find him chasing around his two school-age sons, watching the Red Sox, playing the bass or reading a programming book.

Comments (26)

Bruce Robertson - August 27, 2012

Very nice! I’m wondering about a tweak to the Cancel script.

Is there a way to detect that in fact no edits have been made and just allow the Cancel script to proceed? We can get(recordModificationCount) but that doesn’t seem to do the trick.

Artie Brosius - August 28, 2012

Great thought, Bruce.  Yes, that would be a really nice enhancement, and certainly would provide an experience that users have grown accustomed to with other platforms.

It's a tricky problem.  As you said, Get( RecordModificationCount ) doesn't work, because it only counts commit operations (which we're suppressing in this technique) and it also only counts the parent record.  Commits to the child records in portals wouldn't be captured by Get( RecordModificationCount ) from the parental context.

The most sure-fire way I could think to do this is to put OnObjectSave script triggers on each and every field, including fields in portals, and count the number of times the script trigger fires.  If it fires more than 0 times, some field, somewhere on the layout has changed; otherwise FM wouldn't fire the trigger.  That solution seems a little inelegant to me, though.  

Another way is a little more involved, but might just work, and it could be a generic solution that would only have to be coded once.  The general idea would be to use the FieldNames() function to retrieve a list of fields on the layout, including fully-qualified related field names, then use this list to construct a SQL query that retrieves the values for these fields.  This routine could run when the popup opens and then again when the user presses Cancel.  Using some kind of hashing function on each query result (to reduce the long string to a shortened but unique "key"), if the two hashes are the same, no Revert Record step is necessary.  I'm taking inspiration from a great talk Todd Geist did at Devcon this year on writing re-usable code.  With the use of ExecuteSQL, this would obviously be a FM12-only solution (or would require a plugin).

Chris Stapleton - September 3, 2012

No need to use ExecuteSQL if you don’t want to, evaluate will work just as well for capturing the current value of all fields on a layout into a global variable (using FieldNames() as you mention) and similarly capturing the values at another time to see if changes have been made and again if required resetting the field values. These methods can be made to be completely generic – I have rolled mine into three scripts, recordSnapshot, checkSnapshot and revertSnapshot. This method allows committed changes to be reverted.

HOnza - September 4, 2012

Great tip!

It’s often overlooked that besides performing actions script triggers can be also very helpful in avoiding certain actions.

Not only makes it easier to roll back unwanted changes but also saves processing time by doing just one instead of multiple unnecessary commits.

Brad Stanford - September 4, 2012

One of my techniques is to load the entire record into a variable as XML whenever the user selects it. I then can compare each field to its XML brother as necessary. Yes, the FieldNames () function is the way to go for sure.

Brian Rich - September 5, 2012

Great idea, I’ve already implemented it in two or three places in my current project.

I got caught out when my edit window contained a global field. These aren’t reverted if they are edited.

Artie Brosius - September 10, 2012

@Chris Stapleton –  Good idea to use Evaluate() and store in a variable.  I'll have to try that.  Thanks!

Artie Brosius - September 10, 2012

@HOnza – I hadn't thought of the effect on processing time, but surely it should help some.  Not sure how expensive a "commit" is relative to a "save and commit".  Would be interesting to test.

Artie Brosius - September 10, 2012

@Brad Stanford – That's a nice idea too.  Thanks!

Artie Brosius - September 10, 2012

@Brian Rich – Glad you like the technique.  Nice to know that you're getting a chance to use it.  Yes, global fields are a complication.  What did you do in that case?  Store the value in a variable?

Josh Ormond - November 17, 2012

Great article. This is one of those techniques that often comes in handy. I’ll be adding a couple tweaks to my current process, Thanks.

As a standard practice, the only thing I tend to do different revolves around the isolating of the record. I started using a strict ‘Perform Find’ using the UUID to isolate the record…Instead of:

Show All Records
Omit Record
Show Omitted Only

I’ve found 2 benefits:
(1) Performance is better. Showing all records forces FM to download at least 25 records to the local cache file. While it applies to even local files, the hit over a WAN can be much more ‘visible’. Plus it is one step instead of 3.

(2) Potential danger of other records being created at the same time. For example, if someone else creates a record between when you ‘Show All Records’ and ‘Show Omitted’, it gets added to the ‘Omitted’ records. Showing Omitted Only will now show you more than 1 record, leaving unintended consequences. It may be rare, but I’ve actually seen it happen more than once in a solution with with only 3 users.

Artie Brosius - November 21, 2012

@Josh Ormond  Josh, thanks for your comments.  Yes, great point about the sequence to isolate a single record.  Thanks for adding that!

Darren Burgess - June 25, 2013

Thanks for sharing this Artie. I was about the go the route of global variables or fields. Saved me a ton of effort.

Darren Burgess

Artie Brosius - June 25, 2013

You're quite welcome, @Darren.  Glad you found it useful!

Lorena - October 22, 2013

I was excited to try this method out…but quickly discovered it didn’t do what I expected it to. I was expecting the parent window data to actually keep the original values until you committed the records. Is there a way to do that? My reasoning is that I am wanting to use the original values (in the parent window) and the new values (in the edit window) to create a history record in a related table when different. The problem I am running into is that it is only seeing the last field as different, because all the other fields have already changed. I have also been considering using the FieldNames () Function. Any thoughts would be helpful. Thanks.

Artie Brosius - November 4, 2013

@Lorena, you are correct; this technique alone won't accomplish what you're looking for.  The values in the new window are "saved", and therefore changed, even though they aren't yet committed to the database.  You could look into crafting a solution based on "OnObjectSave" for field(s) you're interested in tracking.  Or you could manually save all the values of the record to a log table as the window is opening (and/or closing).  This would preserve a snapshot of the record before modifications.  If you're looking for really robust field-level tracking/logging, I would look into the products from SyncDek at 

Mike - February 18, 2014

Artie – This is great! I’ve already used it in three places in my current project, so thank you.

One quick question re: rollback functionality with data shown via a portal. I have a sales order layout with a line items portal. If I edit the current sales order record and add a line item in the portal records, all of the changes made to the sales order record “roll back” when I cancel the edits, but any line item records added or deleted in the portal are not rolled back. Am I missing something?

Thanks again!

Artie Brosius - February 19, 2014

@Mike, I'm thrilled you find this useful!  As for portal records, I'm not sure what would be going on in your solution.  Certainly the technique should work for portal records; in fact, that was the original inspiration for developing the technique.  If you haven't looked at it lately, I would look back at the demo file again and see how it was done.  Perhaps you can see what is going on in your own file?  If that doesn't work, feel free to reach out to me back-channel at abrosius at soliantconsulting dot com

Gale - February 12, 2015

This is a great technique.

Philip Kushnir - February 26, 2015

I use not isEmpty ( Get ( ModifiedFields ) ) to determine if any changes have been made to the record. If not then no point in showing the user a dialogue to save changes. That combined with the above technique works great.


Shane - March 17, 2015

Thank you for this great tip, Artie. Please excuse me for any dumb comments or questions, as I’m very new to this software.

1. Where in the script are the “Save” and “Cancel” buttons created in the new popup window? Mine are not appearing for some reason.

2. For some reason, the OnCommit script, which I’m calling through the On Record Commit script trigger, is making my entire application unusable, unless I close it through task manager (can’t seem to close it any other way) and reopen it. Everything is fine until I try to make a change, or hit the “Edit” button I’ve created. However, once the new window appears, I can edit fields and whatnot. I just can’t save the changes, or even close the new window. Maybe it’s because my “Save” and “Cancel” buttons aren’t there?

Any help would be greatly appreciated.


Wim Decorte
Wim Decorte - March 18, 2015

Hi Shane,

Buttons in FileMaker are not defined in a script, you add them to the layout while in Layout mode.

The reason why your file seems to hang is that the OnCommit script prevenst the commit from happening until the global variable $$allowCommit is set to 1.  That variable is set by the buttons that are missing from your layout.

You can see this happening by leaving the Script Debugger on and tryng to close the window.  With the Script Debugger you can them manually move the execution point to the step that says "Exit Script[ 1 ]" which will allow the commit and close the window.

Per Enström (@EnstromPer) - August 31, 2015

Hiya, wonderful guide! I was wondering if you have any suggestions on how to create modals in list view. My solution needs a modal to show a list of records with an “ok” and a “cancel” button.

I’m thinking that I might just send the user to the modal and end the script and then pick up with another script based on the two buttons. But I thought I’d explore this solution first.

    Wim Decorte
    Wim Decorte - September 2, 2015

    Hi Per,

    Modality in FM has changed a fair bit since this article was written. You can now use native modal windows by using the Advanced settings on the “New Window” script step. That makes it easy to create modal windows, even for list views.

    Your basic approach is solid: take the user to a new modal window, provide “ok” and “cancel” buttons to close the modal window and proceed with what is required.

    Keep in mind that this article was written from the perspective of being able to capture edits that a user makes to a record. Trying to do the same for a list view is a lot more challenging.

    Best regards,

nuriozbilenler - February 12, 2016

Thank You.
Portal ?


Leave a Reply