Need Alt solution for an Appointment Follow Up
-
08 Mayıs 2012 Salı 20:50
Requirement: When an appointment is Saved as Complete, pop up another appointment form with the regarding and required copied over from the appointment being completed.
I tried passing parameters by url, but CRM won't allow anything but a simple lookup to be set this way. Regarding & required are not simple look ups.
Any ideas on how to solve this? The follow up button on appointments comes close, so how is it passing the data?
Maybe I need to create the appointment, save it in the background, then pop it up to the user? How can I do that?
Is there a way to open up the appointment if it was created by a workflow?
Any ideas/thougts would be great!
-JP
Tüm Yanıtlar
-
08 Mayıs 2012 Salı 22:02Sahip
You can add custom parameters to the appointment form. See Configure a Form to Accept Custom Querystring Parameters
Those parameters might be named regarding1Type,regarding1Name,regarding1Id,regarding2Type,regarding2Name,regarding2Id,... depending on how many records you need to set in the regarding field.
Do the same thing with the Required fields.
When you open the new window using window.open add those parameters to the URL.
Then, in the appointment form onload event add a handler to look for those parameters. Use context.getQueryStringParameters
If those parameters exist, use the data to set the regarding lookup field values. See the sample at Set Lookup Attribute Value
I hope this helps
Jim Daly Technical Writer Microsoft Dynamics CRM
- Düzenleyen Jim Daly [MSFT]Microsoft Employee, Editor 08 Mayıs 2012 Salı 22:03 open link in new window
-
09 Mayıs 2012 Çarşamba 14:18
Thank you for the reply!
The instructions for configuring a Form to Accept Custom QueryString Parameters must be for 2011, I don't have the parameters tab on my form. I'm using 4.0. I'm able to do the following with some success:
var parms = 'snc_productid=' +crmForm.all.snc_productid.DataValue[0].id; parms += '&snc_productidname=' +crmForm.all.snc_productid.DataValue[0].name; parms += '®ardingobjectid=' +crmForm.all.regardingobjectid.DataValue[0].id; parms += '®ardingobjectidname=' +crmForm.all.regardingobjectid.DataValue[0].name; openStdDlg(prependOrgName('/userdefined/edit.aspx?etc=4201&' + parms));BUT - The regardingobject doesn't know what entity to make it, (it puts the name and ID in the field but with an odd icon and the link doesn't work) so I put in this line:
parms += '®ardingobjectidtype=' +crmForm.all.regardingobjectid.DataValue[0].typecode;
And that's when I get an error. Is this where you suggest using the 1? Do I need to get the string on the onload event? Is regardingobjectidtype the wrong name? I'm so in the dark on how all this works...
Any help would be great! Thanks!
-
09 Mayıs 2012 Çarşamba 14:48Sahip
Sorry, I assumed you were using CRM 2011.
For CRM 4 see the sample Create Activity Record Templates.
Also look at How to Work with Lookup Form Controls.
This is the sample from the latter, you need to use 'typename'
// Create an array to set as the DataValue for the lookup control. var lookupData = new Array(); // Create an object to add to the array. var lookupItem= new Object(); // Set the id, typename, and name properties to the object. lookupItem.id = '{1AAC1363-01A1-DB11-8432-0003FF9CE217}'; lookupItem.typename = 'account'; lookupItem.name = 'A Bike Store'; // Add the object to the array. lookupData[0] = lookupItem; // Set the value of the lookup field to the value of the array. crmForm.all.parentaccountid.DataValue = lookupData;Jim Daly Technical Writer Microsoft Dynamics CRM
- Yanıt Olarak İşaretleyen lifeIsPunny 17 Mayıs 2012 Perşembe 12:49
-
09 Mayıs 2012 Çarşamba 16:19
Great Information - I think I can make this work...I think. Thank you for your help. I'l mark as answer soon.
-
11 Mayıs 2012 Cuma 13:14
ok - next road block:
The code on the links you sent me is very helpful, I just one issue, so far anyway... The only thing that code looks for before it starts parsing is if the Form Type is 1 and if location.search is true. In their example that works for them because they are using a button to start it all. I'm starting mine from the OnSave of an appointment, so I need another check before it starts pasring becuase that condition is being met every time I click New appointment, and I don't want that. Should I put something in the url to check? Is there a way to check for 'I'm an Appointment that was created from the OnSave of antoher?'
Please let me know if I haven't stated this clearly.
Thanks!
-
11 Mayıs 2012 Cuma 14:13Sahip
Look at Form Event: OnSave
For an Appointment and other tasks, when the event.Mode = 58 you know that the appointment 'Save as Completed' button was the event that initiated the save.
Based on your statement of requirement in your first post, perhaps you can include this as the check you need?
Jim Daly Technical Writer Microsoft Dynamics CRM
-
11 Mayıs 2012 Cuma 15:22
Thanks for the reply! In the OnSave event I am checking for the event.Mode = 58 and that part is working fine.
My issue is the onLoad event of the appointment. When you click new appointment from an entitiy (Company/contact/etc.) the location.search contains data and therefore the parse starts, which is good, I want it to fill the regarding and required...but it's running the rest of the code and failing because it won't contain the product information. I need the Onload to only run the parse of the location.search when it's from a completed appiontment and not when selecting New - Appointment.
I may have just come up with a solution...let it parse, then check to see if the product information is contained in the information, if so set it, if not just set the required and regarding.
Thoughts?
This is the parse code I'm looking at using, I haven't customized it yet:
var CRM_FORM_TYPE_CREATE = 1;
// Only for new Tasks created with querystring parameters added.
if ((crmForm.FormType == CRM_FORM_TYPE_CREATE) && (location.search))
{
// Create an array to store the querystring parameters.
var request= new Array();
var vals=location.search.substr(1).split("&");
for (var i in vals)
{
vals[i] = vals[i].replace(/\+/g, " ").split("=");
request[unescape(vals[i][0])] = unescape(vals[i][1]);
}
// Get the priority and subject fields from the querystring.
// var prioritycode = parseInt(request["prioritycode"],10);
var subject = request["subject"];
// Set the due date based on the priority.
var oToday = new Date();
var oDate = oToday;
var iDate = oToday.getDate();
switch (prioritycode)
{
case 0: //Low Priority
iDate = iDate+3
break;
case 1: //Normal Priority
iDate = iDate+2
break;
case 2: //High Priority
iDate = iDate+1
break;
}
oDate.setDate(iDate);
// Set the values for the priority, subject, and due date.
//crmForm.all.prioritycode.DataValue = prioritycode;
crmForm.all.subject.DataValue = subject;
crmForm.all.scheduledend.DataValue = oDate;
// Get information from the parent account.
if (window.opener)
{
var oParentCrmForm = window.opener.document.all.crmForm;
if (oParentCrmForm)
{
var gRecordId = oParentCrmForm.ObjectId;
var sRecordName = oParentCrmForm.all.name.DataValue;
var sFormTypeName = oParentCrmForm.ObjectTypeName;
var lookupData = new Array();
var lookupItem = new Object();
lookupItem.id = gRecordId;
lookupItem.typename = sFormTypeName;
lookupItem.name = sRecordName;
lookupData[0] = lookupItem;
// Set the value of the Resgarding lookup field
crmForm.all.regardingobjectid.DataValue = lookupData;
}
}
}
- Düzenleyen lifeIsPunny 11 Mayıs 2012 Cuma 15:24
-
11 Mayıs 2012 Cuma 15:57
Alright - I solved the issue I was having above by checking for a subject, if it's not there the Form goes about it's regular business. Now I think the issue I'm having is I'm not passing the information correctly. I get the standard "An Error has Occurred" when I tried to open a new appointment. ANY help would be great.
OnSave event Code:
//give it something to check for var parms = 'subject=this'; //Grab the information from the form and develop the URL parms += '®ardingobjectid=' +crmForm.all.regardingobjectid.DataValue[0].id; parms += '®ardingobjectidname=' +crmForm.all.regardingobjectid.DataValue[0].name; parms += '®ardingobjectidtype=' +crmForm.all.regardingobjectid.DataValue[0].typename; //Open a new appointment with this URL openStdDlg(prependOrgName('/activities/appointment/edit.aspx?&' + parms));OnLoad Event:
var CRM_FORM_TYPE_CREATE = 1; // Only for new Tasks created with querystring parameters added. if ((crmForm.FormType == CRM_FORM_TYPE_CREATE) && (location.search)) { // Create an array to store the querystring parameters. var request= new Array(); var vals=location.search.substr(1).split("&"); for (var i in vals) { vals[i] = vals[i].replace(/\+/g, " ").split("="); request[unescape(vals[i][0])] = unescape(vals[i][1]); } //If there is a subject, set the fields wanted var subject = request["subject"]; if(subject) { //set the regarding var lookupdataRegarding = new Array(); var lookupItemRegarding = new Object(); lookupItemRegarding.id = request['regardingobjectid']; lookupItemRegarding.typename = request['regardingobjectidtype']; lookupItemRegarding.name = request['regardingobjectidname']; lookupdataRegarding[0] = lookupItemRegarding; crmForm.all.regardingobjectid.DataValue = lookupdataRegarding; } else //for testing only so I know it hit the condition correctly alert('there was no subject all is cool'); }
-
11 Mayıs 2012 Cuma 16:30Sahip
Try this
openStdDlg(prependOrgName('/activities/appointment/edit.aspx?&' + encodeURIComponent(parms)));There could be some characters in the values of the parameters that you are passing that could be breaking stuff. See http://msdn.microsoft.com/en-us/library/aeh9cef7(VS.85).aspx
BTW - openStdDlg is an internal function that we don't support people using. window.open is the supported method to open a new window. But this is probably not the cause of the error you are getting.
Jim Daly Technical Writer Microsoft Dynamics CRM
- Düzenleyen Jim Daly [MSFT]Microsoft Employee, Editor 11 Mayıs 2012 Cuma 16:39 note that openStdDlg is not supported
-
11 Mayıs 2012 Cuma 18:08
Just to make sure openStdDlg wasn't the problem I switched to window.open and my code now looks like this:
window.open('/activities/appointment/edit.aspx?&' + encodeURIComponent(parms));
This is the url of the error, does this make any sense to you?
http://servername.domain.com/tenantname/_common/error/errorhandler.aspx?ErrorCode=&RequestUri=%2factivities%2fappointment%2fedit.aspx%3f%26subject%253Dthis%2526regardingobjectid%253D%257B5E02C92F-A1E0-DF11-9545-00219B955415%257D%2526regardingobjectidname%253D1st%2520ABC%2520Company%2526regardingobjectidtype%253Daccount&BackUri=
-
11 Mayıs 2012 Cuma 18:36Sahip
The URL for the error doesn't help very much.
We know that the subject parameter can be passed without a problem. right?
You still have to set the subject value in your onload event code.
I think the issue is that the page is getting parameters that unexpected and therefore are being blocked by the application.
In CRM 2011 we have a similar issue with the web resources feature. These URL addressable pages only support a single parameter that can be passed. That parameter is 'data'.
In this cases, you might be able to apply the same strategy described in the CRM 2011 SDK topic Sample: Pass Multiple Values to a Web Resource Through the Data Parameter
The basic idea is to encode a lot of custom parameters and set them as the value of the 'data' parameter. Then pull them out of the 'data' parameter, except in your case you would use the 'subject' parameter.
One thing to be aware of though is this might cause issues when you upgrade to CRM 2011 because in CRM 2011 the subject field can be set via the querystring parameters. So it could try and set the encoded value which could very easily exceed the maximum length allowed for the subject field. I think that could throw an error before your onload event code would have a chance to set the subject field correctly. If this works you will want to make sure to refactor your code when you upgrade.
Jim Daly Technical Writer Microsoft Dynamics CRM
- Yanıt Olarak İşaretleyen lifeIsPunny 17 Mayıs 2012 Perşembe 12:48
- Yanıt İşaretini Geri Alan lifeIsPunny 17 Mayıs 2012 Perşembe 12:48
-
11 Mayıs 2012 Cuma 18:52
I think you're right in that the page is being past something unexpected and therefore is blocking - I just discovered that the page is giving me the error BEFORE any of the code is gone through. The URL I pass isn't getting a chance to run through the OnLoad code.
I'll figure out how to change the code in the link you sent me to work for what I'm trying to do and post again.
-
11 Mayıs 2012 Cuma 19:22
I remembered in CRM 4, you'll need to do a registry change to allow custom querystrings to be passed in to the form.
If you haven't done so, you'll need to add / update a DWORD registry key named DisableParameterFilter under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM.
Set the value to 1.
Once you've done this, restart the IIS and it should work fine.
PS: Make sure that you back up the registry before making this changes.
Dimaz Pramudya - CRM Developer - CSG (Melbourne) www.xrmbits.com http://twitter.com/xrmbits
- Yanıt Olarak Öneren Dimaz Pramudya (www.xrmbits.com) 11 Mayıs 2012 Cuma 19:22
- Yanıt Olarak İşaretleyen lifeIsPunny 17 Mayıs 2012 Perşembe 12:48
-
14 Mayıs 2012 Pazartesi 19:43
Thanks Dimaz, that was the overall answer, although all the other code help made it all work very nice after I added that registry key.
Another question. Required can have multiple objects in them. I assume I need to loop through them. on both sides, but I'm at a loss as to how to do that, then set multiple values. Any help would be great!
Below is the code I'm currently using.
OnSave:
//Save as Complete if(event.Mode ==58) { //I replaced subject for check with popup as I don't want to set subject var parms = 'popup=true'; //Required object, can be mulitple parms += '&requiredobjectid=' +crmForm.all.requiredattendees.DataValue[0].id; parms += '&requiredobjectname=' +crmForm.all.requiredattendees.DataValue[0].name; parms += '&requiredobjecttype=' +crmForm.all.requiredattendees.DataValue[0].typename; //regarding object, 1 and only 1 parms += '®ardingobjectid=' +crmForm.all.regardingobjectid.DataValue[0].id; parms += '®ardingobjectidname=' +crmForm.all.regardingobjectid.DataValue[0].name; parms += '®ardingobjectidtype=' +crmForm.all.regardingobjectid.DataValue[0].typename; //URL openStdDlg(prependOrgName('/userdefined/edit.aspx?etc=4201&' + parms)); }OnLoad:
//From the onload event of appointment var CRM_FORM_TYPE_CREATE = 1; // Only for new Tasks created with querystring parameters added. if ((crmForm.FormType == CRM_FORM_TYPE_CREATE) && (location.search)) { // Create an array to store the querystring parameters. var request= new Array(); var vals=location.search.substr(1).split("&"); for (var i in vals) { vals[i] = vals[i].replace(/\+/g, " ").split("="); request[unescape(vals[i][0])] = unescape(vals[i][1]); } //If there is a subject, set the fields wanted var popup = request["popup"]; if(popup) { //set the regarding var lookupdataRegarding = new Array(); var lookupItemRegarding = new Object(); lookupItemRegarding.id = request['regardingobjectid']; lookupItemRegarding.typename = request['regardingobjectidtype']; lookupItemRegarding.name = request['regardingobjectidname']; lookupdataRegarding[0] = lookupItemRegarding; crmForm.all.regardingobjectid.DataValue = lookupdataRegarding; //set the required var lookupdataRequired = new Array(); var lookupItemRequired = new Object(); lookupItemRequired.id = request['requiredobjectid']; lookupItemRequired.typename = request['requiredobjecttype']; lookupItemRequired.name = request['requiredobjectname']; lookupdataRequired[0] = lookupItemRequired; crmForm.all.requiredattendees.DataValue = lookupdataRequired; } else //for testing only so I know it hit the condition correctly alert('there was no subject all is cool'); }
Thanks!
-
14 Mayıs 2012 Pazartesi 22:59
Hi lifeIsPunny,
In your OnSave method, you can combine all the required ids into a single comma separated text. The same thing goes with the requiredobjectname and requiredobjecttype.
So your code will look something like this:
//Required object, can be multiple var reqObjIds = ''; var reqObjNames = ''; var reqObjTypes = ''; for (var i =0; i < crmForm.all.requiredattendees.DataValue.length; i++) { reqObjIds += crmForm.all.requiredattendees.DataValue[i].id + ','; reqObjNames += crmForm.all.requiredattendees.DataValue[i].name + ','; reqObjTypes += crmForm.all.requiredattendees.DataValue[i].typename + ','; } parms += '&requiredobjectid=' + reqObjIds; parms += '&requiredobjectname=' + reqObjNames; parms += '&requiredobjecttype=' + reqObjTypes;And from the onload, you'll just need to get the value from requiredobjectid and split them by comma.
Dimaz Pramudya - CRM Developer - CSG (Melbourne) www.xrmbits.com http://twitter.com/xrmbits
- Yanıt Olarak Öneren Dimaz Pramudya (www.xrmbits.com) 14 Mayıs 2012 Pazartesi 23:01
-
15 Mayıs 2012 Salı 15:34
Thanks!
Another question, if I haven't worn out your patience already...
In the Onload event, I THINK I can figure out how to parse the String based on the comma, but how do I set the required? I assume I need to place an index [i] somewhere, but I get an error everywhere I've tried:
//Parse the string by comma into an array? //for loop of (var i = 0, i<length of array, i++) var lookupdataRequired = new Array(); var lookupItemRequired = new Object(); lookupItemRequired.id = request['requiredobjectid']; lookupItemRequired.typename = request['requiredobjecttype']; lookupItemRequired.name = request['requiredobjectname']; lookupdataRequired[0] = lookupItemRequired; crmForm.all.requiredattendees.DataValue = lookupdataRequired; //Do I use an index when I set the field? //crmForm.all.requiredattendees.DataValue[i]?
Thanks!
-
15 Mayıs 2012 Salı 22:53
lifeIsPunny,
Can you try the following code?
var lookupdataRequired = new Array(); for (var i=0; i < arrayLength; i++) { var lookupItemRequired = new Object(); lookupItemRequired.id = request['requiredobjectid']; lookupItemRequired.typename = request['requiredobjecttype']; lookupItemRequired.name = request['requiredobjectname']; lookupdataRequired[i] = lookupItemRequired; } crmForm.all.requiredattendees.DataValue = lookupdataRequired;I hope this helps. If my response answered your question, please mark the response as an answer and also vote as helpful.
Dimaz Pramudya - CRM Developer - CSG (Melbourne) www.xrmbits.com http://twitter.com/xrmbits
- Yanıt Olarak Öneren Dimaz Pramudya (www.xrmbits.com) 15 Mayıs 2012 Salı 22:53
- Düzenleyen Dimaz Pramudya (www.xrmbits.com) 15 Mayıs 2012 Salı 22:53
- Düzenleyen Dimaz Pramudya (www.xrmbits.com) 15 Mayıs 2012 Salı 22:54
-
16 Mayıs 2012 Çarşamba 15:47
This is PERFECT!!!!
Everything is working great, except one issue, that's not really an issue, I just know it'll throw off my end users.
It's having trouble with names that have an & in them, like: A&B Company. It'll display it as A. Everything is good because it has the ID number and next time the appoitment is opened it reads correctly. I assume I need to escape those characters some how. Can you help me with how?
For anyone who comes across this later and wants the code, here's what I did:
On Save:
//Save as Complete if(event.Mode ==58 && crmForm.all.snc_result.SelectedText != '') //result has to be filled before the appointment will save as complete { //Only set as a marker to be used in the OnLoad Event var parms = 'popup=true'; //if there isn't a value in required, don't send that information try { //Required object, can be mulitple var reqObjIds = ''; var reqObjNames = ''; var reqObjTypes = ''; //loop through to get all the required attendees for (var i =0; i < crmForm.all.requiredattendees.DataValue.length; i++) { reqObjIds += crmForm.all.requiredattendees.DataValue[i].id + ','; reqObjNames += crmForm.all.requiredattendees.DataValue[i].name + ','; reqObjTypes += crmForm.all.requiredattendees.DataValue[i].typename + ','; } parms += '&requiredobjectid=' + reqObjIds; parms += '&requiredobjectname=' + reqObjNames; parms += '&requiredobjecttype=' + reqObjTypes; } catch (err) { } //if there isn't a value in required, I don't want the pop up try { //regarding object, 1 and only 1 parms += '®ardingobjectid=' +crmForm.all.regardingobjectid.DataValue[0].id; parms += '®ardingobjectidname=' +crmForm.all.regardingobjectid.DataValue[0].name; parms += '®ardingobjectidtype=' +crmForm.all.regardingobjectid.DataValue[0].typename; //URL openStdWin(prependOrgName('/userdefined/edit.aspx?etc=4201&' + parms)); }//close try catch(err) { } }//close ifOnLoad event:
//From the onload event of appointment var CRM_FORM_TYPE_CREATE = 1; // Only for new Tasks created with querystring parameters added. if ((crmForm.FormType == CRM_FORM_TYPE_CREATE) && (location.search)) { // Create an array to store the querystring parameters. var request= new Array(); var vals=location.search.substr(1).split("&"); for (var i in vals) { vals[i] = vals[i].replace(/\+/g, " ").split("="); request[unescape(vals[i][0])] = unescape(vals[i][1]); } //If there is a value in popup, set the fields wanted var popup = request["popup"]; if(popup) { //set the regarding var lookupdataRegarding = new Array(); var lookupItemRegarding = new Object(); lookupItemRegarding.id = request['regardingobjectid']; lookupItemRegarding.typename = request['regardingobjectidtype']; lookupItemRegarding.name = request['regardingobjectidname']; lookupdataRegarding[0] = lookupItemRegarding; crmForm.all.regardingobjectid.DataValue = lookupdataRegarding; //only if data came for required do this if(request['requiredobjectid']) { //put the string into a var var requiredid = request['requiredobjectid']; //create an array to store the required var id = new Array(); //parse the string into the array id = requiredid.split(','); //repeat for type var requiredtype = request['requiredobjecttype']; var type = new Array(); type = requiredtype.split(','); //repeat for name var requiredname = request['requiredobjectname']; var name = new Array(); name = requiredname.split(','); //array to hold all the required values var lookupdataRequired = new Array(); //loop through the array to get all values for (var i=0; i < id.length - 1; i++) { var lookupItemRequired = new Object(); lookupItemRequired.id = id[i]; lookupItemRequired.typename = type[i]; lookupItemRequired.name = name[i]; lookupdataRequired[i] = lookupItemRequired; } //take all values at once and put into required crmForm.all.requiredattendees.DataValue = lookupdataRequired; }//end if required contains data }//end if pop up }//end if got data- Yanıt Olarak İşaretleyen lifeIsPunny 17 Mayıs 2012 Perşembe 12:48
-
16 Mayıs 2012 Çarşamba 20:52
Hi lifeIsPunny,
The way to get around the & is to encode it to & when you pass in the data.
You can encode it using this function on your OnSave function.
reqObjNames += crmForm.all.requiredattendees.DataValue[i].name.replace(/&/g, "&").replace(/"/g, """) + ',';
Now, I haven't checked whether you'll need to decode it back during the OnLoad process. But if you do, you'll just do it the other way around.
I hope this helps. If my response answered your question, please mark the response as an answer and also vote as helpful.
Dimaz Pramudya - CRM Developer - CSG (Melbourne) www.xrmbits.com http://twitter.com/xrmbits
- Yanıt Olarak Öneren Dimaz Pramudya (www.xrmbits.com) 16 Mayıs 2012 Çarşamba 20:52
- Yanıt Olarak İşaretleyen lifeIsPunny 17 Mayıs 2012 Perşembe 12:48
-
17 Mayıs 2012 Perşembe 11:51
Hi lifeIsPunny,
How is it going? Did the code work fine?
If my response answered your question, please mark the response as an answer and also vote as helpful so that it can help others finding the answer easily.
Dimaz Pramudya - CRM Developer - CSG (Melbourne) www.xrmbits.com http://twitter.com/xrmbits
-
17 Mayıs 2012 Perşembe 11:55It came in as I as leaving yesterday. I threw it in real quick, but it didn't work. I didn't get an error, it just didn't do what it was suppose to do. I'm thinking it's something with the quote marks or needing a slash with it...I just got back into work and was going to look at it now. I'll let you know.
-
17 Mayıs 2012 Perşembe 12:47
I had to tweak it a little, I ended up using this:
reqObjNames += crmForm.all.requiredattendees.DataValue[i].name.replace(/&/g, "%26")+ ',';
With that there is no decoding on the other side, the system reads it perfectly.
THANK YOU, THANK YOU, THANK YOU!!! I could not have done this with out your help. I have marked all the posts that are answers. I want to point out to future readers that none of this would have worked without the registery edit.
Thank you again!
- Yanıt Olarak İşaretleyen lifeIsPunny 17 Mayıs 2012 Perşembe 12:48