locked
JavaScript - Save Contact, Open Account, Close Contact form RRS feed

  • Question

  • We are trying to accomplish the following:

    1) User changes a field value on the Contact form which triggers a JS method
    2) The JS method performs the following:
         a) Saves the Contact form (this triggers an Update plugin which creates an Account record)
         b) Opens the Account form and displays newly created Account record
         c) Closes the Contact form

    Here are some of our JS attempts so far:

    eg 1) This results in "Error: Can't execute code from a freed script."

    accountField_OnChange() {
        Xrm.Page.data.entity.save('saveandclose');
        Xrm.Utility.openEntityForm("account", newAccountGUID);
    }

    eg 2) This works except the calling Contact form is still open

    accountField_OnChange() {
        Xrm.Page.data.entity.save();
        Xrm.Utility.openEntityForm("account", newAccountGUID);
    }


    Is there a recommended approach to doing this in CRM 2011? 



    • Edited by Cipher Tuesday, August 13, 2013 8:16 PM
    Tuesday, August 13, 2013 8:14 PM

Answers

  • Hi Cipher,

    Did you try the Supported JavaScript method in CRM 2011?

    Xrm.Page.ui.close();

    This may prompt you for the save.

    to stop this prompt you need to use getSubmitMode method of attribute and need to set submitMode to never like below

     var attributes = Xrm.Page.data.entity.attributes.get();

      for (var i in attributes)

        {       attributes[i].setSubmitMode(“never”);

        }

    Xrm.Page.ui.close();

    Hope this helps!

    Thanks!

    • Marked as answer by Cipher Wednesday, August 14, 2013 2:45 PM
    • Unmarked as answer by Cipher Wednesday, August 14, 2013 7:14 PM
    • Marked as answer by Cipher Thursday, August 15, 2013 3:21 AM
    Wednesday, August 14, 2013 4:32 AM
  • I believe the problem is that in some cases the record is not created before the form is opened (since the plugin will fire after all the javascript has processed).

    If the form saves and the plugin creates the record before the other window finishes loading, then it is fine.

    But if the other window finishes loading before the plugin creates the record, then you will have issues.

    The best way to do it is only open the record after you know the plugin has fired (when the contact reloads)...

    By the way, if you're setting submit mode to 'never' on all fields, your newAccountGUID will not be submitted either (assuming you're setting this in a field somewhere).

    Paul


    If my response helped you find your answer please show your thanks by taking the time to "Mark As Answer" and "Vote As Helpful".

    Twitter LinkedIn Facebook Blog Magnetism

    • Marked as answer by Cipher Thursday, August 15, 2013 3:21 AM
    Wednesday, August 14, 2013 8:25 PM

All replies

  • My understanding of the requirement above states there would be a plugin that would create the new account.

    Just curious to know how do you access the newAccountGuid, since that would be created by the plugin behind the scenes.

    To solve your immediate problem, you could call window.close() after the openentityForm to close the current contact form.

    HTH

    Sam


    Dynamics CRM MVP | Inogic | http://inogic.blogspot.com| news at inogic dot com

    If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"

    • Proposed as answer by Sam - Inogic Wednesday, August 14, 2013 3:44 AM
    • Unproposed as answer by Cipher Wednesday, August 14, 2013 4:21 AM
    Wednesday, August 14, 2013 3:44 AM
  • Hi Sam,

    I'm generating the GUID in JS and passing this on a hidden field to the plugin.  This way I can then pass it to the openEntityForm() method.

    Unfortunately, window.close() doesn't close the Contact form when I add it after the openEntityForm() call. 

    accountField_OnChange() {    Xrm.Page.data.entity.save();    Xrm.Utility.openEntityForm("account", newAccountGUID);   
    window.close(); }

    • Edited by Cipher Wednesday, August 14, 2013 4:20 AM
    Wednesday, August 14, 2013 4:13 AM
  • Hi Cipher,

    Did you try the Supported JavaScript method in CRM 2011?

    Xrm.Page.ui.close();

    This may prompt you for the save.

    to stop this prompt you need to use getSubmitMode method of attribute and need to set submitMode to never like below

     var attributes = Xrm.Page.data.entity.attributes.get();

      for (var i in attributes)

        {       attributes[i].setSubmitMode(“never”);

        }

    Xrm.Page.ui.close();

    Hope this helps!

    Thanks!

    • Marked as answer by Cipher Wednesday, August 14, 2013 2:45 PM
    • Unmarked as answer by Cipher Wednesday, August 14, 2013 7:14 PM
    • Marked as answer by Cipher Thursday, August 15, 2013 3:21 AM
    Wednesday, August 14, 2013 4:32 AM
  • Ok, the problem is not how you're saving or closing the record. The problem is that you're trying to execute code after calling 'save'. As soon as you 'save' the record, the form will save. No other code will execute, and so your account will not be opened.

    Here is what you can do:

    • Your JavaScript function needs to set something to trigger the plugin (can be a hidden yes/no field), and then save the form (not save and close).
    • Your plugin then needs to fire (filtering on the trigger field) and create the account, then set the account ID on your target entity into a hidden field. 
    • When the form reloads, another JavaScript function needs to fire, and check your account ID hidden field contains data, and then pop the record, and close the current form.
    • Finally, you will need another plugin to run asynchronously on change of the trigger field, which simply wipes the hidden account ID field (and optionally resets the trigger field), so that it doesn't keep popping the account in future, but because it's async it won't fire before the form has reloaded and popped the account once.

    I use this method all the time and it works fine.

    Hope that helps

    Paul


    If my response helped you find your answer please show your thanks by taking the time to "Mark As Answer" and "Vote As Helpful".

    Twitter LinkedIn Facebook Blog Magnetism

    Wednesday, August 14, 2013 10:25 AM
  • Kalim, I think that might have done it.  Here is the complete JS method...

     

    accountField_OnChange() {     

    Xrm.Page.data.entity.save();         //Save Contact record 
    Xrm.Utility.openEntityForm("account", newAccountGUID);   //Open Account form to newly created Account record 
          
    var attributes = Xrm.Page.data.entity.attributes.get();   //Set setSubmitMode to 'never' for all fields on Contact form       
    for (var i in attributes)        {                  
    attributes[i].setSubmitMode("never");        
    }       

    Xrm.Page.ui.close();       //Close Contact form
    }






    • Edited by Cipher Wednesday, August 14, 2013 2:53 PM
    Wednesday, August 14, 2013 2:44 PM
  • Hi Paul,

    Actually, code was executing after the save() method.  The Account form was opening to the new record, but the problem was we couldn't close the original Contact form. 

    I've marked Kalim's recommendation above as it looks like it's solved the issue.

    Wednesday, August 14, 2013 2:50 PM
  • Ok, it looks like this has only partially fixed the issue (Kalim, I've temporarily unmarked your answer until we resolve this related issue.).  We are now occasionally getting "the requested record was not found" error when trying to open the Contact form.  It looks to me like the Contact form open logic is sometimes running before the Contact record is actually saved by the plugin.

    I tried adding a setTimeout() call with a 5 second delay after the Xrm.Page.data.entity.save() line, but this didn't run.  Based on this result and what I saw earlier it looks like only certain commands are executing after the save() method.

    Any ideas how to add a delay in JS after the Save event has run or somehow ensure that we only open the Contact form once the record is saved?



    • Edited by Cipher Wednesday, August 14, 2013 7:24 PM
    Wednesday, August 14, 2013 7:14 PM
  • Hi Cipher,

    On change event of the field call below method.

    accountField_OnChange() {      
    Xrm.Page.data.entity.save();             //Save Contact record  
    setTimeout(openAccountForm,30000)  // Increase the Timeout to 30 second
    }

    openAccountForm()
    {
       Xrm.Utility.openEntityForm("account", newAccountGUID);   //Open Account form to newly created Account record         var attributes = Xrm.Page.data.entity.attributes.get();   //Set setSubmitMode to 'never' for all fields on Contact form         for (var i in attributes)       
            { 
             attributes[i].setSubmitMode("never");        
     }         
    Xrm.Page.ui.close();             //Close Contact form}
    }

    Now I have kept the timeout to 30 second. if it doesn't work Try to increase the timeout value and give another try.

    Any specific reason for creating account through Plugin? How much time it is taking for execution? If the Current Plugin has some more Plugins in same pipeline transaction it may take more time. 

    Hope this helps!

    Thanks!


    • Edited by Kalim Khan Wednesday, August 14, 2013 8:21 PM
    Wednesday, August 14, 2013 8:20 PM
  • I believe the problem is that in some cases the record is not created before the form is opened (since the plugin will fire after all the javascript has processed).

    If the form saves and the plugin creates the record before the other window finishes loading, then it is fine.

    But if the other window finishes loading before the plugin creates the record, then you will have issues.

    The best way to do it is only open the record after you know the plugin has fired (when the contact reloads)...

    By the way, if you're setting submit mode to 'never' on all fields, your newAccountGUID will not be submitted either (assuming you're setting this in a field somewhere).

    Paul


    If my response helped you find your answer please show your thanks by taking the time to "Mark As Answer" and "Vote As Helpful".

    Twitter LinkedIn Facebook Blog Magnetism

    • Marked as answer by Cipher Thursday, August 15, 2013 3:21 AM
    Wednesday, August 14, 2013 8:25 PM
  • Timeout will not work as the form will save and close before the timeout has even started waiting.

    If my response helped you find your answer please show your thanks by taking the time to "Mark As Answer" and "Vote As Helpful".

    Twitter LinkedIn Facebook Blog Magnetism

    Wednesday, August 14, 2013 8:27 PM
  • Paul, thanks for the advice on running the openEntityForm() code on the reload.  It's not as elegant as we had hoped, as the Contact record as to reload, but by waiting until the form reloads before opening the Account record, we are making sure that the record has been created by the plugin.

    Kalim, unfortunately we couldn't get the setTimeout call to execute after the Save() method was called (see my earlier post).  Ideally, we would have created a loop checking for the existence of the Contract record and then delaying it by x seconds via setTimeout before checking again, but it looks like only certain JS logic is supported after the Save() method call.

    Also, we're using a Plugin to save the record rather then JS as there is some complex logic that we're using to create the Account record and it's much easier doing it on the server side.  Unfortunately, that choice has led to the issue we've seen here as doing this all in JS on the client side would have eliminated the timing issue.  It would be greet if MS could add a callback option in JS once a plugin has finished running (similar to the Xrm.Page.data.entity.addOnSave() method).

    In case others come across this thread, our plugin was a Post Create plugin and we experienced these issues on Rollup 12-14.

    Thanks again, guys.  I've marked the two replies that helped us to a working solution. 


    • Edited by Cipher Thursday, August 15, 2013 3:23 AM
    Thursday, August 15, 2013 3:21 AM