2009/09/23

CRM 4.0 Software prerequisites

Not running on 2008 platform
In addition to the software prerequisites below,
the Main Admin Account (which will be the Main Service account in CRM) to be used in the CRM 4.0 Install
must be a local administrator on the CRM Application Server, and possibly on the SQL Server as well.

Also the Main Admin Account must have full+extended privileges on the specified Organizational Unit (OU) in Active Directory (AD)...

For the CRM Server (IIS Server), the following must be installed:
1. Windows Server 2003 (Standard or Enterprise Edition, preferably Enterprise Edition on Production) with Service Pack 2
2. IIS 6 (with all options installed)
3. Also Windows Indexing Service

Please note that the following services must then be running on the CRM Server (IIS Server):
- Indexing Service
- World Wide Web Publishing
- IIS Admin Service

Then the actual CRM install will go and install the rest of the software listed below (from Microsoft_Dynamics_CRM_IG_Installing.doc, Section 2-8, Page 15):
(Please note that Microsoft .Net Framework 2 and Microsoft .Net Framework 3 can and be installed before this)
• SQL Server 2005 Reporting Services Report Viewer control
• Microsoft SQL Server Native Client
• Microsoft Application Error Reporting tool
• Microsoft Visual C++ Runtime Library
• MSXML 6
• Microsoft .NET Framework 3.0, which includes the following components:
o .NET Framework 2.0 (required by Microsoft Dynamics CRM Server)
o Windows® Workflow Foundation (required by Microsoft Dynamics CRM Server)
o Windows Presentation Foundation
o Windows Communication Foundation

And the SQL Server 2005 Server must have SQL Server 2005 (Standard or Enterprise Edition, preferably Enterprise Edition on Production)
with the following SQL Server components installed with Service Pack 2 applied on them:
1. SQL Server 2005 Database Engine with SP2
2. SQL Server 2005 Agent with SP2
3. SQL Server 2005 Reporting Services with SP2
4. SQL Server 2005 Full Text Search with SP2

I think that about covers it, but If I missed anything, perhaps the other guys can spot it…

2009/09/02

Some useful CRMform jscripts

<span style="font-family:arial;font-size:85%;">/*
function isFormInCreateMode()
function isFormInUpdateMode()
isFormActive = function()
hideNavBarItemById = function(navBarItemId)
setNavBarItemVisibilityByName = function(sectionName, itemName, visible)
hideNavBarItemByName = function(sectionName, itemName)
showNavBarItemByName = function(sectionName, itemName)
setFormEnabled = function(enabled)
hideTabById = function(tabId)
hideTabByName = function(tabName)
setControlEnabled = function(fieldObject, enabled)
setFieldRequired = function(fieldObject)
setFieldRecommended = function(fieldObject)
setFieldNotRequired = function(fieldObject)
refParam = function()
getLastKnownGood = function(fieldObject)
setLastKnownGood = function(fieldObject, value)
captureLastKnownGood = function(fieldObject)
restoreLastKnownGood = function(fieldObject)
hookValidationOnChange = function(fieldObject)
hookValidationOnBlur = function(fieldObject)
hookValidation = function(fieldObject, functionPointer, optionalFocusFieldObject)
performValidation = function()
function guidString4()
createGuid = function()
hideActionMenuItem = function(itemName)
HideAssociatedViewButtons = function(loadAreaId, buttonTitles)

*/

<strong>// Check if form in CREATE mode</strong>
isFormInCreateMode = function()
{
if (crmForm.FormType == 1)
return true;
else
return false;
}

<strong>// Check if form in UPDATE mode
</strong>isFormInUpdateMode = function()
{
if (crmForm.FormType == 2)
return true;
else
return false;
}

isFormActive = function()
{
var active = true;
if (crmForm.all.statecode != null &amp;&amp; crmForm.all.statecode.DataValue != null )
active = (crmForm.all.statecode.DataValue == 0);
if( active )
active = (crmForm.FormType <> 4); // not readonly or disabled
return active;
}

/************************************************************************************************************************/
<strong>/* Navigation Map Functions</strong>
/************************************************************************************************************************/

/* hide a navigation bar item */
hideNavBarItemById = function(navBarItemId)
{
var navBar = document.getElementById(navBarItemId)

if (navBar != null)
{
navBar.style.display = "none";
}
}

<strong>/* hide a tab using the tab name as reference */</strong>
setNavBarSectionVisibilityByName = function( sectionName, visible )
{
var groups = document.getElementById("crmNavBar").childNodes;

if( groups != null )
{
for( var i = 0; i < groups.length; i++ )
{
var groupName = groups[i].childNodes[0];

if( groupName.innerText.trim() == sectionName )
{
groupName.style.display = visible ? "block" : "none";
groups[i].childNodes[1].style.display = visible ? "block" : "none";
}
}
}
}

<strong>/* hide a tab using the tab name as reference */</strong>
setNavBarItemVisibilityByName = function( sectionName, itemName, visible )
{
var groups = document.getElementById("crmNavBar").childNodes;

if( groups != null )
{
for( var i = 0; i < groups.length; i++ )
{
var groupName = groups[i].childNodes[0];

if( groupName.innerText.trim() == sectionName )
{
var items = groups[i].childNodes[1].childNodes;
for( var n = 0; n < items.length; n++ )
{
var item = items[n];

if( item.innerText.trim() == itemName )
item.style.display = visible ? "inline" : "none";
}
}
}
}
}

<strong>/* hide a tab using the tab name as reference */</strong>
hideNavBarItemByName = function( sectionName, itemName )
{
setNavBarItemVisibilityByName(sectionName, itemName, false);
}

/* hide a tab using the tab name as reference */
showNavBarItemByName = function( sectionName, itemName )
{
setNavBarItemVisibilityByName(sectionName, itemName, true);
}

/************************************************************************************************************************/
<strong>/* Form Functions</strong>
/************************************************************************************************************************/

setFormEnabled = function(enabled)
{
var iLen = crmForm.all.length;

for (i = 0; i < iLen; i++)
{
crmForm.all[i].Disabled = !enabled;
}
}

<strong>// gets the ordinal position of a tab</strong>
getTabNumber = function( tabName ) {
var tabs = document.getElementById("crmTabBar").childNodes;
if( tabs != null ) {
for (var i = 0; i < tabs.length; i++) {
var tab = tabs[i];
if (tab.innerText == tabName) {
return i;
}
}
}
return -1;
}

<strong>// returns a tab by name</strong>
getTabByName = function( tabName ) {
var tabs = document.getElementById("crmTabBar").childNodes;
if (tabs != null) {
var num = getTabNumber(tabName);
if( num >= 0 ) {
return tabs[num];
}
}
return null;
}

<strong>/* disable or enable tab using the tab name as reference */</strong>
setTabEnabledByName = function(tabName, enabled)
{
var tab = getTabByName(tabName);
if( tab != null ) {
tab.disabled = !enabled;
}
}

<strong>/* hide a tab using the tab id as reference */</strong>
hideTabById = function(tabId)
{
var tab = document.getElementById(tabId);
if( tab != null ) {
tab.style.display = "none";
}
}

<strong>/* hide a tab using the tab name as reference */</strong>
hideTabByName = function(tabName)
{
var tab = getTabByName(tabName);
if( tab != null ) {
//alert(tab.style.display);
tab.style.display = "none";
}
}

<strong>/* show a tab using the tab name as reference */
</strong>showTabByName = function(tabName)
{
var tab = getTabByName(tabName);
if( tab != null ) {
tab.style.display = "block";
}
}

<strong>/* Enabled/disable a control by setting the disabled property and toggling "ms-crm-ReadOnly" on the classname */</strong>
setControlEnabled = function(fieldObject, enabled)
{
fieldObject.disabled = !enabled;

if (!enabled &amp;&amp; fieldObject.className.indexOf("ms-crm-Text") >= 0) {
// append readonly property to className if not already there
if (fieldObject.className.indexOf("ms-crm-ReadOnly") < 0)
fieldObject.className += " ms-crm-ReadOnly";
}
else
fieldObject.className = fieldObject.className.replace(/ ms-crm-ReadOnly/gi, "");
}

setFieldRequired = function(fieldObject)
{
crmForm.SetFieldReqLevel(fieldObject.id, 2);
}

setFieldRecommended = function(fieldObject)
{
crmForm.SetFieldReqLevel(fieldObject.id, 1);
}

setFieldNotRequired = function(fieldObject)
{
crmForm.SetFieldReqLevel(fieldObject.id, 0);
}

/************************************************************************************************************************/
<strong>/* Validation base functions</strong>
/************************************************************************************************************************/

/* represents a parameter object to be passed by reference
* use param.setValue from a function to set the return value of the parameter
* use param.getValue to read the returned value
*/
refParam = function()
{
this.array = new Array(1);
this.setValue = function(v) { this.array[0] = v; }
this.getValue = function() { return this.array[0]; }
}

/* gets/captures/restores the value of the field as the last known good value */
getLastKnownGood = function(fieldObject)
{
return fieldObject.getAttribute("lastKnownGood");
}
setLastKnownGood = function(fieldObject, value)
{
fieldObject.setAttribute("lastKnownGood", value);
}
captureLastKnownGood = function(fieldObject)
{
setLastKnownGood(fieldObject, fieldObject.DataValue);
}
restoreLastKnownGood = function(fieldObject)
{
fieldObject.DataValue = getLastKnownGood(fieldObject);
}

/*
* captures last known good value (captureLastKnownGood)
* hooks validation of the field onto the "onchange" event
*/
hookValidationOnChange = function(fieldObject)
{
fieldObject.setAttribute("onblur", null);
fieldObject.setAttribute("onchange", performValidation);
}
hookValidationOnBlur = function(fieldObject)
{
fieldObject.setAttribute("onchange", null);
fieldObject.setAttribute("onblur", performValidation);
}
hookValidation = function(fieldObject, functionPointer, optionalFocusFieldObject)
{
captureLastKnownGood(fieldObject);
fieldObject.setAttribute("validationFunction", functionPointer);
if( optionalFocusFieldObject != null )
fieldObject.setAttribute("focusFieldObject", optionalFocusFieldObject);
fieldObject.setAttribute("onchange", performValidation);
}
performValidation = function()
{
var fieldObject = event.srcElement;
if( fieldObject.DataValue != getLastKnownGood(fieldObject) )
{
var functionPointer = fieldObject.getAttribute("validationFunction");

var message = new refParam();
var valid = functionPointer(fieldObject, message);

if( !valid )
{
var msg = message.getValue() + "rnnWould you like to correct the value?";
if( confirm(msg) )
{
var focusObject = fieldObject.getAttribute("focusFieldObject");
if( focusObject == null )
focusObject = fieldObject;
else
{
captureLastKnownGood(fieldObject);
hookValidationOnChange(fieldObject);
setLastKnownGood(focusObject, null);
}

focusObject.SetFocus();
event.returnValue = false;
hookValidationOnBlur(focusObject);
}
else
{
restoreLastKnownGood(fieldObject);
hookValidationOnChange(fieldObject);
}
}
else
{
captureLastKnownGood(fieldObject);
hookValidationOnChange(fieldObject);
}
}
else
hookValidationOnChange(fieldObject);
}

guidString4 = function()
{
return (((1 + Math.random()) * 0x10000) 0).toString(16).substring(1);
}

createGuid = function()
{
return (guidString4() + guidString4() + "-" + guidString4() + "-" + guidString4() + "-" + guidString4() + "-" + guidString4() + guidString4() + guidString4()).toUpperCase();
}

<strong>/* hide action menu item */</strong>
hideActionMenuItem = function(itemName)
{
var element = document.getElementById(itemName)

if (element != null) {
element.style.display = "none";
}
}

hideActionMenuDeleteButton = function()
{
hideActionMenuItem("_MIonActionMenuClickdelete" + crmForm.ObjectTypeCode);
}

hideActionMenuDeactivateButton = function()
{
hideActionMenuItem("_MIchangeStatedeactivate" + crmForm.ObjectTypeCode + "5");
}

hideActionMenuActivateButton = function()
{
hideActionMenuItem("_MIchangeStateactivate" + crmForm.ObjectTypeCode + "6");
}

/* Hides the associated Views buttons. i.e Hides the add existing button. */
/* NB: If called multiple times, the settings of the previous calls are overwritten by the final one! */
/* A menu element on the "More actions" drop-down menu can be hidden
* by adding a string such as 'More Actions::Activate' to the buttonTitles array.
*/
HideAssociatedViewButtons = function(loadAreaId, buttonTitles)
{
var navElement = document.getElementById('nav_' + loadAreaId);
if (navElement != null)
{
navElement.onclick = function LoadAreaOverride()
{
// Call the original CRM method to launch the navigation link and create area iFrame
loadArea(loadAreaId);
HideViewButtons(document.getElementById(loadAreaId + 'Frame'), buttonTitles);
}
}
}

<strong>/* Used internally by the 'HideAssociatedViewButtons' method */</strong>
HideViewButtons = function(Iframe, buttonTitles)
{
if (Iframe != null)
{
Iframe.onreadystatechange = function HideTitledButtons()
{
if (Iframe.readyState == 'complete')
{
var iFrame = frames[window.event.srcElement.id];
var liElements = iFrame.document.getElementsByTagName('li');
for (var j = 0; j < buttonTitles.length; j++)
{
buttonTitleParts = buttonTitles[j].split('::');
if (buttonTitleParts.length > 0)
{
buttonTitle = buttonTitleParts[0];
for (var i = 0; i < liElements.length; i++)
{
liElement = liElements[i];
if (liElement.getAttribute('title') == buttonTitle)
{
if (buttonTitleParts.length == 1)
{
liElement.style.display = 'none';
break;
}
else
{
/* We want to hide a menu item in a drop-down menu.
Find the descendant text element with the specified text.
Then find its parent list item and hide it:
*/
menuText = buttonTitleParts[1];
var spanElements = liElement.getElementsByTagName('span');

for (var k = 0; k < spanElements.length; k++)
{
spanElement = spanElements[k];
if (spanElement.className == 'ms-crm-MenuItem-Text' )
{
textElement = spanElement.firstChild;
if (textElement != null &amp;&amp; textElement.nodeType == 3) /* 3 = Node.TEXT_NODE */
{
if (textElement.data == menuText)
{
liMenuItemElement
= spanElement.parentNode.parentNode.parentNode;
liMenuItemElement.style.display = 'none';
break;
}
}
}
}
}
}
}
}
}
}
}
}
}

<strong>// Load up a CRM entity into an iframe - typically the main view screen</strong>
getCRMFormSource = function(tabSet)
{
if (crmForm.ObjectId != null)
{
var oId = crmForm.ObjectId;
var oType = crmForm.ObjectTypeCode;
var security = crmFormSubmit.crmFormSubmitSecurity.value;

return "/userdefined/areas.aspx?oId=" + oId + "&amp;oType=" + oType + "&amp;security=" + security + "&amp;tabSet=" + tabSet;
}
else
{
return "about:blank";
}
}

setVisibilityOfSectionContainingField = function(crmField, visibility)
{
if (visibility)
{
crmField.parentElement.parentElement.parentElement.style.display = 'block';
}
else
{
crmField.parentElement.parentElement.parentElement.style.display = 'none';
}
}

hideSectionContainingField = function(crmField)
{
setVisibilityOfSectionContainingField(crmField, false);
}

setVisibilityOfSectionWithName = function(tabNumber, sectionName, visibility)
{
var tab = document.getElementById('tab' + tabNumber.toString());
if (tab != null)
{
var tdElements = tab.getElementsByTagName('td');
for (var i = 0; i < tdElements.length; i++)
{
tdElement = tdElements[i];
if (tdElement.className == 'ms-crm-Form-Section ms-crm-Form-SectionBar')
{
textElement = tdElement.firstChild;
if (textElement != null &amp;&amp; textElement.nodeType == 3) /* 3 = Node.TEXT_NODE */
{
if (textElement.data == sectionName)
{
trSectionElement
= tdElement.parentNode.parentNode.parentNode.parentNode.parentNode;

if (visibility)
{
trSectionElement.style.display = 'block';
}
else
{
trSectionElement.style.display = 'none';
}
return true;
}
}
}
}
}
return false;
}

hideSectionWithName = function(tabNumber, sectionName)
{
return setVisibilityOfSectionWithName(tabNumber, sectionName, false);
}

hideSection = function(tabName, sectionName) {
var tabNumber = getTabNumber(tabName);
return setVisibilityOfSectionWithName(tabNumber, sectionName, false);
}

showSection = function(tabName, sectionName) {
var tabNumber = getTabNumber(tabName);
return setVisibilityOfSectionWithName(tabNumber, sectionName, true);
}

showModalWindow = function(url, objectparams, x, y, height, width)
{
return window.showModalDialog(url, objectparams,
(height != null ? "dialogHeight:" + height.toString() + "px;" : "") +
(width != null ? "dialogWidth:" + width.toString() + "px;" : "") +
(y != null ? "dialogTop:" + y.toString() + "px;" : "") +
(x != null ? "dialogLeft:" + x.toString() + "px;" : "") +
"center:Yes;" +
"help:No;" +
"resizable:No;" +
"scroll:No;" +
"status:No;");
}


FetchViewer = function( iframeId )
{
var Instance = this;
var vDynamicForm;
var m_iframeTab;
var m_iframeDoc;

Instance.Entity = "";
Instance.Iframe = null;
Instance.FetchXml = "";
Instance.QueryId = "";
Instance.LayoutXml = "";

Instance.RegisterOnTab = function( tabIndex )
{
Instance.Iframe = document.getElementById( iframeId );

if( !Instance.Iframe )
return alert( "Iframe " + iframeId + " is undefined" );

m_iframeDoc = getIframeDocument();
var loadingGifHTML = "<table height="'100%'" width="'100%'" style="'cursor:wait'">";
loadingGifHTML += "<tr>";
loadingGifHTML += "<td valign="'middle'" align="'center'">";
loadingGifHTML += "<img alt="''" src="'/_imgs/AdvFind/progress.gif'/" />";
loadingGifHTML += "<div/><b>Loading View...</b>";
loadingGifHTML += "</td></tr></table>";
m_iframeDoc.body.innerHTML = loadingGifHTML;

if( parseInt( "0" + tabIndex ) == 0 ) Instance.Refresh();
else Instance.Iframe.attachEvent( "onreadystatechange" , RefreshOnReadyStateChange );
}

function RefreshOnReadyStateChange()
{
if( Instance.Iframe.readyState != 'complete' )
return;

Instance.Refresh();
}

Instance.Refresh = function()
{
if( !Instance.Iframe )
return alert( "Iframe " + iframeId + " is undefined" );

m_iframeDoc = getIframeDocument();

Instance.Iframe.detachEvent( "onreadystatechange" , RefreshOnReadyStateChange );

var create = m_iframeDoc.createElement;
var append1 = m_iframeDoc.appendChild;
vDynamicForm = create("<form name="'vDynamicForm'" method="'post'">");

var append2 = vDynamicForm.appendChild;
append2(create("<input type="'hidden'" name="'FetchXml'">"));
append2(create("<input type="'hidden'" name="'LayoutXml'">"));
append2(create("<input type="'hidden'" name="'EntityName'">"));
append2(create("<input type="'hidden'" name="'DefaultAdvFindViewId'">"));
append2(create("<input type="'hidden'" name="'ViewType'">"));
append1( vDynamicForm );

vDynamicForm.action = prependOrgName("/AdvancedFind/fetchData.aspx");
vDynamicForm.FetchXml.value = Instance.FetchXml;
vDynamicForm.LayoutXml.value = Instance.LayoutXml;
vDynamicForm.EntityName.value = Instance.Entity;
vDynamicForm.DefaultAdvFindViewId.value = Instance.QueryId;
vDynamicForm.ViewType.value = 1039;
vDynamicForm.submit();

Instance.Iframe.attachEvent( "onreadystatechange" , OnViewReady );
}

function OnViewReady()
{
if( Instance.Iframe.readyState != 'complete' ) return;

Instance.Iframe.style.border = 0;
Instance.Iframe.detachEvent( "onreadystatechange" , OnViewReady );
m_iframeDoc = getIframeDocument();
m_iframeDoc.body.scroll = "no";
m_iframeDoc.body.style.padding = "0px";
}

getIframeDocument = function()
{
return Instance.Iframe.contentWindow.document;
}
}

<strong>// Set custom form title</strong>
setFormTitle = function(title)
{
document.all.crmMenuBar.nextSibling.rows[0].cells[1].childNodes[0].innerText = title;
}


setLookupEnabled = function(control, enabled)
{
control.Disabled = !enabled;
}



<strong>/****************** BUTTONS *************************/</strong>
// Get an element in a document by it's class name
// Parameters:
// oElm = starting element
// strTagName = tags to filter on, e.g. TR or * for all
// oClassNames = arraylist of class names to find
// Returns:
// array of elements found
function getElementsByClassName(oElm, strTagName, oClassNames){
var arrElements = (strTagName == "*" &amp;&amp; oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
var arrRegExpClassNames = new Array();
if(typeof oClassNames == "object"){
for(var i=0; i<oClassNames.length; i++){
arrRegExpClassNames.push(new RegExp("(^s)" + oClassNames[i].replace(/-/g, "-") + "(s$)"));
}
}
else{
arrRegExpClassNames.push(new RegExp("(^s)" + oClassNames.replace(/-/g, "-") + "(s$)"));
}
var oElement;
var bMatchesAll;
for(var j=0; j<arrElements.length; j++){
oElement = arrElements[j];
bMatchesAll = true;
for(var k=0; k<arrRegExpClassNames.length; k++){
if(!arrRegExpClassNames[k].test(oElement.className)){
bMatchesAll = false;
break;
}
}
if(bMatchesAll){
arrReturnElements.push(oElement);
}
}
return (arrReturnElements)
}

<strong>// hide the entire grid menu bar of normal CRM grid view</strong>
hideGridViewMenuBar = function(document)
{
if (document != null)
{
var menuBar = document.getElementById('gridMenuBar');

if (menuBar != null)
{
menuBar.style.display = "none";
}
}
}

<strong>// hide the entire grid view bar of normal CRM grid view</strong>
hideGridViewGridBar = function(document)
{
if (document != null)
{
var gridBar = document.getElementById('gridBar');

if (gridBar != null)
{
gridBar.style.display = "none";
}
}
}

<strong>// Hide all the menu items/buttons on a menu bar of normal CRM grid view.
// The menu bar will still be visible when done</strong>
hideAllGridViewMenuBarButtons = function(document)
{
if (document != null)
{
var menuBar = getElementsByClassName(document, "ul", "ms-crm-MenuBar-Left");

if (menuBar != null &amp;&amp; menuBar.length > 0)
{
menuBar[0].style.display = "none";
}
}
}

<strong>// hide the status bar of normal CRM grid view.</strong>
hideGridViewStatusBar = function(document)
{
if (document != null)
{
var menuBar = getElementsByClassName(document, "tr", "ms-crm-List-StatusBar");

if (menuBar != null &amp;&amp; menuBar.length > 0)
{
menuBar[0].style.display = "none";
}
}
}

<strong>// add a button to the grid menu bar</strong>
addGridViewMenuButton = function(document, text, toolTipText, image, javaScriptString)
{
var buttonScript = "<li class="ms-crm-Menu" tabindex="-1" title="'" action="" onclick="'window.execScript(action)'">";
buttonScript += " <span class="ms-crm-Menu-Label">";
buttonScript += " <a class="ms-crm-Menu-Label" tabindex="-1" onclick="'return" href="'javascript:onclick();'" target="_self">";

if (image != null)
{
buttonScript += " <img class="ms-crm-Menu-ButtonFirst" tabindex="-1" alt="'" src="'/_imgs/vieweditor/" />";
}

buttonScript += " <span class="ms-crm-MenuItem-TextRTL" tabindex="0">" + text + "</span>";
buttonScript += " </a>";
buttonScript += " </span>";