A few months ago I posted a method of importing external javascript files into CRM forms. See 'Reference External Javascript File in CRM Form Events'.
Some of you may have noticed an issue with this method when including multiple exeternal files. This is due to the fact that the process runs asynchronously while the rest of the code continues to execute.
A friend of mine Sam Manins managed to come up with a full work around for this. Thanks to Sam, the function below can be pasted into your OnLoad event for a more reliable method to import Javascript files into your CRM forms.
The idea is to invoke the command to add your external file, then wait for confirmation that the file was imported. Only then should we allow the code to continue. See comments within the code.
//Paste this function somewhere into your form "OnLoad" event
function includeExternalJSFiles(sec)
{
var errFound = 0;
// load the Ascentium js file into a Script element - do not do this on recursive calls to this function
if (sec == 1)
{
//Include the CRM js file
var Ascentium_Script = document.createElement("script");
Ascentium_Script.language = "javascript";
Ascentium_Script.src = "MyJSFunctions1.js"
document.getElementsByTagName("head")[0].appendChild(Ascentium_Script);
//Include another js file
var Ascentium_Script = document.createElement("script");
Ascentium_Script.language = "javascript";
Ascentium_Script.src = "MyJSFunctions2.js"
document.getElementsByTagName("head")[0].appendChild(Ascentium_Script);
//Add any more JS files you need
}
try
{
//Each file needs to have a simple function(with a unique name) that does nothing that can be called.
//then you can call this finction to see if the file has been imported yet.
MyJSFunction1_STUB();//this function is contained in the external JS file
MyJSFunction2_STUB();//this function is contained in the external JS file
}
catch(err)
{
//error found(probably could not find the function
errFound = 1;
}
if (sec < 5 && errFound == 1)
{
sec++;
setTimeout("includeExternalJSFiles(" + sec + ")", 100); //waits 0.1 second before trying the stubs again.
}
else
{
if (errFound == 1)
//Did not work after 5 attempts (0.5 seconds)
//Try a longer time period or output an error message for the user
//alert("Did not work: " + sec);
else
//All functions were found (all files imported)
//No need to do anything. Just exit functions and continue code
//alert("Success after " + sec + " attempts. ");
}
}
Remember to have a unique stub function to run in each external file. the function needs no do anything. Just needs to be there(See sample below).
//this function would be found in the file MyJSFunction1.js
function MyJSFunction1_STUB()
{
//stub function (does nothing)
var a;
}
Finally you need to call the function to import your Javascript files:
includeExternalJSFiles(0);
The above example makes the call to add the files to the page header, then continues to try to run a functions in each file every 0.1 seconds until successful or until 5 failed attempts. Different systems under different workloads may perform the job at different speeds. Feel free to modify the code to suit your needs.
And improvement on this function could be to also pass in the name of each Javascript file in an array, making it more generic.
A big thank you goes to Sam Manins for the solution.
Showing posts with label CRM Customization. Show all posts
Showing posts with label CRM Customization. Show all posts
Sunday, February 8, 2009
Sunday, September 7, 2008
Microsoft Dynamics CRM Javascript Access to Form Elements
Here's how to access each control on your forms using Javascript. Using this information you can add very useful functionality to CRM's front end.
There are a couple of ways to do this, you can choose which ever suits your situation best...
Currently displayed entitie's GUID:
crmForm.ObjectId
To access a control on the form:
crmForm.all.[attributename]
// OR
document.getElementById("[attributename]")
Hide/show attribute(set to visible or invisible):
//Hide it
crmForm.all.[attributename].style.display = "none";
//Show it
crmForm.all.[attributename].style.display = "inline";
Enable/disable attribute:
//Disable
crmForm.all.[attributename].Disabled = true;
//Enable
crmForm.all.[attributename].Disabled = false;
Does control/attribute contain any data?
if (crmForm.all.[attributename] != null)
//Contains some data
Control's value(this is the current on screen value. ie, may not have been saved yet):
crmForm.all.[attributename].DataValue
// OR
crmForm.all.[attributename].value
// OR if its a checkbox
crmForm.all.[attributename].Checked = [true false=""]
// OR if its a lookup
//Descriptive name for the selected item
crmForm.all.[attributename].DataValue.name
//GUID value of the selected item
crmForm.all.[attributename].DataValue.id
//Type of entity selected in the lookup(1=Account, 2=Contact...)
crmForm.all.[attributename].DataValue.type
//Descriptive name for the selected entity type
crmForm.all.[attributename].DataValue.typename
Reference External Javascript file in CRM form events
Some times you may have a great deal of Javascript code to insert into your CRM entity's form events, be it OnLoad, OnSave or OnChange of a control.
It is possible to encapsulate the functionality or procedures into separate JS files and reference them from the form. I often do this and have a list of standard JS files with specific functions as I need them. You can insert the file into your event by ading this block of code.
Don't forget to substitute your own server, port and filename. Ensure that it's hosted in a website or virtual directory and reachable from the CRMWeb website application.
It is possible to encapsulate the functionality or procedures into separate JS files and reference them from the form. I often do this and have a list of standard JS files with specific functions as I need them. You can insert the file into your event by ading this block of code.
//Insert JS Functions to perform whatever functionality:
var script = document.createElement("script");
script.language = "javascript";
script.src = "http://crmserver:5555/ISV/JSFiles/CRMControlFunctions.js";
document.getElementsByTagName("head")[0].appendChild(script);
Don't forget to substitute your own server, port and filename. Ensure that it's hosted in a website or virtual directory and reachable from the CRMWeb website application.
Saturday, September 6, 2008
Access MS CRM data through the Web Service via Javascript SDK
So I was madly typing away and badly mixing my languages up as I tried to remember how to access the CRM Web Service using Javascript from the front end when I finally succumbed to calling on a Google search.
I don't usually post something that I've already been able to find on the net, but it took me a while to find this and when I did... Oh man it was like a gift from heaven.
A fantastic post by Jason Hunt at Ascentium:
A Microsoft Dynamics CRM JavaScript SDK
http://www.ascentium.com/blog/crm/Post129.aspx
I don't usually post something that I've already been able to find on the net, but it took me a while to find this and when I did... Oh man it was like a gift from heaven.
A fantastic post by Jason Hunt at Ascentium:
A Microsoft Dynamics CRM JavaScript SDK
http://www.ascentium.com/blog/crm/Post129.aspx
Tuesday, August 26, 2008
Plugins and Add-ons With Multiple Server CRM Deployment
Recently I had a remarkable amount of trouble with the SDK on a particular CRM deployment. After a spot of poking around I managed to find that this deployment actually consists of 3 servers.
Application Server
Platform Server
Database Server
This configuration seemed to be working fine for some time with plugins hosted on the Application Server, but when I came to write applications using the web services hosted on the Platform Server I received the following error: 0x80044191 Assembly can not be loaded from C:\Program Files\Microsoft Dynamics CRM\server\bin\assembly\MyOrganisation.Plugins.dll. Platform.
Here's the fix:
If plugins are registered, ensure they are deployed with source on database.
If the plugin source MUST be on disk, then it must be stored on the Platform Server. Not the Application Server
Application Server
Platform Server
Database Server
This configuration seemed to be working fine for some time with plugins hosted on the Application Server, but when I came to write applications using the web services hosted on the Platform Server I received the following error: 0x80044191 Assembly can not be loaded from C:\Program Files\Microsoft Dynamics CRM\server\bin\assembly\MyOrganisation.Plugins.dll. Platform.
Here's the fix:
If plugins are registered, ensure they are deployed with source on database.
If the plugin source MUST be on disk, then it must be stored on the Platform Server. Not the Application Server
Labels:
CRM Customization,
Microsoft Dynamics CRM
Thursday, July 10, 2008
Customize CRM Logo image and colors...
I've spent a fair bit of time looking for ways to change the CRM header logo and page color... My final conclusion is that it is entirely unsupported by MS. Never the less, it is possible to customize your pages to suit your client/company look and feel.
Note carefully though, that these changes are completely unsupported and may be overwritten by service packs and/or hotfixes in the future.
CRM is essentially just a website with masses of .Net pages and SQL Server as its engine, its very easy to hack its content. Now, I would suggest strongly that you at least take a backup copy of every file you are about to modify or better yet, take a backup of the entire folder BEFORE you start.
Changing the CRM Logo to your company logo...
The easiest way is to go to your CRM installation's website files, typically C:\Program Files\Microsoft CRM\CRMWeb. This is where all the .Net files and images are stored.
The main logo image is C:\Program Files\Microsoft CRM\CRMWeb\_imgs\masthead.jpg along with masthead_live.jpg, masthead_live_rtl.jpg and masthead_rtl.jpg for various situations. You will also need to modify the file mast_back.gif. This image allows for resizing of the window.
Simply replace these images with your own copies to the same dimensions. and you now have your own branded CRM. That was the easy part.
Alternatively, you could modify the page(eg C:\Program Files\Microsoft CRM\CRMWeb\_common\styles\global-dynamic-styles.css.aspx) that calls these images, but logically, I think it would be safer an easier to just replace the images.
Changing all pages to suit your company's look and feel...
Now you want to change CRM's standard blue, outlook feel to suit your business.
This part of the job is massively time consuming. There are proximately 46 million aspx, css, xml, xsl... files and images within the CRMWeb folder. You need to visit each one individually and change any reference to a color to your own equivalant one. There doesn't seem to be a very good standard of colors used in CRM and you'll notice that there are 46 million slight variations of a similar shade of blue in each file. It almost as if they've done this on purpose to discourage developers from touching it!?!?!?
I suggest that you gather maybe 6 different shades of your own colors and systematically replace each CRM shade of blue. Every change is live upon saving, so you can check the resulting page instantly. Once all web pages have been visited, its time to modify each of the 46 million images(within the _img folder).
You should expect to spend 2-4 days depending on how finely you need it tuned.
NOTE: Occasionally the client browser may not update to recent changes and may need IE temporary files to be cleared.
Labels:
CRM Customization,
Microsoft CRM 4.0
Subscribe to:
Posts (Atom)