web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics CRM (Archived)

Need to copy and concatenate multiple fields into a single field, but there is a catch -- oh no

(0) ShareShare
ReportReport
Posted on by 1,589

Any assistance or guidance would be greatly appreciated. For the sake of being expedient, I have simplified the environment in this example so that we can deal only with the problem and the immediate components that impact it.

I have a CRM form named Test License. The Form connects back to the Test License entity.

The form has five text box fields in our example. We will call them 1, 2, 3, A, and L as shown in the image below.

Three of the five text box fields, labeled as 1, 2, and 3 will always populated with data. The data present is entirely dependent on what the user selects when they choose to create a new License and open this form.

Field A, gets its data via a managed plugin that auto increments when the user clicks the save button. So Field A gets its value when save is clicked.

The last field, field L, must be filed with data that is concatenated from the other 4 fields, and it must be placed in the 5th field after the managed plug in populates field A, but before the save process ends.

TestForm.png

Normally, I would use JavaScript to simply check the values of field 1, 2, A, and 3 concatenate them, and then set them in field L.

However, I cannot do this because as per the design of CRM 2011, once the “save button is clicked” JavaScript no longer functions and fields can no longer be accessed via front end scripting.

If it could, I have a perfect script that would work. Prior to implementing it, I removed the CRM “save and close” as well as the “save and new” button because the script requires part of the changes to be made on form load, and the form must save and reload to set the permanent value in fieldL. So by forcing the end user to hit the save button, the that would force a form load, and run the script below, which would update the final field now that we can access the form again to grab the data put there by the auto-number.

Here was my original plan:

  1. User chooses to create a new record

  2. User enters their data

  3. User clicks the save button, which stops all of my JavaScript code from running.

  4. The 3rd party auto-number plugin fires and inserts the value into the fieldA field.

  5. The save process completes, and the form reloads by design.

  6. Then on Form Load, the following script executes to update the FieldL filed, (which currently has a temporary value just so it could be saved in the previous step) with the real value via the following JavaScript code.

function GenerateLicenseID(){
//field1 – will always contain a G or B value 
//field2 – will always two digit license year
//field3 – will either contain letters and/or numbers or be null 
//fieldA - the portion of the id number generated by the auto incrementing managed plugin – will always be populated via the 3rd party plugin solution once the save button is pressed. 
//fieldL – destination where the final number must be copied to, final number is a concatenated combination of all the other fields 
//fieldX – a two value radio button that must get set to yes once all five of these fields are properly populated 
var fld1test = Xrm.Page.getAttribute("field1").getValue();
var fldXtext = Xrm.Page.getAttribute("fieldX").getValue();
var fld3test = Xrm.Page.getAttribute("field3").getValue();
if  (fldXtest == true) {SetAllLicenseFieldsDisabled(); return;}
else if (((fld1test ^= 'G') || (fld1test ^= 'B')) && ((fldXtest == null) || (fldXtest == false) || (fldxtest == 0)) && (fld3test == null)) {
var fld1 = Xrm.Page.getAttribute("field1").getValue();
var fld2 = Xrm.Page.getAttribute("field2").getValue();
var fld3 = Xrm.Page.getAttribute("field3").getValue();
var fldA = Xrm.Page.getAttribute("fieldA").getValue();
var fldL = Xrm.Page.getAttribute("fieldL").getValue();
var destination = field1 + "-" + field2 + "-"+ fieldA;
Xrm.Page.getAttribute("fieldL”).setValue(destination);
Xrm.Page.getAttribute("fieldX").setValue(true)
Xrm.Page.data.entity.save();  
return;}
else if (((fld1test ^= 'G') || (fld1test ^= 'B')) && ((fldXtest == null) || (fldXtest == false) || (fldxtest == 0)) && (fld3test != null)) {
          var destination1 = field1 + "-" + field2 + "-" + field3 + "-" + fieldA;
          Xrm.Page.getAttribute("fieldL”).setValue(destination1);
          Xrm.Page.getAttribute("fieldX").setValue(true);
          Xrm.Page.data.entity.save();  
                            return;}  
}


This scenario would have worked perfectly if it were possible.

Unfortunately, when the form reloads immediately after hitting the save button, I get the error “Can’t execute code from a freed script”. And clicking to debug shows code on the main CRM page, which isn’t something I have control over with the Jscript.

FreedScriptError.jpg

If the user does a save and close. And then opens the record from a closed state, this error doesn’t appear, but that usage scenario is not acceptable.

As a looked in to the problem, I found that other folks encountered similar issues calling Xrm.Page.data.entity.save(); on form load, but their work around was always to set a timeout value.

Therefore, I put the save command in a function

function CustomSave(){
Xrm.Page.data.entity.save(); }


Then I called that function with a time out as shown below, and tried time out values of 4000, then 6000, then 12,000 and no luck, same error shown above)

setTimeout(CustomSave(),6000)

I also tried the whole parent.Xrm.Page.data.entity.save(); thing after setting isDirty to true as some suggested, but that didn’t work either.

Unfortunately I am now out of time, and need this solved yesterday. So it seems based on everything I have read, that I am forced to use a plugin.

With that being said, the new order of operations must flow like this:

  1. User chooses to create a new record

  2. User enters their data

  3. User clicks the save button, or save and close button, or save and new button, which stops all of my JavaScript code from running.

  4. The 3rd party auto-number plugin fires and inserts the value into the fieldA field.

  5. My plugin must fire, and execute code that does the C# equivalent of the JavaScript code in the function GenerateLicenseID above:

  6. The save process completes.

  7. The user moves on to do whatever they were planning to do next.

I never made a plug in before and I am coming at this knowing how to open visual studio, create a plugin project, and connect to CRM. Everything after that, is new.

I am not concerned about plug in registration and all the configuration particulars I can figure those out.

My concern is, however, threefold:

  • What options do I select when I create the plug in, so that when the plug in runs, it runs after the 3rd party plug in completes its data insert process in step 4, that runs once the user hits save, but is able to select and copy the values form the form before the save process actually completes?

 2260.plugin.png

  • What C# code must I actually write inside of the plugin so that the plugin will copy the values from the other fields, then concatenate them as I need it to, then set the concatenated value into the fieldL field as described above? The JavaScript code is pretty simple, but not having wrote anything in C#, I need some help “converting” or at least understanding where the code needs to go, and how to write it as close to the JavaScript code as is possible so I can actually understand what it’s doing when I see it.

     

  • What is a good mechanism to debug it? And troubleshoot it.

I already watched some of the videos here about how to make plug-ins

https://www.youtube.com/watch?v=rnQqxSO-WHQ

https://www.youtube.com/watch?v=TGX1zMMu4Uw

But when I do exactly what they do, I am left with an error that I cannot figure out how to get past.

Error 22 Error registering plugins and/or workflows. Plug-in assembly does not contain the required types or assembly content cannot be updated.                                C:\Program Files (x86)\MSBuild\Microsoft\CRM\Microsoft.CrmDeveloperTools.12.targets        176          4              CrmPackage

DeployErrorSM.jpg

 

If anyone can provide some insight specific to the situation described above, that would be greatly appreciated.

*This post is locked for comments

I have the same question (0)
  • Aiden Kaskela Profile Picture
    19,696 on at

    Hi Jim,

    Concerning: "{...} once the “save button is clicked” JavaScript no longer functions and fields can no longer be accessed via front end scripting."

    You can add an event to the forms OnSave event, which fires after the Save button is clicked but before the record is persisted. This is intended for form validation, but you could use that event to set any fields you want. Can you not use this because you need the persisted value in the calculation?

    Thanks,

     Aiden

  • ACECORP Profile Picture
    1,589 on at

    I believe that is my dilemma. I think it is the persisted value that's needed for the calculation. I conclude that because if I put the function shown below on the form's onSave event, the result is that nothing happens.

    The "save button" in addition to the "save and close button" as well as the "save and new button" no longer functions. No error messages occur either. The form data just can't be saved and the save buttons act as if they don't work. 

    Whatever I do, needs to slide in-between the 3rd party plugin and the actual committing of the data.

    function GenerateLicenseIDOnSave(){
    //field1 – will always contain a G or B value 
    //field2 – will always two digit license year
    //field3 – will either contain letters and/or numbers or be null 
    //fieldA - the portion of the id number generated by the auto incrementing managed plugin – will always be populated via the 3rd party plugin solution once the save button is pressed. 
    //fieldL – destination where the final number must be copied to, final number is a concatenated combination of all the other fields 
    //fieldX – a two value radio button that must get set to yes once all five of these fields are properly populated 
    var fld1test = Xrm.Page.getAttribute("new_field1").getValue();
    var fldXtext = Xrm.Page.getAttribute("new_fieldx").getValue();
    var fld3test = Xrm.Page.getAttribute("new_field3").getValue();
    if  (fldXtest == true) {SetAllLicenseFieldsDisabled(); return;}
    else if (((fld1test ^= 'G') || (fld1test ^= 'B')) && ((fldXtest == null) || (fldXtest == false) || (fldxtest == 0)) && (fld3test == null)) {
    var fld1 = Xrm.Page.getAttribute("new_field1").getValue();
    var fld2 = Xrm.Page.getAttribute("new_field2").getValue();
    var fld3 = Xrm.Page.getAttribute("new_field3").getValue();
    var fldA = Xrm.Page.getAttribute("new_autonumber").getValue();
    var fldL = Xrm.Page.getAttribute("new_testlicenseid").getValue();
    var destination = field1 + "-" + field2 + "-"+ fieldA;
    Xrm.Page.getAttribute("new_testlicenseid").setValue(destination);
    Xrm.Page.getAttribute("new_fieldx").setValue(true)
    return;}
    else if (((fld1test ^= 'G') || (fld1test ^= 'B')) && ((fldXtest == null) || (fldXtest == false) || (fldxtest == 0)) && (fld3test != null)) {
              var destination1 = field1 + "-" + field2 + "-" + field3 + "-" + fieldA;
              Xrm.Page.getAttribute("new_testlicenseid").setValue(destination1);
              Xrm.Page.getAttribute("new_fieldx").setValue(true);
                                    return;}  
    }
    


     

  • Verified answer
    Aiden Kaskela Profile Picture
    19,696 on at

    Hi Jim,

    If you're adding that javascript to the Save event and none of the save events work anymore, there's absolutely a bug in your script which is preventing CRM from attempting to save the record. I've done it a hundred times, and that's going to be the case even if you didn't have the 3rd party tool installed. If you want to get that working, I'd start adding in code a few lines at a time until you find the point it doesn't work anymore.

    Javascript aside, if you want to concatenate the field but one of the values is set in a plugin then you should set your field in the plugin after that runs (as you suggested in your original post). You need to see when your auto-number plugin is running (it should be PreOperation) and make yours run after it. The Execution Order is what you want to set on your plugin to ensure it runs after another plugin. All the plugins run stage by stage, and within that stage it's Execution Order with lowest first - if there are ties then the earliest compiles assembly is run first.

    In the C# code, you can get your entity as a Target property. Here's a pretty good overview about how to get the entity being worked on: msdn.microsoft.com/.../gg309673.aspx

    When you have an Entity representing the record being updated, you can get properties by checing if an attribute exists:

      myEntity.Contains("my_field")

    and access is like:

      myEntity["my_field"].ToString()

    You'd build up your concatenated field by stringing them together based on if they have data or not. I like to test my plugins by doing as much as possible in a test application (eg: retrieve an entity from CRM via SDK and treat that as the entity coming into the plugin).

    Let me know if you have any issue building the plugin, I'd be happy to try and help. If this helps with your problem, I'd appreciate if you would mark this as a Verified answer.

    Thanks,

     Aiden

  • ACECORP Profile Picture
    1,589 on at

    I got the javascript working onSave but it executes before the auto-number plugin fills the field, so that option is off the table. As I suspected, it appears the only sure-fire way to do this is to write a plug-in that executes after the auto-number one does. I will focus my attention on that moving forward. I appreciate your info on the execution order and the C# code. That was definitely helpful and gives me a place to start. I already have a plugin project set up, albeit an empty one, so I will focus on adding the C# code and see where that takes me. Thanks again for the info. It is greatly appreciated!

  • Aiden Kaskela Profile Picture
    19,696 on at

    Hi Jim,

    I'm happy to help. Good luck with the plugins; if you have any issues just post them and we'll get it squared away.

    Thanks,

     Aiden

  • Suggested answer
    Community Member Profile Picture
    on at

    Hi, have you solved you problem? if not, I have a simple suggestion for you.

    do you have access to the code that increments that field? if yes, you could simply concatenate the fields AFTER you increment, got it?

    if you don't I think you could put a javascript on the "OnChange" event of the field you are incrementing, I'm not sure, but it may help you, good luck.

  • ACECORP Profile Picture
    1,589 on at

    No I  do not have access to that code. The auto-number plugin is closed source. It makes all kinds of custom determinations based on many things. Its actually not just an auto-increment,  but we "view it like that" for the simplicity of discussion.

    As of right now, the plug I wrote to combine the fields works from a functional standpoint and does exactly what I need it to do. However, it is executing before the other plug-in that does the auto-number executes, so I am close but not quite there yet. I have a ticket open with the plug-in's creator to find out when it executes, so once I get that info, I should be able to make the appropriate adjustment to mine.

    In the interim, I am going to change my plug-in from executing in the Pre-Validation stage to execute in the Post-Operation stage and see if that solves the problem.

    I will update accordingly.

    Thanks for your suggestions!

  • Verified answer
    Aiden Kaskela Profile Picture
    19,696 on at

    Hi Jim,

    You want to be really careful updating your record in the Post-Operation stage. That runs after the record is saved, so if you're setting a value there then you'll have to save it for it to be persisted in CRM. If you're always setting that field and saving, you can get into an infinite loop where the record is being saved over and over again. You can still do your logic in the post-operation stage, but you want to make sure that you only save the record again if the value changes.

    Thanks,

     Aiden

  • ACECORP Profile Picture
    1,589 on at

    As of right now, the plug I wrote to combine the fields works from a functional standpoint and does exactly what I need it to do. However, it is executing before the other plug-in that does the auto-number executes, so I am close but not quite there yet. As a fix, I removed my own Pre-Validation plugin and created a new one that is Post-Operation with a Rank of 999 to try to "guarantee" that mine comes in after the other one. However, now it doesn't work.

    *UPDATE** I also created a Pre-Operation Plug-In and set that to Rank 999, it works but it still happens BEFORE the other plug-in because I am not getting the correct from the field that other "closed source" plugin updates.

    I have a feeling the "closed source" plugin executes Post-Operation, but my Post-OP plug-in doesn't appear to work as it does not update any fields as it did when created as a Pre-Validation or Pre-Operation plug in.

    Anything special or different I need to do for a Post-Operation plugin compared to a Pre-Validation or Pre-Op?

    Any ideas or suggestions you have would be great!

  • Verified answer
    Aiden Kaskela Profile Picture
    19,696 on at

    Jim,

    If you missed my last post, go back and check that out. If you set a field in the Post Operation then it's after the record has been saved in CRM and you'll need to explicitly Update the record with the updated value.

    Thanks

    ,  Aiden

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics CRM (Archived)

#1
SA-08121319-0 Profile Picture

SA-08121319-0 4

#1
Calum MacFarlane Profile Picture

Calum MacFarlane 4

#3
Alex Fun Wei Jie Profile Picture

Alex Fun Wei Jie 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans