4

We have a requirement to refresh the form after saving (to ensure that some hide/show logic works as expected based on a field value).

Currently the form does not automatically refresh after saving the record.

I have gone through some articles and found this reference: http://msdn.microsoft.com/en-us/library/dn481607%28v=crm.6%29.aspx

When I try to do either of the below, it results in an infinite loop and throws a 'Callstack exceeded Max limit' error.

  1. OnSave(context)
    {
      //my logic 
      ...
      ...
    
      Xrm.Page.data.save.then(SuccessOnSave, ErrorOnSave);
    }
    
      function SuccessOnSave()
     {
      //force refresh
       Xrm.Page.data.refresh();
     }
      function ErrorOnSave()
      {
        //do nothing
      }
    
  2.   OnSave(context)
     {
       ...
      ...
      //force refresh
      Xrm.Page.data.refresh(true).then(SuccessOnSave, ErrorOnSave);
    }
    
      function SuccessOnSave()
     {
      //do nothing
     }
      function ErrorOnSave()
      {
        //do nothing
      }
    

Can someone please explain me how to use the refresh or save method to do a force refresh of the form ??

Rajesh

Rajesh
  • 449
  • 2
  • 9
  • 22

8 Answers8

2

I use to achieve it with 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) {
    }
    );
MaKeer
  • 61
  • 6
2

For me this is what solved the purpose (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);
Tully
  • 95
  • 2
  • 6
SunilR
  • 39
  • 2
  • `Xrm.Page.data.refresh()` is not 100% ... thanks code best – KingRider Apr 14 '16 at 19:29
  • I wish that Xrm.Page.data.save().then(successCallback, errorCallback) actually did what the [SDK says it does...](https://msdn.microsoft.com/en-us/library/dn481607(v=crm.7).aspx#BKMK_dataSave) but the callback was not working for me. I guess that's a difference between CRM 2015 vanilla and CRM 2015 SP1? – codo-sapien Jun 18 '16 at 00:11
0

If you want to do a hard refresh on the form data, you will likely want to do a location reload. What I've done in the past is put the refresh logic in a function that is called when the Form is loaded (after being saved). The tricky part about this is that the function can get called if the form is auto-saved in CRM 2013. You also want to take into account that you don't want to refresh the form on the first load, since this would result in an infinite reloading loop. Here's an example:

var formLoaded = false;
function formLoad() {
    if (formLoaded) {
        window.location = location.href;
    }
    formLoaded = true;
}
BlueSam
  • 1,888
  • 10
  • 17
0

You have attached the OnSave() method to OnSave event. So, logically if you call save again within the same event, the calls goes recursively.

From MSDN

Xrm.Page.data.refresh(save).then(successCallback, errorCallback); Parameter: save - A Boolean value to indicate if data should be saved after it is refreshed.

So, you will have to pass 'false' to this method (You just need to refresh, no save is required)

Thangadurai
  • 2,573
  • 26
  • 32
  • :-) Just realized that it's an year old question – Thangadurai Sep 03 '14 at 14:08
  • it's not an year old question.. it's just a month old :). And about your answer, calling the 'refresh' method with a false is giving me a popup saying 'Your changes have not been saved.Are you sure you want to navigate away from the page' ? ...because we are sending 'false'. – Rajesh Sep 05 '14 at 05:46
0

As I couldn't find the complete code for this written in a 'generically' reusable way, here goes:

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's 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);
}
bigly
  • 1
  • using this, the save would get called twice ... (on creating object for the first time) – Muhammad Naderi Oct 06 '15 at 14:44
  • Seems newer versions of dynamics blocks this form of the inner save with error code -1 and message "Service is Busy", as they think it is infinity loop :/ – Wisienkas Nov 26 '20 at 10:35
0

Use Mscrm.Utilities.reloadPage();

0

I found this post helpful in demonstrating the difference between Xrm.Page.data.refresh() and Xrm.Utility.openEntityForm(entityName, id).

TL;DR - if you want the screen to repaint, consider using Xrm.Utility.openEntityForm(entityName, id).

Tunaki
  • 132,869
  • 46
  • 340
  • 423
0

You can achieve by placing Modified On field on the form. And set visible by default property to false.

Use below JS to refresh the 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 On Change event on Modified on field and provide above function name.