Programatically trigger "You have unsaved changes"...
# help-with-umbraco
d
Hi all, I've recently imported products from an external data source into Umbraco and created content nodes for each product. Smooth sailing so far. Along with this, I've included the ability to sync all products, and even sync a singular product from within the product node (from a custom property editor making an HTTP request to my Products Controller). When a singular product sync is completed, I do location.reload() to refresh the node so that the updated property values are shown. However, this made me realize something. If a backoffice user starts manually updating some properties (without saving changes) and then triggers a singular product sync, the manual changes of those properties will not be saved. Hence, it would be really smooth to trigger the "You have unsaved changes" overlay from Umbraco when a user has made changes to a content item and tries to trigger a product sync. Is it possible to programatically trigger this "You have unsaved changes" overlay? Or should I explore an alternative approach?
j
What I usually do is show the imported properties as readonly, and then make other properties to overwrite those values. That way you can import without worry, and the editors can work with things as they want without timing being an issue.
d
I'm not sure I understand what you mean. I should clarify that I have some readonly propreties that are programatically updated by the product sync. However, when I update other properties manually (that are not handled by the product sync) and I don't save, then trigger a product sync, I would like some overlay confirmation to notify the user that there are unsaved changes on the content item.
s
Oooh! What an interesting and fun use case
Which version?
k
you will probibly need to build something with SignalR to achvie that, because you will have to ping the client to tell them updates have happened on the server so it can prompt people before they save.
s
Could you also not save before you do your sync?
d
Yes, that's what I'm going to have to do. But I would like to still give some sort of indication to the user that there are unsaved changes. After a couple hours of research, I stumbled upon a solution. Please let me know if you think it's appropriate or not. In my property editor's controller, I declare the following variable:
Copy code
var contentForm = angular.element('form[name=contentForm]').scope().contentForm;
And then do a check like the following:
Copy code
if(contentForm.$dirty)
To the best of my knowledge, if the above condition is true, it indicates that some property has been modified, hence indicating that there are unsaved changes. Then I can just create my own "You have unsaved changes" overlay which will provide the option to either discard/save changes.
Currently sitting in version 13.0 btw
k
that will tell you if a property has changed in the editor. but if you have updated properties via a sync on the server the properties won't be dirty in the users browser 😦
s
I think that's the desired behaviour though, no? ie, is dirty -> give option to save before pulling in
k
but how are you doing the sync ? or have i miss understood that bit ? - user is editing a page - some background process (on teh server) updates the content editor - user needs to know that changes have happened on the server ? ?
d
I have a button in a custom property editor which the user will click on to trigger the product sync. So the desired behavior is to check whether or not a property has changed in the editor before clicking the sync button
Then the sync itself is a background process that updates certain properties of the product node and saves the node.
k
thats ok, but be aware if the user then saves the item it will save whatever is in the browser state (so what was loaded before the sync happened?).
m
I think what @Jemayn suggests is a good suggestion.. having a process where by you can manually update a property that comes from an external sync is fraught with danger? How do you know which prop you have manually updated vs from the sync? A second editor could come along and simply sync and and wipe out editor one's manual updated?
(and that second editor's content wouldn't be dirty)
indeed two editors could be concurrrently modifying/syncing data?
a yoyo of change and revert to external
if you dupe the props in the backoffice and make from sync readonly.. then any editor coming in can see ah a manual overide from someone..
and if they want to revert to from external then they remove the manual override ?
eg
name (from sync)
and a
name (override)
added bonus you can visibly see what has changed from the sync?
render code just does a is
name (overide)
empty then use
name (from sync)
d
The flow will be the following (hopefully): 1. User clicks on the sync button, this triggers the sync function within the property editor's controller. 2. By checking if(contentForm.$dirty), I can see if a property has changed in the editor. This indicates that some property has been modified, and will be lost if the sync proceeds. 3A. (If the above condition is true): Present an overlay indicating to the users that there are unsaved changes, and they can choose to either a) proceed with the sync and discard the changes of the other properties or b) save the changes and proceed with the sync. 3B (If the above condition is false): Proceed with the sync, not presenting any overlay. 4. In the sync function within the property editor's controller, an HTTP request to my Products Controller is executed, which updates certain specific read-only properties on my Product node, and then saves the Product node. If the previous step is 3A, I'd like to begin by saving to save the value of the properties that were modified, and then proceed with the flow I just described Does this make sense?
The properties that come from the external sync are read-only and cannot be manually updated. I'm talking about other properties on the product node that are not affected by the external sync.
m
I guess what I don't understand in that workflow, is why hitting sync will lose the manual changes, or even why if the are mutually exclusive that you need the save and sync, vs loose changes and sync (can you leverage the umbraco core "leaving this page will loose changes")... if they aren't overlapped by the editable not from sync onesz? (maybe just because you want to refresh the view for synced properties, but could you do that via angular in the backoffice so it doesn't need a save/publish cycle?) You do have the same issue with a second editor synching the external.. wouldn't update the view of the first editor?
Might you be following an antipattern where none editable and volatile properties from an external source are stored as real umbraco node properties? eg might be better to import to a custom table and have a content app that can show them from that custom table? Or a custom property that can fetch from the table and be refreshed client side?
This reminds me of a check-in/check-out implementation that we tried way back with v4.. to stop concurrency issues with multiple editors in the action of updating a node and the last save by the slower editor wiping out updates.. 🙂