Anyone who has been using OrangeScape, will know about the auto save feature (in runtime). (I use the word “auto save”, just coz, i could not think of any other word, which will explain what i am trying to say).
Once you type in a field in your application, and move to the next field, the first field value will be automatically saved. (Didn’t they say they use AJAX too). But sometimes, this is not required. So, for those who do not require that data be saved to the backend immediately, OrangeScape has three options which you can set, and control when the data is sent back to the server, to be saved to the backend. In Form Design, in the Ribbon, under the category Cell, you can see three options : Dont Submit, Submit, Submit on Dependency. Lemme briefly say what these three options are.
- Dont Submit : as the name says, the field data will not be sent to server, as and when the field data changes. The whole form will be submitted when you submit the form.
- Submit : The field data will be sent to server on every change.
- Submit on Dependency : The data will be sent only if there are any formula / rule which depends on the value of the field which is currently being changed. All data till that point which has been entered will be sent to server. for ex. if you have 3 fields, name, qty and amount. Amount will be calculated based on formula which involves qty, then when you change qty, the name field value will also be sent to server.
The default is Submit on Dependency.
Ok! after all these details, you must be thinking, then what is this Cancel button problem that i am talking about. If you aren’t, then, after reading the scenario, you will.
Disclaimer: The following process / scenario / Persons in this scenario is a fictional one. any resemblance to an existing process / scenario / Persons is purely coincidental. Few words of technical mumbo-jumbo can be seen. I apologize.
Warning : This is a really long & boring blog post.
Let’s assume, that you are updating profile details, which you created when you first logged in to this awesome application created with orangescape. Let’s see what details are there in the form. There is the usual, first name, last name, date of birth, address, country, state, city. This person, who is editing, has moved to a city in another State.
Let’s make another assumption, that all fields have been set as Dont Submit. so what will happen, the user will change the address, the State in the State drop down, then will try to change the City in the City drop down. But wait! the city drop down is still showing cities belonging to the previous chosen State. Why? because, the application does not know, what are the cities in the State which you have chosen. It has to communicate with the server, and then find out what are the cities in the state you have chosen, and then show it to you. But it has been set as Dont Submit, which means communications to server have been bared till you submit the page.
Now, this leaves us with no other choice, other than to change the setting to Submit on Dependency on the three drop downs (Country, State, City). Now after changing the address, the person chooses the state, now, a request will be sent to server the fetch the data for the list of cities belonging to the state chosen. At this point, in the request sent to the server, the data which has been modified till this point will be submitted. Which means the address has been saved.
Well, what’s the problem you ask?! The person had a change of mind, and does not want to carry on with the update, and want to cancel and go back to how it was previously. Unfortunately, it can’t be done. the data has been changed and saved. There is no way of getting it back. Ah! now you get the problem?!!
So how to do we solve this problem?!! During a discussion at work, a person with whom i work with, gave this idea, which he had used in another application of his. Which was good. And this would also help those who want to track every change that their users did, during every submit. Yeah! you are thinking right.
Data Versioning, essentially what you will be doing is, whenever you open a record to edit, you will be actually opening a copy of the data to edit, and if everything is ok, and you want to submit the changes, then they will be changed, else you can discard the data. (or you can store it and see how the user changed the data from what to what, etc., But be responsible with what you do.)
Whatever you wanna call this : This is not the only way. May be there are (will be) other alternatives. If you are going to use this, welcome aboard.
Ok! let’s say we have one model, for which we want to implement this. Let’s see how to do it.
Now, keep only those fields, which are absolute necessary in this model. Leave out fields for validations, flags for permissions and all those unnecessary stuff. Create one more model, when you can write all those unnecessary stuff + all your fields which are absolute necessary. Let’s call the model with absolute necessary fields as Transactions and the other model with all the unnecessary stuff + absolute necessary fields as History.
We need 2 more fields in the Transaction model as connections to History model, and 1 field in History model as connection to Transaction model. The following logic, will be really confusing, coz, i was getting confused with this logic, when listening, when explaining, and also when doing. So most probably i will be writing this in the same confused way. Be prepared to be confused.
In Transactions model i am going to create three actions.
- Create History
- A NEW Command which will create a copy of the current data in History model for editing
- Update Transactions
- An UPDATE Command, which sets the value of Draft into Current.
- An UPDATE Command, which releases the History command from draft state to commit state.
- A Submit Command, to proceed in the workflow.
Now lets move to History Model. Here i am going to create just one action
- Update Entries
- Two PARENTCALL Commands, first one to call Update Transactions, and 2nd one to call WorkFlow action.
In Transactions in all fields i have written DGET()
to fetch data from History model, based on the “Current” Reference Field. As for the forms, i had designed the forms in History Model, and used that form as a Many To One form via Draft reference field. and for the submit, i had used the Update Entries Action. thats it. O! i totally forgot, that CreateHistory action, that will fire everytime a record comes to the activity, i have used the Connect -> Action
in the Process Design to set it.
So how it Works?!#@.
Once you create a new record or submit an existing record, the Create History will be called, and a new History record will be created with existing set of values. For ex: lets consider a simple model Transaction
So, when a new record is created / a record is submitted , CreateHistory action is called, and a History record is created via the NEW command, and reference to the newly created record is set in the Draft Reference Cell in Transactions model and a reference to Transactions model is set in History reference cell in History model. Now based on the Draft reference cell, the newly created History model record will show in the form as a Many to one record. The user will make changes / enter data in this form. So, all data are being entered into History model record. Till the user clicks submit button all data will reside in History model. If the user decides to cancel, then you can either discard the History model record, or store it as editing history.
Ok! So when the user submits, via the call child action we set the value of the Current Reference cell to the value in Draft Reference Cell. Now, all DGET() functions in the Transaction model will fire based on the Current Reference Cell value, and sync the data which was entered / changed in the current submitted version of the History Record. Then we will clear the Draft Reference Cell value to blank, so that the Current Referenced and Draft Referenced records are not the same records.
So That’s it. I have done it and tested, and it is working. But don’t take my word for it. Please try it out, and understand what is really happening. This may or may not get complex based on your scenarios. I know, i know, it is already confusing, and i am writing this whole thing, in the middle of the night, half asleep.
If you still got questions, please post your questions in the comments. Or, if you think you have an even better idea, lemme know, we can make things work better,.