How do I detect when a user is not on the site?

The Situation:
In my app users edit data on a page by clicking edit to switch to edit mode for a particular Product Group, edit one or several fields, then click Save or Cancel. When they initially click edit, that Product Groups is locked so that other users can’t edit at the same time. As they are editing, the app is creating temporary records in the db (marked by a temp field), which are converted to permanent if the user clicks Save or deleted if they Cancel.

The Problem:
If a user happens to leave the page or the site entirely in the middle of editing, having made some edits but not clicking Save or Cancel, then:
A) these temp records persist
B) the Product Group remains locked so that other users cannot edit

I looked for solutions that involved detecting page exit, tab closing, etc and found other people asking questions but no answers, like this one.

I think if I had a way of having a back end workflow detect whether or not a user is logged in I could run some sort of cleanup, either in a database triggered event or a scheduled workflow, but it looks like that’s not possible?

How would I go about detecting whether a user is actually on the site currently, or trigger some change when a user enters or exits the site (not necessarily the same as logging on or off)?

Are there any other ways I might solve this issue?


Additional info based on comments from @mikeloc and @ntabs

The reason I don’t think custom states would work is that when I tried them the save function took a long time. I get what you’re saying about moving that workflow server side, so I need to clarify: I think it’s not actually the DB actions that are causing the time, but the looping on the client side. Here’s my setup for editing:

This is showing one Product Group in edit mode. Here there are only 3 rows of 4, but it could be as many as 10 rows of 20. # of rows is variable and the user can add more or less, so they are a dynamic repeating group. The number of columns is also variable between Product Groups, though as you can see within a Product Group like this one it is consistent. The point is, I have to use nesting repeating groups for this.

If I’m using custom states in each cell, I have to use the Musicians plugin and iterate through every cell to get its custom state and save it individually. I think that’s the slow part, and not something I can pass to the server. That’s why I rebuilt it to create the actual records marked as “temp” - when the user clicks save, it just updates anything marked temp as not, and if they click cancel it deletes them.

Maybe there’s a different way to do this with custom states, such as storing them outside the repeating group so I don’t have to iterate through every cell upon save. However, that presents its own set of issues I’m not sure how to solve.

Hope the explanation is clear, certainly open to any ideas and thank you for your help!

Hi there, @johndurso… I could be off base here, but a thought that comes to mind is to possibly avoid the locking issue and the temp records altogether by using custom states to hold a user’s edits until they save them. Before I go too far down this path with any sort of explanation as to why I think custom states might be a potential solution, have you already considered using them, and is this path a non-starter for any reason?


Good question, I actually had that as a solution originally. The issue was that the save action then took quite a long time as there might be a good deal of records to create and delete with that one action.

Also, that would only be a solution for A), not for B), which is necessarily stored in the database so that when other users view the Product Group, it will show as locked.

I must have misunderstood because I thought you were just making changes to one or more things when the save button is clicked, and those actions shouldn’t take that long. You could also consider making the changes via a backend workflow, too.

As far as locking the record is concerned, I was thinking the locking wouldn’t be necessary if you were using custom states. True, two users could technically be editing the same record at the same time, but because the edits would be stored in custom states until a user clicked save, I don’t necessarily see why it would matter that two users were editing the same record. If one of the users saved their changes and then the other user saved their changes right after, it would be the same as if the second user waited for the record to become unlocked and then made a bunch of changes that may or may not undo some of the changes made by the first user.

Anyway, it still seems to me like custom states could work, but that’s probably enough out of me at this point because I don’t know enough about what’s really going on in your app.

I may be missing out on something but IMO, you can use custom states like what @mikeloc just mentioned and use backend workflows instead to push the workflow to the server side or if you want to do it on the client side, you can use loaders instead for better UX.

Also, if you’re trying to check if user is still logged in after x time, you can probably do have a workflow to check it very x seconds like this

Here’s an example of 5 minutes

@mikeloc @ntabs since both of you suggested custom states, I edited my original post with an clarification of why that wasn’t working. Let me know what you think!

@ntabs I did actually implement a solution like that for when they’re idle on the page, but it doesn’t solve for my issue, what do I do when the just leave the page or close the tab?

This topic was automatically closed after 70 days. New replies are no longer allowed.