27
Views
6
Comments
Solved
Auto Save Form And Auto Retrieve

Hi Team, 

I am creating one form In Reactive Web application with the feature of auto-saving the form and auto-retrieving form data.

For that I am using JavaScript and JSON serialization for storing data in local storage in the device, and for retrieving the data I used JSON deserialization.

JSON serialization output is saved in the database, but when I retrieve that data from local storage using deserialization, I am not getting data.

Could You Please tell me where I made a mistake and How to solve this problem?

Also, I am attaching my OML file; just check it out.

UserName: Omkar

PassWord: Omkar@123

Thanks.


FromAutoSave.oml
2019-01-07 16-04-16
Siya
 
MVP
Solution

Ok. Let’s keep it simple. You will need to create 3 generic Client Actions and 3 generic Server Actions, plus a demo screen to showcase the functionality.

Client Actions

  1. SaveDraft(KeyId, JSON)

    • Save to Local Storage using the existing JS code.

      • Use GetUserId() instead of passing UserId.

    • Call the SaveDraft Server Action.

  2. LoadDraft(KeyId)

    • Load the JSON from Local Storage (similar to current code).

      • Again, use GetUserId() instead of a parameter.

    • If no Local JSON is found, call the LoadDraft Server Action.

    • Return the JSON.

  3. ClearDraft(KeyId)

    • Clear the JSON from Local Storage using the existing JS code.

    • Call the ClearDraft Server Action.

NOTE : Ensure that you use the same key in JS. I have noticed that it's different in SaveDraft - its is prefixed with "draft_" where as in Load and Clear the 'draft_' prefix is missing.

Server Actions

  1. SaveDraft(KeyId, JSON)

    • Retrieve the record for KeyId and UserId from the Draft Entity.

    • If found, update it; otherwise, create a new record.

    • Always use GetUserId() (no parameters).

    • Do not fetch all records and then filter (as in current code).

    • Handle exceptions (All Exception Handler). Return Success = False and Message = Exception.Message when applicable.

  2. LoadDraft(KeyId)

    • Retrieve the record for KeyId and UserId from the Draft Entity.

    • Return the JSON.

    • As above, don’t fetch all records and filter; use direct lookups with GetUserId().

  3. ClearDraft(KeyId)

    • Delete the record from the Draft Entity for the given KeyId and UserId.

    • Current implementation is fine here.

Demo Screen (for Customer entity)

  • Add a Form bound to a Local Variable of type Customer.

  • Inside the form, add two buttons:

    • Save Draft

      • Disable form validation.

      • Serialize the Customer variable.

      • Call SaveDraft Client Action with Form.Id and serialized Customer.

      • This saves data to both Local Storage and the Draft Entity.

    • Save

      • Keep form validation enabled.

      • Call the Customer Save Server Action.

      • If successful, call ClearDraft Client Action with Form.Id.

      • This saves data directly to the Customer Entity and clears the draft.

  • In OnReady, call LoadDraft Client Action with Form.Id.

    • Deserialize the returned JSON.

    • Assign it to the Customer variable.

Notes

  • No need to create a Block.

  • These 6 generic methods can be reused for other forms.

  • Ensure each form uses a unique KeyId; otherwise, deserialization may fail.

Follow these steps and let me know how it works.

2019-01-07 16-04-16
Siya
 
MVP

@Sagar Andyal : What exactly  are you  trying to achieve ? While inspecting the OML I can see many things eg :  As soon as the focus reaches the Phone Number field, the Save is fired i.e a record is created without Phone No. ,  When I click on "Save",  another record is created . I can also an entity - Draft which stores the information in JSON etc.

The reason LoadDraft is not deserialising is there is no code written for it.  After LoadFromDraft you are checking LoadFromDraft.Datajson = "" . If so you are just assigning to DataJson and returning. there is no code written to deserialise DataJson. 

btw you can put a breakpoint and debug the code.

2025-10-09 13-52-02
Sagar Andyal

Hi @Siya,

I am trying to achieve this: Form Auto-Save & Resume (recommended)—automatically save users' form data (localStorage + server draft) and let them resume later. 

2019-01-07 16-04-16
Siya
 
MVP

You want to persist the data both locally (using Local Storage) and on the server (inside a Draft entity). When the user explicitly chooses Save, the data should then be stored in the Customer entity.

If the user accesses the system from a different browser, the draft should be loaded from the server (since it won’t exist in Local Storage). If the user simply refreshes the same page, the draft should be loaded from Local Storage.

Also it should clear the local storage and server draft once it is successfully saved.

Is my understanding correct?

2019-01-07 16-04-16
Siya
 
MVP
Solution

Ok. Let’s keep it simple. You will need to create 3 generic Client Actions and 3 generic Server Actions, plus a demo screen to showcase the functionality.

Client Actions

  1. SaveDraft(KeyId, JSON)

    • Save to Local Storage using the existing JS code.

      • Use GetUserId() instead of passing UserId.

    • Call the SaveDraft Server Action.

  2. LoadDraft(KeyId)

    • Load the JSON from Local Storage (similar to current code).

      • Again, use GetUserId() instead of a parameter.

    • If no Local JSON is found, call the LoadDraft Server Action.

    • Return the JSON.

  3. ClearDraft(KeyId)

    • Clear the JSON from Local Storage using the existing JS code.

    • Call the ClearDraft Server Action.

NOTE : Ensure that you use the same key in JS. I have noticed that it's different in SaveDraft - its is prefixed with "draft_" where as in Load and Clear the 'draft_' prefix is missing.

Server Actions

  1. SaveDraft(KeyId, JSON)

    • Retrieve the record for KeyId and UserId from the Draft Entity.

    • If found, update it; otherwise, create a new record.

    • Always use GetUserId() (no parameters).

    • Do not fetch all records and then filter (as in current code).

    • Handle exceptions (All Exception Handler). Return Success = False and Message = Exception.Message when applicable.

  2. LoadDraft(KeyId)

    • Retrieve the record for KeyId and UserId from the Draft Entity.

    • Return the JSON.

    • As above, don’t fetch all records and filter; use direct lookups with GetUserId().

  3. ClearDraft(KeyId)

    • Delete the record from the Draft Entity for the given KeyId and UserId.

    • Current implementation is fine here.

Demo Screen (for Customer entity)

  • Add a Form bound to a Local Variable of type Customer.

  • Inside the form, add two buttons:

    • Save Draft

      • Disable form validation.

      • Serialize the Customer variable.

      • Call SaveDraft Client Action with Form.Id and serialized Customer.

      • This saves data to both Local Storage and the Draft Entity.

    • Save

      • Keep form validation enabled.

      • Call the Customer Save Server Action.

      • If successful, call ClearDraft Client Action with Form.Id.

      • This saves data directly to the Customer Entity and clears the draft.

  • In OnReady, call LoadDraft Client Action with Form.Id.

    • Deserialize the returned JSON.

    • Assign it to the Customer variable.

Notes

  • No need to create a Block.

  • These 6 generic methods can be reused for other forms.

  • Ensure each form uses a unique KeyId; otherwise, deserialization may fail.

Follow these steps and let me know how it works.

2025-10-09 13-52-02
Sagar Andyal

Hi @Siya,

My apologies for the delayed reply—I was busy working on another project and couldn’t respond sooner.

Thank you so much for the detailed solution you shared. It was clear, thorough, and exactly what I needed to get everything working. Your guidance not only solved my problem but also helped me learn more about it.

I really appreciate your time and effort—thank you again!

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.