My client has an issue where WebDirect users are not committing their edits.
I figured I could add a bottom navigation with a cancel and save button that would conditionally change format when the Get ( RecordOpenState ) is open. That way the user can see a green save button when the record is in an open state.
The problem is that the window or buttons require a refresh to trigger the conditional formatting. Adding a refresh script to the OnLayoutKeystroke Script Triggers works for desktop but not WebDirect
I'm one of those devs who doesn't like to use On Timer window scripts, because I am concerned that a periodic script firing off will get in the way of the user as they work in the screen that they are on.
That said, I might consider it in this case. Supposing there were an On Timer script that fires fairly frequently but then cancels itself when it's no longer needed.
- Script checks Get( RecordOpenState ).
- If record is closed, exit.
- If record is open: Refresh the appropriate layout objects and then cancel the OnTimer so that it is no longer called.
The idea is that, once the record is known to be open, there's no reason to fire the script again, because we know that the record will remain open until the user clicks the Save button, and whatever script handles the Save can take on the burden of re-setting-up the On Timer, if needed.
If I've thought this through correctly, it means that the On Timer only has the potential to interrupt the user once, which would be the first time that it fires and it discovers that the record is open. Until then, presumably the user is not trying to type into a field or do some other action which the On Timer could disrupt.
EDIT: I guess there would also have to be some sort of handling of the case where the user leaves the layout without ever opening the record, in which case, I suppose there needs to be something to conditionally disable the On Timer.
I suggest splitting the layout into two layouts: one for viewing and finding; one for editing. Users would need to click on an "edit" button to switch from viewing / finding to editing. The edit script would first check to see if the record is already open for editing before navigating to the edit layout and opening the record for editing. A timer could ensure that users who take a lot of time in the edit layout are kicked out under certain condition. Save would perform any validation and handle errors and cancel would revert the record. Probably best if the edit layout can't auto-save a record.
IDLE_Commit.fmp12 (280 KB)
Something I built for a large webdirect solution having the same issues.
It's an onTimer designed to silently commit users records when not active.
The basic concept is when the users cursor is in a field it will store into a global variable some information about the users current state. This includes the current fields value, record open state, and a few other things.
This information goes into a specific repetition in the global variable which corresponds to the window name (allowing us to capture state for multiple windows in a solution).
If the stored state (from the last time run) is the same as the current state, we deduce the user has done nothing in that time, and so commit the record.
If the states are different, we assume the user is actively engaging with the record and updating it, and so we do not commit and allow them to continue editing.
The main reason for this is for committing in situations where the user is inactive in an open record.
Has worked fine for us so far.
I also wrote an article on this for more detail: https://www.teamdf.com/blogs/idle-release/
Thanks for the quick replies. I will explore the timers and perhaps, as @bdbd suggested, reconsider the UI. I see a card window works in WebDirect. That might be the UI approach to help clarify to the user that the record is in an edit state.
Here is my current test ;
- every field (~30) triggers a RefeshButtons script via the OnObjectModify trigger.
- the same script is called via OnRecordCommit.
So far, so good. The buttons are in their correct conditional state during an edit and when creating a new record.
[side note]: the Command-Option-A shortcut (Select objects of the same type ) made setting the field trigger script easy.
I also use a display layout and open a card window for editing. However, I make the entries/changes in global fields. When the card is opened, these are filled with the existing values. After clicking on a save button, the new values are written back to the actual data record. As this is scripted anyway, I can also do the logging at the same time.
This way records are locked just for a second or less. And I can do logical validations if neccessary.
You just have to think about how you want to handle it if someone else has changed the record in the meantime.
I am currently trying out the best way to handle this: Set a flag so that others are warned if they want to edit the record while I'm in there. Compare hashes before/after. And so on ... I'm still working on this.
But any autosave action I want to avoid. This way I have no idea in what state the record remains. You can have done half of the changes, walk away and the system saves. That's really not what I want!
One idea: If another user has changed a record that was flagged "open" in the meantime, I get info about who has changed what since I had opened the record. So I can decide what to do.