Archive
JavaScript Libraries in Microsoft Dynamics CRM 2011
In Microsoft Dynamics CRM 4, it is a very tedious task for system customizers to manage and track JavaScript. System Customizers/Developers have to write JavaScript on every event handler on the form. But Microsoft Dynamics CRM 2011 provides JavaScript libraries that can be utilized on events and forms across the solution. Now common JavaScript functions can be written at one centralized JavaScript file and utilized across solution.
Moreover, multiple JavaScript libraries can be created. For example, one common library for general CRM Service calls and one common library for UI manipulation and so on.
Let’s create a very simple JavaScript library and create a function to hide/show a tab/section on the form. JavaScript libraries are added as web resources in solution as shown below:
Now let’s create a JavaScript Common Library by adding a web resource in the solution. Then attach a JavaScript file this web resource.
Now let’s open the file in Text Editor available in web resource to add a function to show/hide a section/tab on form.
Microsoft Dynamics CRM 2011 provides new xrmPage model to access UI and data at client side. Here is a snapshot of the hierarchy.
Now let’s go to the account form in solution and then go to form properties to set JavaScript library and function to execute on form load event handler as shown below:
Now let’s add library from solution library.
Now let’s call the HideShowSection function in JavaScript Library by selecting appropriate JS library and typing the right function. Enable the event handler by setting Enable flag to true. Also pass parameter to function by comma separated list of parameters i.e. 1, false which in turn sets tab 1 to visible false.
You can see that Details tab is now hidden and alert.
Enhanced: FTP Server as Document Store for CRM4
Microsoft CRM can store files as annotation but is not a document management system at all. There are many ways to integrate CRM with Document Management Systems. My approach in this article is pretty much utilization of CRM as xRM. So this xRM based solution is built on top of powerful Dynamics CRM platform.
The idea behind this post is a cost effective way to create, persist, and distribute documents. Since document size can increase to GB’s so attaching documents as annotation is not a good idea and can clearly increase the size of database in days and degrade the system performance.
I am using FTP and FTPS protocol to manage documents. At CRM side i have created an entity representing document as a record and then associated this entity where ever required. So here is my entity.
I have document category and sub category (dependent picklist) to categorize and classify my document on FTP Server. I have a due date to trigger my document escalation/follow-up workflows. I have a status reason associated to a document (Draft/Approved/Pending/Rejected/On Hold/Reviewed). I have Upload and Download Button to save and retrieve document from FTP server. In the references section, I have the meta data attached to the document entity. The metadata could be a relationship to case/contact/account or any other custom entity. So in Case entity my document will appear as shown below:
I can instantly view the file without downloading it on local disk by just pressing download button and click open.
So now I can instantly Approve/Reject/On Hold/ Review in CRM by using ISV buttons depending on current user privileges.
I have a full log of actions on my document available with status, user performing action and dates.
I have a comprehensive log of correspondence on this document available as shown below:
I have configurable alerts regarding Pending document/document on hold or documents to be reviewed. They are available to me on daily/weekly/fortnightly/monthly etc. bases and they are right in my outlook with links to my document in CRM.
Also I can utilize these documents online in my customer portals (eService). My documents can be accessed online by using FTP/FTPs and utilized in various ways as below:
Support Portals
Online Product Catalogues
Online Newsletters
Online Product Notices
FTP Server as Document Store for CRM4
Microsoft CRM can store files as annotation but is not a document management system at all. There are many ways to integrate CRM with Document Management Systems. If you are looking for search within document, version control, and publishing workflow then this post is not for you.
The idea behind this post is to utilize CRM structural relationship model and build a Document Store to process documents and also a cost effective way create, persist, and distribute document. Since document size can increase to GB’s so attaching documents as annotation is not a good idea and can clearly increase the size of database in days.
I am using FTP and FTPS protocol to manage documents. At CRM side i have created an entity representing document as a record and then associated this entity where ever required. So here is my entity.\
I have document category and sub category (dependent picklist) to categorize and classify my document on FTP Server. I have Upload and Download Button to save and retrieve document from FTP server. In the references section, I have the meta data attached to the document entity. The metadata could be a relationship to case/contact/account or any other custom entity. So in Case entity my document will appear as shown below:
So now I can apply approval workflows in CRM whenever a new document is created.
Also I can utilize these documents online in my customer portals (eService). My documents can be accessed online by using FTP and utilized in various ways as shown below:
Auto Complete Recursive/Waiting Workflows – Microsoft CRM 4
Microsoft Dynamics CRM provides very powerful workflow designer tools to create workflows for various business scenarios. Waiting workflows are one of them. Very often, it is required to create waiting workflow on dates. So if a date is changed the waiting workflow remains in waiting state and date change executes another waiting workflow. So this aggregation of workflows affects CRM Server performance and application functionality.
Recently I have created a custom workflow activity to kill these waiting workflows in a recursive workflow. So I would like to share my experience with all of you.
I am in a condition to create a waiting workflow to reschedule my activity periodically i.e. recurring appointments, Auto Reorder (Sales Order) etc. My workflow is fired on Create of activity/Order and on change of Next Due date/Next Order Date. So if the user has changed Next Due Date or Next Order Date, the workflows in waiting remains in waiting and also a new Waiting workflow is fired. My aim is to kill the existing workflow as it is invalid now and start a new waiting workflow with updated information.
My workflow name is Auto Reschedule Activity. Here is the description of my workflow:
Start: Wait for Next Due Date == Today Reschedule Activity Accordingly Recursive Call: Auto Reschedule Activity EndWhat i am looking for is:
Start: Check if there is an existing workflow with same Workflow ID, Entity ID and in Waiting State. Then Kill that workflow. Wait for Next Due Date == Today Reschedule Activity Accordingly Recursive Call: Auto Reschedule Activity EndSo I started with a custom Activity to fetch workflows in waiting state with same name and regardingobjectid:
I created a query object in my custom workflow activity:
QueryExpression query = new QueryExpression(); query.EntityName = “asyncoperation”; query.ColumnSet = cols;And created 3 conditions as below:
ConditionExpression c1 = new ConditionExpression(); c1.AttributeName = “name”; c1.Operator = ConditionOperator.Equal; c1.Values = new Object[] {‘My workflow Name’}; //Workflow ConditionExpression c2 = new ConditionExpression(); C2.AttributeName = “statecode”; C2.Operator = ConditionOperator.Equal; C2.Values = new Object[] {1}; //Waiting ConditionExpression c3 = new ConditionExpression(); C3.AttributeName = “regadingobjectid”; C3.Operator = ConditionOperator.Equal; C3.Values = new Object[] {context. PrimaryEntityId}; //WaitingSo now I have all the waiting workflows regarding my activity. Ideally there will be only one workflow in waiting state all the time. This workflow will be responsible for rescheduling.
So now is the time to kill the outdated workflow. So here is the code for setting that workflow complete/cancelled.
foreach (BusinessEntity be in bec.BusinessEntities) { asyncoperation async = (asyncoperation)be; async.statecode = new AsyncOperationStateInfo(); async.statecode.Value = AsyncOperationState.Completed; service.Update(async); }You can improve this workflow utility to add lot more functionality to workflow designer.
HTML Content Editor in CRM4
It is often required to format and validate HTML contents in CRM 4. Here is a quick way of integrating a JavaScript WYSIWYG Editor. You can find many open source as well as 3rd part JavaScript WYSIWYG Editors. The editor I have used in my post is from TinyMCE – Javascript WYSIWYG Editor.
TinyMCE is a platform independent web based JavaScript HTML WYSIWYG editor control released as Open Source under LGPL by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances. TinyMCE is very easy to integrate into other Content Management Systems
So here is a step by step process to integrate this editor to CRM4.
Step One:
Create an ASPX page with only one HTML TEXTAREA control and a Submit Button. TextArea control will hold the content editor and button will move the generated HTML to crmForm Controls.
<asp:TextBox ID=”Content” runat=”server” TextMode=”MultiLine”></asp:TextBox>
<div>
<asp:Button ID=”btnSubmit” runat=”server” Text=”Submit”
onclick=”btnSubmit_Click” OnClientClick=”javascript:OnSubmit();” />
</div>
</form>
And copy the script as provided below:
This Script can be found at http://tinymce.moxiecode.com/examples/full.php#
<script src=”<your installation path>/tiny_mce/tiny_mce.js”></script>
<script>
tinyMCE.init({
// General options
mode : “textareas”,
theme : “advanced”,
plugins : “safari,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,imagemanager,filemanager”,
// Theme options
theme_advanced_buttons1 : “save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect”,
theme_advanced_buttons2 : “cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor”,
theme_advanced_buttons3 : “tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen”,
theme_advanced_buttons4 : “insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage”,
theme_advanced_toolbar_location : “top”,
theme_advanced_toolbar_align : “left”,
theme_advanced_statusbar_location : “bottom”,
theme_advanced_resizing : true,
// Example content CSS (should be your site CSS)
content_css : “css/example.css”,
// Drop lists for link/image/media/template dialogs
template_external_list_url : “js/template_list.js”,
external_link_list_url : “js/link_list.js”,
external_image_list_url : “js/image_list.js”,
media_external_list_url : “js/media_list.js”,
// Replace values for the template plugin
template_replace_values : {
username : “Some User”,
staffid : “991234″
}
});
</script>
Step Two:
Write two JavaScript functions to handle Onload and button submit events:
Onload will load the generated HTML to Editor and On Submit will submit form and load Generated HTML back to crmForm.
function OnSubmit()
{
document.myform.submit();
window.parent.document.forms[0].all.end_content.DataValue = document.getElementById(‘content’).value;
}
function OnLoad()
{
document.getElementById(‘content’).value = window.parent.document.forms[0].all.new_content.DataValue;
}
Step Three:
Place this page at ISV/ folder and use an IFRAME at the form where you want this editor to be visible. Set the IFRAME src to this aspx form and you all set to go.

Generated HTML in crmForm control.
![]()
Let me know in case you need any assistance or suggestions.





















Recent Comments