CRM 2013: Force Form Refresh After Save
We have a requirement to update the form after saving (to ensure that any hidden / displayed logic works as expected based on the field value).
Currently, the form does not automatically update after saving the record.
I looked at some articles and found this link: http://msdn.microsoft.com/en-us/library/dn481607%28v=crm.6%29.aspx
When I try to do any of the below, it ends up in an infinite loop and throws a "Calls exceeded maximum" error.
-
OnSave(context) { //my logic ... ... Xrm.Page.data.save.then(SuccessOnSave, ErrorOnSave); } function SuccessOnSave() { //force refresh Xrm.Page.data.refresh(); } function ErrorOnSave() { //do nothing }
-
OnSave(context) { ... ... //force refresh Xrm.Page.data.refresh(true).then(SuccessOnSave, ErrorOnSave); } function SuccessOnSave() { //do nothing } function ErrorOnSave() { //do nothing }
Can someone please explain to me how to use the refresh or save method to force a form refresh?
Rajesh
source to share
For me this is what solved the goal (CRM 2015)
// Save the current record to prevent messages about unsaved changes
Xrm.Page.data.entity.save();
setTimeout(function () {
// Call the Open Entity Form method and pass through the current entity name and ID to force CRM to reload the record
Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId());
}, 3000);
source to share
I am using it to achieve the following code
Xrm.Page.data.save().then(
function () {
Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {
attribute.setSubmitMode("never");
});
Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId());
},
function (errorCode, message) {
}
);
source to share
If you want to do a hard refresh of the form data, you will most likely want to do a location reload. What I have done in the past is putting the update logic into a function called when the form is loaded (after it has been saved). The tricky part of this is that the function can be called if the form is automatically saved in CRM 2013. You should also take into account that you do not want to update the form on first load, as this will result in an endless reload loop. Here's an example:
var formLoaded = false;
function formLoad() {
if (formLoaded) {
window.location = location.href;
}
formLoaded = true;
}
source to share
You have hooked up the OnSave () method to the OnSave event. So, logically, if you call save again on the same event, the calls are recursive.
From MSDN
Xrm.Page.data.refresh (save). then (successCallback, errorCallback); Parameter: save - a boolean value indicating whether the data should be saved after the update.
So, you will have to pass "false" to this method (you just need to update, no save required)
source to share
Since I couldn't find the complete code for this, written in a "generic" reusable way, here's what:
var triggeredSave = false;
//Attach the OnSave Form event to this OnSave function
//and select passing of context as the first parameter.
//Could instead be attached programmatically using the code:
//Xrm.Page.data.entity.addOnSave(OnSave);
function OnSave(context) {
var eventArgs = context.getEventArgs();
var preventedAutoSave = false;
//Preventing auto-save is optional; remove or comment this line if not required.
preventedAutoSave = PreventAutoSave(eventArgs);
//In order to setup an after save event function, explicitly
//invoke the save method with callback options.
//As this is already executing within the OnSave event, use Boolean,
//triggeredSave, to prevent an infinite save loop.
if (!preventedAutoSave && !triggeredSave) {
triggeredSave = true;
Xrm.Page.data.save().then(
function () {
//As the form does not automatically reload after a save,
//set the save controlling Boolean, triggeredSave, back to
//false to allow 'callback hookup' in any subsequent save.
triggeredSave = false;
OnSuccessfulSave();
},
function (errorCode, message) {
triggeredSave = false;
//OPTIONAL TODO: Response to failed save.
});
}
}
function PreventAutoSave(eventArgs) {
if (eventArgs.getSaveMode() == 70 || eventArgs.getSaveMode() == 2) {
eventArgs.preventDefault();
return true;
}
return false;
}
//Function OnSuccessfulSave is invoked AFTER a save has been committed.
function OnSuccessfulSave() {
//It seems CRM doesn't always clear the IsFormDirty state
//by the point callback is executed, so do it explicitly.
Xrm.Page.data.setFormDirty(false);
//TODO: WHATEVER POST SAVE PROCESSING YOU REQUIRE
//e.g. reload the form as per pre CRM 2013 behaviour.
ReloadForm(false);
//One scenario this post save event is useful for is retriggering
//Business Rules utilising a field which is not submitted during save.
//For example, if you implement a Current User field populated on Form
//Load, this can be used for user comparison Business Rules but you
//may not wish to persist this field and hence you may set its submit
//mode to 'never'.
//CRM internal retriggering of Business Rules post save doesn't
//consider changes in fields not submitted so rules utilising them may
//not be automatically re-evaluated or may be re-evaluated incorrectly.
}
function ReloadForm(preventSavePrompt) {
if (preventSavePrompt) {
Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {
attribute.setSubmitMode("never");
});
Xrm.Page.data.setFormDirty(false);
}
Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(),
Xrm.Page.data.entity.getId());
//Another way of trying Form reload is:
//window.location.reload(true);
}
source to share
You can achieve by placing the "Modified" field on the form. And set the default visible property to false.
Use below JS to update your form
function refreshCRMFORM()
{
setTimeout(function () {
// Call the Open Entity Form method and pass through the current entity name and ID to force CRM to reload the record
Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId());
}, 1000);
}
Create a "Change On" event in the "Modified" field and specify the function name above.
source to share