crm 2013 javascript save and refresh crashes

zabby picture zabby · Apr 24, 2014 · Viewed 10.3k times · Source

I currently have a development environment for CRM 2013 On-Premise. In my custom entity, the following JavaScript code runs:

function UpdateBPF() {
    var requests = [];
    requests.push(Xrm.Page.getAttribute('description').setRequiredLevel('none'));
    requests.push(Xrm.Page.getAttribute('categoryid').setRequiredLevel('none'));
    requests.push(Xrm.Page.getAttribute('priority').setRequiredLevel('none'));
    requests.push(Xrm.Page.getAttribute('initialtype').setValue(1));
    requests.push(Xrm.Page.data.save());
    requests.push(event.returnValue = false);

    $.when.apply(undefined, requests).always(function () {
        Xrm.Page.data.setFormDirty(false);
        RefreshForm();
    });
};

function RefreshForm() {
    Mscrm.ReadFormUtilities.openInSameFrame(window._etc, Xrm.Page.data.entity.getId());
};

What I'm trying to do:

  • Change a business process flow on change of an option set value

What my code is doing after switching the option set:

  • Launching a custom workflow to do the actual switching (Works fine, I require the refresh to actually display the selected workflow to the user)
  • Not requiring certain fields (prevented refresh from occurring if not filled)
  • Saving the form (After refreshing to display the correct business process flow, values were never saved so the option set value was never set)
  • Preventing the "You have not saved yet" popup from occurring. (Good possibility I no longer need this)
  • I set the form to not dirty after not saving

Why am I pushing most of the steps into the requests variable?

  • I wanted those values to definitely occur before refreshing the form. Very likely I'm doing this incorrectly or not efficiently.

What worked:

  • Everything worked in my CRM 2013 On-Premise Test environment as expected.
  • Save
  • Refresh
  • Correct Business Process Flow & Stage

The Issue for CRM 2013 Online:

  • Saving and Refreshing do not work
  • IE 9,10,11 and FireFox Completely crash. Chrome is fine.
  • Turning off Auto-Save didn't make a difference

What I've tried for save:

  • Xrm.Page.data.save()
  • Xrm.Page.data.entity.save()

What I've tried for refresh:

  • Xrm.Page.data.refresh()
  • Mscrm.ReadFormUtilities.openInSameFrame(window._etc, Xrm.Page.data.entity.getId())
  • Xrm.Utility.openEntityForm("service_ticket", Xrm.Page.data.entity.getId(), null)
  • var url = Xrm.Page.context.getClientUrl(); window.open(url + "/main.aspx?etn=ticket&pagetype=entityrecord&id=" + Xrm.Page.data.entity.getId() + "&newWindow=false", "_blank", null, false);

When I debug, step by step through the code posted at the top, it gets the then .when, .apply, and.always but SKIPS everything inside. I would think that always means that it always runs...

When I try:

Xrm.Page.data.save().then(
    function () {
        alert('Save worked, refresh');
        Xrm.Page.data.refresh();
    },
    function () {
        alert('Save failed!');
    }
);

Stepping through the code has it hit save. But after hitting then, it SKIPS everything inside and then IE(Which I've been mainly testing in because Chrome seems to work...), completely crashes. An error doesn't exactly popup, it's more of an alert that say "IE has stopped working".

I've seen 1 similar issue in StackOverflow without an accepted answer or an answer that did not work for me at all. The Xrm.Page.data.save() function just before the previous 2 paragraphs was a sample from one of the answers. Super simple sample that was easy to follow and step through for testing purposes with no change in result.

I've also Googled (my best friend) and even Binged my issue. The one other post on another site, I believe on a Microsoft Site, had no responses at all. Based on what was written, I assume it was the same person as for the StackOverflow post.

Any insight into the problem, whether it be my code or something else, is greatly appreciated.

tl;dr Save and Refresh JavaScript does not work for CRM 2013 Online

Answer

zabby picture zabby · Apr 28, 2014

What I ended up doing was having a setTimeout just before Xrm.Page.data.save. It appears that something occurs directly after the field change and just before my JavaScript. It might be business rules (but I had them initially deactivated, so there's a chance this is not it).

Either way, what I did to solve my problem is enclose the save function within a short timeout, and then use Xrm.Utility.openEntityForm to "refresh" the whole page since I'd rather not use the unsupported

Mscrm.ReadFormUtilities.openInSameFrame(window._etc, Xrm.Page.data.entity.getId())

Below is the code snippet I used:

setTimeout(function () {
    Xrm.Page.data.save().then(
        function () {
            var id = Xrm.Page.data.entity.getId();
            var entityLogicalName = Xrm.Page.data.entity.getEntityName();
            Xrm.Utility.openEntityForm(entityLogicalName, id);
        },
        function () {
            alert('Save failed! Please refresh the form.');
        });
}, 500);

I get the record's id after the save for newly created records. Having it outside the timeout or before the save causes a new record to open (Save + New essentially).

If there is a more efficient way to go about this, please feel fee to let me know and I will select your answer (if it works) as the correct one.

EDIT:
The below code is actually a better version. The previous code I had did Save and Save&Close, causing Save to occur twice, which messed up some logic of mine for a different project

setTimeout(function () {
    var id = Xrm.Page.data.entity.getId();
    var entityLogicalName = Xrm.Page.data.entity.getEntityName();
    Xrm.Utility.openEntityForm(entityLogicalName, id);
}, 500);

Here, openEntityForm is Saving the record before closing and opening itself up again, the closest I can get to a Save & Refresh.