Stopping and continuing a save event

For some customizations you do need to stop the form onsave event, perform some business logic and continue the save event. An example would be that in specific conditions are met when a record is saved, then a popup will need to be shown. After filling in data in the popup and pressing a continue button on the popup, then the save operation would need to continue. The SDK helps in this situation. Look at the following page for more information. MSDN SDK: OnSave Event

On that page you will see that you can stop the onsave event by setting the 'event.returnValue = false'. Don't forget to follow that line with a 'return false'. This will cause the save procedure to stop right at that point. Otherwise statements after that will still be executed.

To call the save event from your javascript code, you can use the javascript functions crmForm.Save(); and crmForm.SaveAndClose(). By looking at the 'event.Mode' you can determine which event was executed before. If the code is 1, then it is a crmForm.Save(); or it is 2 for a crmForm.SaveAndClose(). There's only one small issue. There can be other save events as well. There's the 'save and new', 'save as completed', and also the 'send' for emails. Below is a list of save events with the corresponding javascript functions to call. Once again, this is not documented in the SDK, so this might change with a hotfix or new version.


Save
Code: 1
Function: crmForm.Save();


SaveAndClose
Code: 2
Function: crmForm.SaveAndClose();


Send
Code: 7
Function: send();


SaveAsCompleted
Code: 58
Function: SaveAsCompleted();


SaveAndNew
Code: 59
Function: crmForm.SubmitCrmForm(59, true, true, false);

Good luck!



Import CSV file to DataTable

I'm preparing a demo right now and for this I'm importing a CSV file to CRM. Especially the piece around the import of data from a CSV file to a DataTable is very generic. I'm sharing it with you guys for if it does make sense for you to use this as well.


class CSVReader
{
public System.Data.DataTable GetDataTable(string strFileName)
{
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Path.GetDirectoryName(strFileName) + "; Extended Properties = \"Text;HDR=YES;FMT=Delimited\"");
conn.Open();
string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]";
System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(strQuery, conn);
System.Data.DataSet ds = new System.Data.DataSet("CSV File");
adapter.Fill(ds);
return ds.Tables[0];
}
}


You can then use this class together with a code like this:

private void YourFunction()
{
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

CSVReader reader = new CSVReader();
DataTable dt = reader.GetDataTable("C:\\CoffeeContacts.csv");
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow dr = dt.Rows[i];

account acc = new account();
acc.name = dr["Company"].ToString();
service.Create(acc);
}
}



ForceSubmit in ASP.Net

Today I've been working on a simple IFrame. This IFrame shows 3 dynamic picklists and the data in these picklists is coming from crm. Since some clients are a bit slow, I would like the picklists to be disabled while the postback is being performed. This is easily done with this script:


function disableFields(field1, field2){
field1.disabled = true;
field2.disabled = true;
}

<asp:DropDownList ID="ddl1" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl2, form1.ddl3);">
<asp:DropDownList ID="ddl2" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl1, form1.ddl3);">
<asp:DropDownList ID="ddl3" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl1, form1.ddl2);">

This works perfectly, but... After a postback, the values of the selected picklists are gone! This seems like the same behavior as the disabled fields in CRM. In CRM you can solve this by setting the attribute ForceSubmit to true on the attribute, but I did not know of such an attribute.

Apparently there is such behaviour built into ASP.NET 2.0. In order to enable the submission of disabled form elements, you need to put this line in the Page_Load:

Page.Form.SubmitDisabledControls = true;

For more information on this attribute, check MSDN

Happy disabling!



Javascript and IFrames

I'm struggling with IFrames and JavaScript quite often. When you're working with this as well, the first thing to keep in mind is:

Deselecte the option "restrict cross site scripting" (in dutch "Het uitvoeren van scripts tussen frames beperken")

That usually saves a lot of troubles.

Furthermore, the next step is to create JavaScripts. One which I use quite often, is one which allows me to access a value in the IFrame. This is useful in onSave routines to copy data from the iframe to any of the CRM attributes. This is the code which I use:


crmForm.all.name.DataValue = crmForm.all.IFRAME_CustomIFrame.Document.formname.name.value;

In this example you do need to change the name of the attribute to which you want to save the data to (crmForm.all.name -> crmForm.all.yourSchemaName). The next modification is to change the name of the IFrame. When setting up an IFrame, you do supply a name. Change the IFRAME_CustomIFrame to IFRAME_YourIFrameName. Then on your custom html or aspx page, you do need to access the variable. That you can do by specifying the name of the form followed by the name of the attribute.

For other examples, look at the page of Jonas Deibe Playing around with iframes or Michael Höhne More JavaScript Code.



VPC CRM 4.0

Just like Microsoft has developed a VPC for CRM 3.0, they have created one for CRM 4.0 as well. Here's the link to the VPC: http://www.microsoft.com/downloads/details.aspx?FamilyID=dd939ed9-87a5-4c13-b212-a922cc02b469&DisplayLang=en



CrmDateTime conversion to DateTime

When working with CrmDateTime, you'll notice that this type does have a .value attribute, but the type of this attribute is string. There is no attribute to get the .net class DateTime out of your CrmDateTime. If you do want to use a DateTime anyway, you'd easily need to convert it. You could use any of these:


Convert.ToDateTime(crmdatetime.Value)
DateTime.Parse(crmdatetime.Value)

For more information on the CrmDateTime, look in the SDK:
http://msdn2.microsoft.com/en-us/library/aa613542.aspx



Logo Dynamics

For a presentation I needed a logo of Microsoft Dynamics. At that point I realized that I have never used an official logo for Microsoft Dynamics. Searching on the internet resulted in this page:

http://www.microsoft.com/Presspass/gallery/ms-logos.mspx?FINISH=YES

It includes logo's for most Microsoft products including Visual Studio, Office, Windows and of course Dynamics.