Got a requirement which needs to get advance find fetch xml on a ribbon button.
Here is the script to get advance find FetchXml on ribbon button click
function getAdvfindXml()
{
var fetchXml = document. all.namedItem("FetchXml").value;
alert(fetchXml);
}
Use the advance find xml accordingly.
Hope helps :)
Note: Above script completely unsupported.
Guru Prasad's Blog: Microsoft Dynamics CRM
Just to Share My Knowledge on Microsoft Dynamics CRM...
Friday, June 20, 2014
Thursday, July 18, 2013
Microsoft Dynamics CRM 2011 Reporting book
scope of this book only limited to reporting on Microsoft Dynamics CRM as the title of the book says.
If you wants this book, go through this link
I was really happy to review this excellent book. Thanks for the great book.
Keep smiling :)
Displaying view in an IFrame CRM 2011
I was getting number of requests to update my earlier post Displaying view in Iframe which broke after UR12. Sorry for the delay, Now I got sometime to update this article to make it work after UR12.
Scenario: Displaying Primary Contact's 'All Activities' view in an I-Frame which is on Account form.
1. Create an Iframe on the Account form and add to the form. Iframe properties
2. Add the following code into a web resource and attach web resource on to the form.
That's it, it will shows the view on the Iframe.
Hope it helps!!!
Note: System/Custom view can be displayed using view GUID. You can customize FetchXML or Grid Layout accordingly based on your requirement. But Adv.Find view's may work in some cases.
Disclaimer: This article is completely unsupported customization. use at your own risk. it might break with feature roll-ups.
Scenario: Displaying Primary Contact's 'All Activities' view in an I-Frame which is on Account form.
1. Create an Iframe on the Account form and add to the form. Iframe properties
2. Add the following code into a web resource and attach web resource on to the form.
/// <summary>
/// loadIFrame method will be main method which needs to be called to Load View into IFrame
/// Here in this example we will be dsiplaying primary contact's All Activities on the Account form
/// </summary>
function loadIFrame() {
// Get Primary Contact of Account
var primarycontact = Xrm.Page.getAttribute("primarycontactid").getValue();
if (primarycontact != null && primarycontact[0].id != null) {
primarycontactId = primarycontact[0].id;
window.fetchActivtities = new FetchViewer("IFRAME_ShowView"); // IFRAME_ShowView = ID of Iframe
fetchActivtities.FetchXml = getFetchXml(primarycontactId); // Pass primarycontact GUID as parameter
fetchActivtities.LayoutXml = getLayoutXml();
fetchActivtities.Entity = "activitypointer"; //Fetching entity schema name
fetchActivtities.QueryId = "{00000000-0000-0000-00AA-000010001902}"; // view GUID, here its 'All Activities' view GUID
fetchActivtities.RegisterOnTab(1); //IFRAME TAB INDEX where Iframe located
}
}
/// <summary>
/// Gets FetchXML
/// </summary>
/// <param name="primarycontactId">Accounts Primary Contact ID</param>
function getFetchXml(primarycontactId) {
// FetchXML Query of view, you can get it from Adv. Find or Customizations.xml
return '<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">'+
'<entity name="activitypointer">'+
'<attribute name="activitytypecode" />'+
'<attribute name="subject" />'+
'<attribute name="statecode" />'+
'<attribute name="prioritycode" />'+
'<attribute name="modifiedon" />'+
'<attribute name="activityid" />'+
'<attribute name="instancetypecode" />'+
'<order attribute="modifiedon" descending="false" />'+
'<filter type="and">'+
'<condition attribute="regardingobjectid" operator="eq" value="'+primarycontactId+'" />'+
'</filter>' +
'<link-entity name="systemuser" from="systemuserid" to="owninguser" visible="false" link-type="outer" alias="activitypointerowningusersystemusersystemuserid">'+
'<attribute name="internalemailaddress" />'+
'</link-entity>'+
'</entity>' +
'</fetch>';
}
/// <summary>
/// Layout of Gridview
/// </summary>
function getLayoutXml() {
// grid layout, you can get easily from Customization.xml file
return '<grid name="resultset" object="4200" jump="subject" select="1" preview="1" icon="1">'+
'<row name="result" id="activityid" multiobjectidfield="activitytypecode">'+
'<cell name="subject" width="180" />'+
'<cell name="regardingobjectid" width="110" />'+
'<cell name="activitytypecode" width="100" />'+
'<cell name="statecode" width="100" />'+
'<cell name="ownerid" width="120" />'+
'<cell name="prioritycode" width="100" />'+
'<cell name="scheduledstart" width="140" />'+
'<cell name="scheduledend" width="140" />'+
'<cell name="activitypointerowningusersystemusersystemuserid.internalemailaddress" width="100" disableSorting="1" />'+
'<cell name="createdby" width="100" />'+
'<cell name="instancetypecode" width="100" ishidden="1" />'+
'</row>' +
'</grid>';
}
/// <summary>
/// Fetch IFrame content
/// </summary>
function FetchViewer(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;
Instance.Refresh();
}
function RefreshOnReadyStateChange() {
if (Instance.Iframe.readyState != 'complete')
return;
Instance.Refresh();
}
/// <summary>
/// Loads Iframe with the view
/// </summary>
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;
var vDynamicForm = document.createElement("form");
vDynamicForm.setAttribute('method', "post");
vDynamicForm.setAttribute('name', "vDynamicForm");
var FetchXml = document.createElement("input");
FetchXml.setAttribute('type', "hidden");
FetchXml.setAttribute('name', "FetchXml");
vDynamicForm.appendChild(FetchXml);
var LayoutXml = document.createElement("input");
LayoutXml.setAttribute('type', "hidden");
LayoutXml.setAttribute('name', "LayoutXml");
vDynamicForm.appendChild(LayoutXml);
var EntityName = document.createElement("input");
EntityName.setAttribute('type', "hidden");
EntityName.setAttribute('name', "EntityName");
vDynamicForm.appendChild(EntityName);
var DefaultAdvFindViewId = document.createElement("input");
DefaultAdvFindViewId.setAttribute('type', "hidden");
DefaultAdvFindViewId.setAttribute('name', "DefaultAdvFindViewId");
vDynamicForm.appendChild(DefaultAdvFindViewId);
var ViewType = document.createElement("input");
ViewType.setAttribute('type', "hidden");
ViewType.setAttribute('name', "ViewType");
vDynamicForm.appendChild(ViewType);
m_iframeDoc.body.appendChild(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";
}
/// <summary>
/// Gets Iframe content
/// </summary>
function getIframeDocument() {
return Instance.Iframe.contentWindow.document;
}
}
3. Now call loadIFrame() method on the form OnLoad.That's it, it will shows the view on the Iframe.
Hope it helps!!!
Note: System/Custom view can be displayed using view GUID. You can customize FetchXML or Grid Layout accordingly based on your requirement. But Adv.Find view's may work in some cases.
Disclaimer: This article is completely unsupported customization. use at your own risk. it might break with feature roll-ups.
Monday, July 15, 2013
Passing parameters to Navigation Link in CRM 2011
In CRM 2011 we have the option to add custom Navigation link. we can add external URL or webresource to the Navigation pane. I wants to add webresource to the navigation pane.
Added webresource to the navigation pane.
Now I wants to pass record GUID as parameter to the webresource. To pass entity properties to the Navigation link, we have to edit entity XML. Export the solution from CRM and then extract the zipfile.
Now open the Customizations.XML file in edit mode. Find the custom navigation link details in the XML, in my case "Custom Link" navigation link.
Modify the navigation link XML in the following way
PassParams = 0 do not pass parameters [default]
1 pass parameters.
Added webresource to the navigation pane.
Now I wants to pass record GUID as parameter to the webresource. To pass entity properties to the Navigation link, we have to edit entity XML. Export the solution from CRM and then extract the zipfile.
Now open the Customizations.XML file in edit mode. Find the custom navigation link details in the XML, in my case "Custom Link" navigation link.
Modify the navigation link XML in the following way
<NavBarItem Id="navLink{e60ed59a-1121-0e37-65de-3432ed3982e4}" Icon="" Url="$webresource:new_mypage.html" Area="Info" Sequence="9600" PassParams="1" >
<Titles>
<Title LCID="1033" Text="Custom Link" />
</Titles>
</NavBarItem>
</NavBar>
I have added PassParams property to the XML which passes parameters to webresource.PassParams = 0 do not pass parameters [default]
1 pass parameters.
Hope this helps!!!
Tuesday, July 9, 2013
Table alias a_065a97880625e1118ea61cc1def13751 is not unique amongst all top-level table and join aliases
Recently we have modified few views in CRM 2011 online. After modifying the views, we were not able to access the view in CRM. Getting the following error message.
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Xml.XmlException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #2C52B8F9Detail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ErrorCode>-2147220970</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>System.Xml.XmlException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #2C52B8F9</Message>
<Timestamp>2013-07-09T05:42:07.7326294Z</Timestamp>
<InnerFault>
<ErrorCode>-2147217104</ErrorCode>
<ErrorDetails xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>Table alias a_065a97880625e1118ea61cc1def13751 is not unique amongst all top-level table and join aliases</Message>
<Timestamp>2013-07-09T05:42:07.7326294Z</Timestamp>
<InnerFault i:nil="true" />
<TraceText i:nil="true" />
</InnerFault>
<TraceText i:nil="true" />
</OrganizationServiceFault>
Looks like a bug with recent roll up's. Found the following article to fix this issue
http://blog.salesmetrix.com/2013/02/08/corruption-of-views-dynamics-crm-2011-online-dec-2012-service-release/
work around provided in the article worked for me. Hope it helps someone..
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Xml.XmlException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #2C52B8F9Detail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ErrorCode>-2147220970</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>System.Xml.XmlException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #2C52B8F9</Message>
<Timestamp>2013-07-09T05:42:07.7326294Z</Timestamp>
<InnerFault>
<ErrorCode>-2147217104</ErrorCode>
<ErrorDetails xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>Table alias a_065a97880625e1118ea61cc1def13751 is not unique amongst all top-level table and join aliases</Message>
<Timestamp>2013-07-09T05:42:07.7326294Z</Timestamp>
<InnerFault i:nil="true" />
<TraceText i:nil="true" />
</InnerFault>
<TraceText i:nil="true" />
</OrganizationServiceFault>
Looks like a bug with recent roll up's. Found the following article to fix this issue
http://blog.salesmetrix.com/2013/02/08/corruption-of-views-dynamics-crm-2011-online-dec-2012-service-release/
work around provided in the article worked for me. Hope it helps someone..
Thursday, April 4, 2013
Unable to attach to the crashing process. A debugger is already attached
Hi All, recently i was trying to debug java script in CRM 2011. I have added debugger; in the java script and enabled script debugging on IE. Getting the debugger prompt window, but after selecting VS2010 to debug, I was unable to debug java script using VisualStudio2010, getting the following error.
I tried using IE developer tool to debug, its working fine. After some analysis & troubleshooting, I came to know that my IE recently upgraded to IE10 by windows updates. I tried uninstalling IE10 updates, it asked for system reboot. After the reboot, IE degraded to IE9 and i was able to debug javascript using VisualStudio :)
It looks like a bug in IE10. Hope Microsoft will resolve soon!!!
Hope it helps!!!
I tried using IE developer tool to debug, its working fine. After some analysis & troubleshooting, I came to know that my IE recently upgraded to IE10 by windows updates. I tried uninstalling IE10 updates, it asked for system reboot. After the reboot, IE degraded to IE9 and i was able to debug javascript using VisualStudio :)
It looks like a bug in IE10. Hope Microsoft will resolve soon!!!
Hope it helps!!!
Wednesday, April 3, 2013
Unhandled Exception: System.ServiceModel.Security.MessageSecurityException: The security timestamp is invalid because its creation time ('2013-04-03T12:49:05.000Z') is in the future
While connecting to Plugin Registration Tool, i got the following error
This happen because my system time is wrong. it running 10 mins slow. I just updated my system time with correct one, this issue got resolved and i'm able to login to Plugin Registration Tool.
Hope this helps!
Unhandled Exception: System.ServiceModel.Security.MessageSecurityException: The security timestamp is invalid because its creation time ('2013-04-03T12:49:05.000Z') is in the future. Current time is '2013-04-03T12:41:50.807Z' and allowed clock skew is '00:05:00'.
Server stack trace:
at System.ServiceModel.Security.SecurityTimestamp.ValidateFreshness(TimeSpan timeToLive, TimeSpan allowedClockSkew)
at System.ServiceModel.Security.SecurityTimestamp.ValidateRangeAndFreshness(TimeSpan timeToLive, TimeSpan allowedClockSkew)
at System.ServiceModel.Security.ReceiveSecurityHeader.ReadTimestamp(XmlDictionaryReader reader)
at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteFullPass(XmlDictionaryReader reader)
at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessageCore(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustContract.Issue(Message message)
at Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel.Issue(RequestSecurityToken rst, RequestSecurityTokenResponse& rstr)
at Microsoft.Xrm.Sdk.Client.ServiceConfiguration`1.Issue(AuthenticationCredentials authenticationCredentials)
at Microsoft.Xrm.Sdk.Client.ServiceConfiguration`1.AuthenticateInternal(AuthenticationCredentials authenticationCredentials)
at Microsoft.Xrm.Sdk.Client.ServiceConfiguration`1.AuthenticateCrossRealm(ClientCredentials clientCredentials, String appliesTo, Uri crossRealmSts)
at Microsoft.Xrm.Sdk.Client.ServiceProxy`1.AuthenticateCore()
at Microsoft.Xrm.Sdk.Client.ServiceProxy`1.ValidateAuthentication()
at Microsoft.Xrm.Sdk.Client.ServiceContextInitializer`1.Initialize(ServiceProxy`1 proxy)
at Microsoft.Xrm.Sdk.Client.OrganizationServiceContextInitializer..ctor(OrganizationServiceProxy proxy)
at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.RetrieveMultipleCore(QueryBase query)
at Microsoft.Crm.Tools.PluginRegistration.OrganizationServiceExtensions.RetrieveMultipleAllPages(IOrganizationService service, QueryBase query)
at Microsoft.Crm.Tools.PluginRegistration.OrganizationHelper.LoadMessages(CrmOrganization org, ProgressIndicator prog)
at Microsoft.Crm.Tools.PluginRegistration.MainForm.LoadMessages(CrmOrganization org)
at Microsoft.Crm.Tools.PluginRegistration.ConnectionsForm.OpenConnection(CrmOrganization org)
This happen because my system time is wrong. it running 10 mins slow. I just updated my system time with correct one, this issue got resolved and i'm able to login to Plugin Registration Tool.
Hope this helps!
Tuesday, March 26, 2013
0x8004D293 : Cannot update RequiredLevel of attribute CustomerId to SystemRequired
Hi All, recently I came across an issue while importing customization's from an existing environment to a new environment.
Error Details:
Entity Relationships || opportunity_customer_accounts || Failure || 0x8004D293 ||Cannot update RequiredLevel of attribute CustomerId to SystemRequired.
Source environment is upgraded to UP12, but the new UI not enabled on it. Target new environment by default came with UR12 new UI enabled. Both the environments are CRM 2011 online.
During UR12, CustomerId field requirement level has been changed from System Required to Business Required. But CustomerId field on the opportunity is an OOB lookup field and we can't modify the requirement level.
Its a known issue & documented at http://msdn.microsoft.com/en-us/library/gg309589.aspx
Solution:
1. Enabling new UI in the Source environment. During new UI enable process, CustomerId field requirement level auto upgraded to Business required.
Follow the following step to upgrade CRM to new UI.
Settings => Administration => Product Updates
Updated UX forms avaiable only for Leads, Contacts, Accounts, Opportunities and Cases. New UI does not support java script and it has other limitations.
However you have an option to Turn on / off the new sales and service process forms
http://rc.crm.dynamics.com/rc/2011/en-us/online/5.1_OSDP/help/source_sf_turn_on_sales_forms.htm
Hope it helps!!!
Error Details:
Entity Relationships || opportunity_customer_accounts || Failure || 0x8004D293 ||Cannot update RequiredLevel of attribute CustomerId to SystemRequired.
Source environment is upgraded to UP12, but the new UI not enabled on it. Target new environment by default came with UR12 new UI enabled. Both the environments are CRM 2011 online.
During UR12, CustomerId field requirement level has been changed from System Required to Business Required. But CustomerId field on the opportunity is an OOB lookup field and we can't modify the requirement level.
Its a known issue & documented at http://msdn.microsoft.com/en-us/library/gg309589.aspx
Solution:
1. Enabling new UI in the Source environment. During new UI enable process, CustomerId field requirement level auto upgraded to Business required.
Follow the following step to upgrade CRM to new UI.
Settings => Administration => Product Updates
Updated UX forms avaiable only for Leads, Contacts, Accounts, Opportunities and Cases. New UI does not support java script and it has other limitations.
However you have an option to Turn on / off the new sales and service process forms
http://rc.crm.dynamics.com/rc/2011/en-us/online/5.1_OSDP/help/source_sf_turn_on_sales_forms.htm
Hope it helps!!!
Sunday, February 24, 2013
Change Record Status using javascript in CRM 2011
Sometimes we needs to change the CRM record status in java script. Following is the java script code to change the record status(deactivate,activate,qualify etc.). In this example i'm going to deactivate a custom entity record.
Hope it helps!!!
function changeRecordStatus(RECORD_ID,stateCode,statusCode) {
// create the SetState request
var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
request += "<s:Body>";
request += "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
request += "<request i:type=\"b:SetStateRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
request += "<a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
request += "<a:KeyValuePairOfstringanyType>";
request += "<c:key>EntityMoniker</c:key>";
request += "<c:value i:type=\"a:EntityReference\">";
request += "<a:Id>" + RECORD_ID + "</a:Id>";
request += "<a:LogicalName>cmic_systemusersalesterritoryassociation</a:LogicalName>";
request += "<a:Name i:nil=\"true\" />";
request += "</c:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "<a:KeyValuePairOfstringanyType>";
request += "<c:key>State</c:key>";
request += "<c:value i:type=\"a:OptionSetValue\">";
request += "<a:Value>"+stateCode+"</a:Value>";
request += "</c:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "<a:KeyValuePairOfstringanyType>";
request += "<c:key>Status</c:key>";
request += "<c:value i:type=\"a:OptionSetValue\">";
request += "<a:Value>"+statusCode+"</a:Value>";
request += "</c:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "</a:Parameters>";
request += "<a:RequestId i:nil=\"true\" />";
request += "<a:RequestName>SetState</a:RequestName>";
request += "</request>";
request += "</Execute>";
request += "</s:Body>";
request += "</s:Envelope>";
//send set state request
$.ajax({
type: "POST",
contentType: "text/xml; charset=utf-8",
datatype: "xml",
url: Xrm.Page.context.getServerUrl() + "/XRMServices/2011/Organization.svc/web",
data: request,
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/xml, text/xml, */*");
XMLHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
},
success: function (data, textStatus, XmlHttpRequest) {
Xrm.Page.ui.close();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
//Deactivating custom entity record
changeRecordStatus(Xrm.Page.data.entity.getId(),1,2);
Hope it helps!!!
Saturday, July 21, 2012
Conditionally Hiding OOB Ribbon Button in CRM 2011
Hi All, To hide the OOB Ribbon button permanently you can use my earlier post. But sometimes we needs to hide OOB Ribbon button conditionally in CRM 2011. Here I am going to hide OOB "Assign" button conditionally based on Optionset Value.
On the Account form, if the "Category" optionset value is "Preferred Customer" then display the "Assign" button otherwise hide the "Assign" button.
1. Export the solution and open Customization.XML file in edit mode. Find the <RibbonDiffXml> at the Account form level.
2. Now open Accountribbon.xml file from the SDK and find the Assign button details at form Level
Now copy the Assign button element from here and add this to custom Actions in the <RibbonDiffXML> which we are customizing.
we also needs to copy the CommandDefinition of the OOB Assign button to provide OOB assign functionality. otherwise OOB Asign button functionality might not work.
3. Now edit the Account <RibbonDiffXML> in the following way
4. Now import the customization file.
Hope it helps!!!
<RibbonDiffXml>
<CustomActions>
<!-- Location will be ID of the Button-->
<CustomAction Location="Mscrm.Form.account.Assign" Id="Sample.Form.account.HideAssign">
<CommandUIDefinition>
<!-- copy the OOB Asign button CommandUI Definition-->
<Button Id="Mscrm.Form.account.Assign" ToolTipTitle="$Resources:Ribbon.HomepageGrid.MainTab.Actions.Assign" ToolTipDescription="$Resources(EntityPluralDisplayName):Ribbon.Tooltip.Assign" Command="Mscrm.AssignPrimaryRecord" Sequence="33" LabelText="$Resources:Ribbon.HomepageGrid.MainTab.Actions.Assign" Alt="$Resources:Ribbon.HomepageGrid.MainTab.Actions.Assign" Image16by16="/_imgs/ribbon/Assign_16.png" Image32by32="/_imgs/ribbon/Assign_32.png" TemplateAlias="o1" />
</CommandUIDefinition>
</CustomAction>
</CustomActions>
<Templates>
<RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
</Templates>
<CommandDefinitions>
<!-- copy the OOB Asign button Command Definition-->
<CommandDefinition Id="Mscrm.AssignPrimaryRecord">
<EnableRules>
<EnableRule Id="Mscrm.FormStateNotNew" />
<EnableRule Id="Mscrm.AssignPrimaryPermission" />
<EnableRule Id="Mscrm.NotOffline" />
</EnableRules>
<DisplayRules>
<DisplayRule Id="Mscrm.AssignPrimaryPermission" />
<DisplayRule Id="Mscrm.NotClosedActivity" />
<!-- Add new display Rule for conditionally hiding-->
<DisplayRule Id="Sample.Form.account.HideAssign.DisplayRule"/>
</DisplayRules>
<Actions>
<JavaScriptFunction FunctionName="assignObject" Library="/_static/_forms/form.js">
<CrmParameter Value="PrimaryEntityTypeCode" />
</JavaScriptFunction>
</Actions>
</CommandDefinition>
</CommandDefinitions>
<RuleDefinitions>
<TabDisplayRules />
<DisplayRules>
<!--Define the conditional Hiding Display Rule-->
<DisplayRule Id="Sample.Form.account.HideAssign.DisplayRule">
<ValueRule Field="accountcategorycode" Value="1"/>
<!--Field will be CRM field schema Name, Value will be optionset Value-->
</DisplayRule>
</DisplayRules>
<EnableRules />
</RuleDefinitions>
<LocLabels />
</RibbonDiffXml>
4. Now import the customization file.
Hope it helps!!!
Friday, July 13, 2012
Plugin on Retrieve Multiple Message in CRM 2011
Hi All, Now will see how to implement plugin on Retrieve Multiple Message. While Retrieving Data from an entity, I needs to check the query passed by the user and based on the filters, adding conditional filters and returning filtered information to the user.
public void Execute(IServiceProvider serviceProvider)
{
// Extract the tracing service.
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
if (tracingService == null)
throw new InvalidPluginExecutionException("Failed to retrieve the tracing service.");
try
{
tracingService.Trace("Posting the execution context.");
if (tracingService == null)
throw new InvalidPluginExecutionException("Failed to retrieve the service bus service.");
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
string city = string.Empty;
if (context.MessageName == "RetrieveMultiple")
{
if (context.Depth <= 1)
{
IOrganizationServiceFactory factory =
(IOrganizationServiceFactory)
serviceProvider.GetService(typeof (IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(null);
if (context.InputParameters.Contains("Query"))
{
// Get the query
// Get the query
QueryExpression query = (QueryExpression)context.InputParameters["Query"];
// get the conditions passed by the user
ConditionExpression[] filters = query.Criteria.Conditions.ToArray();
foreach (var filter in filters)
{
if (filter.AttributeName == "new_city")
city = filter.Values[0].ToString();
//check if the query has city filter
if (!string.IsNullOrEmpty(city) && city == "MyCity")
{
// write your logic, adding additional filters conditionally or performing other tasks etc..
}
}
}
}
}
}
catch (FaultException<OrganizationServiceFault> e)
{
tracingService.Trace("Exception occured in the Plugin:" + e.ToString());
// Handle the exception.
throw;
}
catch (Exception ex)
{
tracingService.Trace("Exception: {0}", ex.ToString());
throw;
}
}
Hope it helps!!!
Tuesday, June 19, 2012
Javascript debugger not working on Ribbon Button click
Recently I tried debugging java script code which is called on ribbon button click. But i am not able to debugger that code. I am able to debug javascript on form level. But not on Ribbon button level. Looks strange!!
I tried solution provided in this forum post , but its partially resolved debugging issue.
After digging deep, I tried upgrading IE version from IE8 - IE9. Finally debugging issue on ribbon button click has been resolved.
Hope it will be helpful!!!
I tried solution provided in this forum post , but its partially resolved debugging issue.
After digging deep, I tried upgrading IE version from IE8 - IE9. Finally debugging issue on ribbon button click has been resolved.
Hope it will be helpful!!!
Friday, April 27, 2012
Tab order Issue with CRM 2011 Managed Solution
Recently I was deploying managed solution into a new environment. Deployment done successfully without errors. But I notice an issue with managed solution deployment in CRM2011.
With Managed solution import, All the OOB entities having wrong tab order. Then i came to know Managed solutions merge changes to the existing customizations file instead of replacing.
http://msdn.microsoft.com/en-us/library/gg309329.aspx
Microsoft has to resolve this issue.
Workaround: Manually editing the customizations.xml of managed solution & reordering the tab sequence. Then importing managed solution to the host system. Now it will get the correct tab order.
It's not a good idea, but hope it helps!!!
With Managed solution import, All the OOB entities having wrong tab order. Then i came to know Managed solutions merge changes to the existing customizations file instead of replacing.
http://msdn.microsoft.com/en-us/library/gg309329.aspx
Microsoft has to resolve this issue.
Workaround: Manually editing the customizations.xml of managed solution & reordering the tab sequence. Then importing managed solution to the host system. Now it will get the correct tab order.
It's not a good idea, but hope it helps!!!
Saturday, March 17, 2012
Completed Customization's Certification in CRM 2011..
Today I completed Customization's Certification in CRM 2011 and became Microsoft Certified Technology Specialist in Microsoft Dynamics™ CRM 2011...
Just wanted to share with all my buddies.. keep exploring things in CRM 2011..
Keep smiling.. :)
Just wanted to share with all my buddies.. keep exploring things in CRM 2011..
Keep smiling.. :)
Thursday, December 22, 2011
Display Custom Advance Find view in Iframe in CRM 2011
Hi All, To bind FetchXml to Iframe Adi Katz,MVP has provided nice article to do in CRM4.0. Thanks Adi Katz for the great article. I just started converting it to work with CRM 2011. Here is the working copy of mine, to bind FetchXml to Iframe.
function loadIFrame() {
window.fetchActivtities = new FetchViewer("IFRAME_TEST");
fetchActivtities.FetchXml = getFetchXml();
fetchActivtities.LayoutXml = getLayoutXml();
fetchActivtities.Entity = "activitypointer";
fetchActivtities.QueryId = "{00000000-0000-0000-00aa-000010001899}"; // view GUID
fetchActivtities.RegisterOnTab(2); //IFRAME TAB INDEX
}
function getFetchXml() {
// FetchXML Query
return ' <fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">' +
'<entity name="activitypointer">' +
' <attribute name="subject" />' +
' <attribute name="scheduledstart" />' +
' <attribute name="regardingobjectid" />' +
' <attribute name="prioritycode" />' +
' <attribute name="scheduledend" />' +
' <attribute name="activitytypecode" />' +
' <attribute name="instancetypecode" />' +
' <order attribute="scheduledend" descending="false" />' +
'<filter type="and">'+
'<condition attribute="regardingobjectid" operator="in">'+
'<value uitype="account">{7CC58DF6-3114-E111-8E22-1CC1DEEAE7D7}</value>'+
' </condition>'+
'</filter>'+
' <attribute name="activityid" />' +
' </entity>' +
' </fetch>';
}
function getLayoutXml() {
// grid layout, you can get easily from Customization.xml file
return '<grid name="resultset" object="4200" jump="subject" select="1" icon="1" preview="1">' +
' <row name="result" id="activityid" multiobjectidfield="activitytypecode">' +
' <cell name="instancetypecode" width="100" ishidden="1" />' +
' </row>' +
' </grid>';
}
function FetchViewer(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;
Instance.Refresh();
}
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";
}
function getIframeDocument() {
return Instance.Iframe.contentWindow.document;
}
}
function loadIFrame() {
window.fetchActivtities = new FetchViewer("IFRAME_TEST");
fetchActivtities.FetchXml = getFetchXml();
fetchActivtities.LayoutXml = getLayoutXml();
fetchActivtities.Entity = "activitypointer";
fetchActivtities.QueryId = "{00000000-0000-0000-00aa-000010001899}"; // view GUID
fetchActivtities.RegisterOnTab(2); //IFRAME TAB INDEX
}
function getFetchXml() {
// FetchXML Query
return ' <fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">' +
'<entity name="activitypointer">' +
' <attribute name="subject" />' +
' <attribute name="scheduledstart" />' +
' <attribute name="regardingobjectid" />' +
' <attribute name="prioritycode" />' +
' <attribute name="scheduledend" />' +
' <attribute name="activitytypecode" />' +
' <attribute name="instancetypecode" />' +
' <order attribute="scheduledend" descending="false" />' +
'<filter type="and">'+
'<condition attribute="regardingobjectid" operator="in">'+
'<value uitype="account">{7CC58DF6-3114-E111-8E22-1CC1DEEAE7D7}</value>'+
' </condition>'+
'</filter>'+
' <attribute name="activityid" />' +
' </entity>' +
' </fetch>';
}
function getLayoutXml() {
// grid layout, you can get easily from Customization.xml file
return '<grid name="resultset" object="4200" jump="subject" select="1" icon="1" preview="1">' +
' <row name="result" id="activityid" multiobjectidfield="activitytypecode">' +
' <cell name="instancetypecode" width="100" ishidden="1" />' +
' </row>' +
' </grid>';
}
function FetchViewer(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;
Instance.Refresh();
}
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";
}
function getIframeDocument() {
return Instance.Iframe.contentWindow.document;
}
}
Note: This script is completely unsupported. it may break in the future with roll-up updates.
Monday, December 19, 2011
Adding New Group to Subgrid in CRM 2011
Hi All, Now i am going to add new custom group to subgrid. Here I am going to add a custom group to contact entity subgrid.
1. Export the solution and open the customization.xml file using visual studio to edit.
2. Now edit the customization file, change the <RibbonDiffXml> of contact entity like this
<RibbonDiffXml>
<CustomActions>
<CustomAction Id="sample.SubGrid.contact.MainTab.CustomGroup.CustomAction" Location="Mscrm.SubGrid.contact.MainTab.Groups._children" Sequence="110">
<CommandUIDefinition>
<Group Id="sample.SubGrid.contact.MainTab.CustomGroup.SampleGroup" Command="sample.SubGrid.contact.MainTab.CustomGroup.Command" Title="$LocLabels:CustomGroup.Title" Sequence="32" Template="Mscrm.Templates.Flexible2" Image32by32Popup="$webresource:new_samplebutton32x32.png">
<Controls Id="sample.SubGrid.contact.MainTab.CustomGroup.Controls">
<Button Id="sample.SubGrid.contact.MainTab.CustomGroup.CustomButton.A" Command="sample.SubGrid.contact.MainTab.CustomGroup.CustomButton.A.Command" Sequence="21" LabelText="$LocLabels:CustomButton.A.LableText" ToolTipTitle="$LocLabels:CustomButton.A.LableText" ToolTipDescription="$LocLabels:CustomButton.A.ToolTipDescription" Image16by16="$webresource:new_samplebutton16x16.png" Image32by32="$webresource:new_samplebutton32x32.png" TemplateAlias="o1" />
</Controls>
</Group>
</CommandUIDefinition>
</CustomAction>
<CustomAction Id="sample.SubGrid.contact.MainTab.CustomGroup.Maxsize.CustomAction" Location="Mscrm.SubGrid.contact.MainTab.Scaling._children" Sequence="120">
<CommandUIDefinition>
<MaxSize Id="sample.SubGrid.contact.MainTab.CustomGroup.Maxsize" GroupId="sample.SubGrid.contact.MainTab.CustomGroup.SampleGroup" Sequence="21" Size="LargeMedium" />
</CommandUIDefinition>
</CustomAction>
</CustomActions>
<Templates>
<RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
</Templates>
<CommandDefinitions>
<CommandDefinition Id="sample.SubGrid.contact.MainTab.CustomGroup.Command">
<EnableRules>
<EnableRule Id="sample.SubGrid.contact.CustomGroup.EnableRule" />
</EnableRules>
<DisplayRules>
</DisplayRules>
<Actions />
</CommandDefinition>
<CommandDefinition Id="sample.SubGrid.contact.MainTab.CustomGroup.CustomButton.A.Command">
<EnableRules>
<EnableRule Id="sample.SubGrid.contact.SingleRecordSelection.EnableRule" />
</EnableRules>
<DisplayRules />
<Actions>
<!-- This new_sample.js webresource must be added before customizing -->
<JavaScriptFunction FunctionName="TestFunction" Library="$webresource:new_sample.js">
<CrmParameter Value="SelectedControlSelectedItemIds" />
</JavaScriptFunction>
</Actions>
</CommandDefinition>
</CommandDefinitions>
<RuleDefinitions>
<TabDisplayRules />
<DisplayRules />
<EnableRules>
<EnableRule Id="sample.SubGrid.contact.CustomGroup.EnableRule">
<EntityRule AppliesTo="PrimaryEntity" EntityName="account" />
</EnableRule>
<EnableRule Id="sample.SubGrid.contact.SingleRecordSelection.EnableRule">
<SelectionCountRule AppliesTo="SelectedEntity" Minimum="1" Maximum="1" />
</EnableRule>
</EnableRules>
</RuleDefinitions>
<LocLabels>
<LocLabel Id="CustomButton.A.LableText">
<Titles>
<Title languagecode="1033" description="Sample Button" />
</Titles>
</LocLabel>
<LocLabel Id="CustomButton.A.ToolTipDescription">
<Titles>
<Title languagecode="1033" description="Sample Button Description" />
</Titles>
</LocLabel>
<LocLabel Id="CustomGroup.Title">
<Titles>
<Title languagecode="1033" description="Custom Group" />
</Titles>
</LocLabel>
</LocLabels>
</RibbonDiffXml>
3. java script function on custom button click
function TestFunction(selectedRecordID) {
alert(selectedRecordID[0]);
// your logic
}
4. Save the customization.xml file and export back to CRM.
Now you will find the custom group and button on the contact subgrid. Here custom button will be enable when you are accessing contact entity subgrid from only Account entity. For rest of all the entities this custom button will be in disable mode. Only single record selection from subgrid will be allowed.
keep coding!!!!!
1. Export the solution and open the customization.xml file using visual studio to edit.
2. Now edit the customization file, change the <RibbonDiffXml> of contact entity like this
<RibbonDiffXml>
<CustomActions>
<CustomAction Id="sample.SubGrid.contact.MainTab.CustomGroup.CustomAction" Location="Mscrm.SubGrid.contact.MainTab.Groups._children" Sequence="110">
<CommandUIDefinition>
<Group Id="sample.SubGrid.contact.MainTab.CustomGroup.SampleGroup" Command="sample.SubGrid.contact.MainTab.CustomGroup.Command" Title="$LocLabels:CustomGroup.Title" Sequence="32" Template="Mscrm.Templates.Flexible2" Image32by32Popup="$webresource:new_samplebutton32x32.png">
<Controls Id="sample.SubGrid.contact.MainTab.CustomGroup.Controls">
<Button Id="sample.SubGrid.contact.MainTab.CustomGroup.CustomButton.A" Command="sample.SubGrid.contact.MainTab.CustomGroup.CustomButton.A.Command" Sequence="21" LabelText="$LocLabels:CustomButton.A.LableText" ToolTipTitle="$LocLabels:CustomButton.A.LableText" ToolTipDescription="$LocLabels:CustomButton.A.ToolTipDescription" Image16by16="$webresource:new_samplebutton16x16.png" Image32by32="$webresource:new_samplebutton32x32.png" TemplateAlias="o1" />
</Controls>
</Group>
</CommandUIDefinition>
</CustomAction>
<CustomAction Id="sample.SubGrid.contact.MainTab.CustomGroup.Maxsize.CustomAction" Location="Mscrm.SubGrid.contact.MainTab.Scaling._children" Sequence="120">
<CommandUIDefinition>
<MaxSize Id="sample.SubGrid.contact.MainTab.CustomGroup.Maxsize" GroupId="sample.SubGrid.contact.MainTab.CustomGroup.SampleGroup" Sequence="21" Size="LargeMedium" />
</CommandUIDefinition>
</CustomAction>
</CustomActions>
<Templates>
<RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
</Templates>
<CommandDefinitions>
<CommandDefinition Id="sample.SubGrid.contact.MainTab.CustomGroup.Command">
<EnableRules>
<EnableRule Id="sample.SubGrid.contact.CustomGroup.EnableRule" />
</EnableRules>
<DisplayRules>
</DisplayRules>
<Actions />
</CommandDefinition>
<CommandDefinition Id="sample.SubGrid.contact.MainTab.CustomGroup.CustomButton.A.Command">
<EnableRules>
<EnableRule Id="sample.SubGrid.contact.SingleRecordSelection.EnableRule" />
</EnableRules>
<DisplayRules />
<Actions>
<!-- This new_sample.js webresource must be added before customizing -->
<JavaScriptFunction FunctionName="TestFunction" Library="$webresource:new_sample.js">
<CrmParameter Value="SelectedControlSelectedItemIds" />
</JavaScriptFunction>
</Actions>
</CommandDefinition>
</CommandDefinitions>
<RuleDefinitions>
<TabDisplayRules />
<DisplayRules />
<EnableRules>
<EnableRule Id="sample.SubGrid.contact.CustomGroup.EnableRule">
<EntityRule AppliesTo="PrimaryEntity" EntityName="account" />
</EnableRule>
<EnableRule Id="sample.SubGrid.contact.SingleRecordSelection.EnableRule">
<SelectionCountRule AppliesTo="SelectedEntity" Minimum="1" Maximum="1" />
</EnableRule>
</EnableRules>
</RuleDefinitions>
<LocLabels>
<LocLabel Id="CustomButton.A.LableText">
<Titles>
<Title languagecode="1033" description="Sample Button" />
</Titles>
</LocLabel>
<LocLabel Id="CustomButton.A.ToolTipDescription">
<Titles>
<Title languagecode="1033" description="Sample Button Description" />
</Titles>
</LocLabel>
<LocLabel Id="CustomGroup.Title">
<Titles>
<Title languagecode="1033" description="Custom Group" />
</Titles>
</LocLabel>
</LocLabels>
</RibbonDiffXml>
3. java script function on custom button click
function TestFunction(selectedRecordID) {
alert(selectedRecordID[0]);
// your logic
}
4. Save the customization.xml file and export back to CRM.
Now you will find the custom group and button on the contact subgrid. Here custom button will be enable when you are accessing contact entity subgrid from only Account entity. For rest of all the entities this custom button will be in disable mode. Only single record selection from subgrid will be allowed.
keep coding!!!!!
Tuesday, December 13, 2011
Retrieve OptionSet Text in CRM 2011 using C#
Hi All, In CRM 2011 we have two types of Option Sets. one will be normal Option set Filed and the other one will be Global Option Set. Lets see how to retrieve Option Set Text for both types.
Retrieve Normal(Local) Option Set Text
// Get Normal option set Text
string optionsetText = entity.FormattedValues["new_optionset"];
or
string optionsetText = entity.GetFormattedAttributeValue("new_optionset");
Retrieve Global Option Set Text
int OptionsetValue = ((Microsoft.Xrm.Sdk.OptionSetValue)entity["new_localoptionset"]).Value;
string GlobaloptionsetText= GetOptionsetText(entity, service, "new_globaloptionset", OptionsetValue );
// Retrieves Global Option set Selected Text
// Parameters: 1. Entity Name 2. Service 3. Global Option Set Name 4. optionset selected value
public string GetOptionsetText(Entity entity, IOrganizationService service,string optionsetName,int optionsetValue)
{
string optionsetSelectedText = string.Empty;
try
{
RetrieveOptionSetRequest retrieveOptionSetRequest =
new RetrieveOptionSetRequest
{
Name = optionsetName
};
// Execute the request.
RetrieveOptionSetResponse retrieveOptionSetResponse =
(RetrieveOptionSetResponse)service.Execute(retrieveOptionSetRequest);
// Access the retrieved OptionSetMetadata.
OptionSetMetadata retrievedOptionSetMetadata = (OptionSetMetadata)retrieveOptionSetResponse.OptionSetMetadata;
// Get the current options list for the retrieved attribute.
OptionMetadata[] optionList = retrievedOptionSetMetadata.Options.ToArray();
foreach (OptionMetadata optionMetadata in optionList)
{
if (optionMetadata.Value == optionsetValue)
{
optionsetSelectedText = optionMetadata.Label.UserLocalizedLabel.Label.ToString();
break;
}
}
}
catch (Exception)
{
throw;
}
return optionsetSelectedText;
}
===========================================
// Gets Local/Normal optionset Lable using Metadata Service
public static string GetoptionsetText(string entityName, string attributeName, int optionSetValue, IOrganizationService service)
{
string AttributeName = attributeName;
string EntityLogicalName = entityName;
RetrieveEntityRequest retrieveDetails = new RetrieveEntityRequest
{
EntityFilters = EntityFilters.All,
LogicalName = EntityLogicalName
};
RetrieveEntityResponse retrieveEntityResponseObj = (RetrieveEntityResponse)service.Execute(retrieveDetails);
Microsoft.Xrm.Sdk.Metadata.EntityMetadata metadata = retrieveEntityResponseObj.EntityMetadata;
Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata picklistMetadata = metadata.Attributes.FirstOrDefault(attribute => String.Equals
(attribute.LogicalName, attributeName, StringComparison.OrdinalIgnoreCase)) as Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata;
Microsoft.Xrm.Sdk.Metadata.OptionSetMetadata options = picklistMetadata.OptionSet;
IList<OptionMetadata> OptionsList = (from o in options.Options
where o.Value.Value == optionSetValue
select o).ToList();
string optionsetLabel = (OptionsList.First()).Label.UserLocalizedLabel.Label;
return optionsetLabel;
}
Retrieve Normal(Local) Option Set Text
// Get Normal option set Text
string optionsetText = entity.FormattedValues["new_optionset"];
or
string optionsetText = entity.GetFormattedAttributeValue("new_optionset");
Retrieve Global Option Set Text
int OptionsetValue = ((Microsoft.Xrm.Sdk.OptionSetValue)entity["new_localoptionset"]).Value;
string GlobaloptionsetText= GetOptionsetText(entity, service, "new_globaloptionset", OptionsetValue );
// Retrieves Global Option set Selected Text
// Parameters: 1. Entity Name 2. Service 3. Global Option Set Name 4. optionset selected value
public string GetOptionsetText(Entity entity, IOrganizationService service,string optionsetName,int optionsetValue)
{
string optionsetSelectedText = string.Empty;
try
{
RetrieveOptionSetRequest retrieveOptionSetRequest =
new RetrieveOptionSetRequest
{
Name = optionsetName
};
// Execute the request.
RetrieveOptionSetResponse retrieveOptionSetResponse =
(RetrieveOptionSetResponse)service.Execute(retrieveOptionSetRequest);
// Access the retrieved OptionSetMetadata.
OptionSetMetadata retrievedOptionSetMetadata = (OptionSetMetadata)retrieveOptionSetResponse.OptionSetMetadata;
// Get the current options list for the retrieved attribute.
OptionMetadata[] optionList = retrievedOptionSetMetadata.Options.ToArray();
foreach (OptionMetadata optionMetadata in optionList)
{
if (optionMetadata.Value == optionsetValue)
{
optionsetSelectedText = optionMetadata.Label.UserLocalizedLabel.Label.ToString();
break;
}
}
}
catch (Exception)
{
throw;
}
return optionsetSelectedText;
}
===========================================
// Gets Local/Normal optionset Lable using Metadata Service
public static string GetoptionsetText(string entityName, string attributeName, int optionSetValue, IOrganizationService service)
{
string AttributeName = attributeName;
string EntityLogicalName = entityName;
RetrieveEntityRequest retrieveDetails = new RetrieveEntityRequest
{
EntityFilters = EntityFilters.All,
LogicalName = EntityLogicalName
};
RetrieveEntityResponse retrieveEntityResponseObj = (RetrieveEntityResponse)service.Execute(retrieveDetails);
Microsoft.Xrm.Sdk.Metadata.EntityMetadata metadata = retrieveEntityResponseObj.EntityMetadata;
Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata picklistMetadata = metadata.Attributes.FirstOrDefault(attribute => String.Equals
(attribute.LogicalName, attributeName, StringComparison.OrdinalIgnoreCase)) as Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata;
Microsoft.Xrm.Sdk.Metadata.OptionSetMetadata options = picklistMetadata.OptionSet;
IList<OptionMetadata> OptionsList = (from o in options.Options
where o.Value.Value == optionSetValue
select o).ToList();
string optionsetLabel = (OptionsList.First()).Label.UserLocalizedLabel.Label;
return optionsetLabel;
}
happy coding :)
Wednesday, November 30, 2011
Phone Number Validation using java script in CRM 2011
Hi All, Here is the logic to format Phone Number field into '(xxx) xxx-xxxx' format. It only allows user to enter only numeric characters, up to 10 char's.
function Bindevents() {
// Binding the events to crm field, which needs to be validated
crmForm.all.telephone1.onkeypress = isvalidPhone;
crmForm.all.telephone1.onblur = function () { formatPhoneNumber("telephone1"); };
}
// Allows to enter only Numbers & upto 10 char's
function isvalidPhone() {
var charCode = event.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57))
return false;
var phnum = event.srcElement.value.replace(/[^0-9]/g, "");
if (phnum.length >= 10)
return false;
return true;
}
// Formats Phone Number to '(xxx) xxx-xxxx' format
function formatPhoneNumber(phnum) {
var phone = Xrm.Page.getAttribute(phnum).getValue();
var tmp = phone.replace(/[^0-9]/g, "");
phoneRegex = /^\d{10}$/;
if (!tmp.match(phoneRegex)) {
event.returnValue = false;
Xrm.Page.data.entity.attributes.get(phnum).controls.get(0).setFocus();
}
else {
var formtedphn = "(" + tmp.substr(0, 3) + ") " + tmp.substr(3, 3) + "-" + tmp.substr(6, 4);
Xrm.Page.getAttribute(phnum).setValue(formtedphn);
}
}
Hope it helps!!!!
function Bindevents() {
// Binding the events to crm field, which needs to be validated
crmForm.all.telephone1.onkeypress = isvalidPhone;
crmForm.all.telephone1.onblur = function () { formatPhoneNumber("telephone1"); };
}
// Allows to enter only Numbers & upto 10 char's
function isvalidPhone() {
var charCode = event.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57))
return false;
var phnum = event.srcElement.value.replace(/[^0-9]/g, "");
if (phnum.length >= 10)
return false;
return true;
}
// Formats Phone Number to '(xxx) xxx-xxxx' format
function formatPhoneNumber(phnum) {
var phone = Xrm.Page.getAttribute(phnum).getValue();
var tmp = phone.replace(/[^0-9]/g, "");
phoneRegex = /^\d{10}$/;
if (!tmp.match(phoneRegex)) {
event.returnValue = false;
Xrm.Page.data.entity.attributes.get(phnum).controls.get(0).setFocus();
}
else {
var formtedphn = "(" + tmp.substr(0, 3) + ") " + tmp.substr(3, 3) + "-" + tmp.substr(6, 4);
Xrm.Page.getAttribute(phnum).setValue(formtedphn);
}
}
Hope it helps!!!!
Monday, November 28, 2011
How to Debug CRM 2011 online plugin
Hi All, its difficult to debug plugins registered in sandbox on CRM 2011 online version. Follow the Steps to debug plugins registered for online version
- Install Plugin Pro-filer in the plugin registration Tool.(if you don’t find this option, download latest SDK)
- Now Register the plug-in and step on the Microsoft Dynamics CRM server. Keep a copy of the debug compiled plug-in assembly on the computer where you are running the tool(@SDK\sdk\tools\pluginregistration\bin\Debug)
- Select a plug-in step and click Profile to enable profiling.
- Perform the operation in Microsoft Dynamics CRM that causes the plug-in to run. Ex: Here updation of Account which trigger the plugin.
- Now the plug-in throws an exception and the Business Process Error dialog is displayed, click Download Log File and save this file.
- In the Plug-in Registration tool, click Debug.
- Debug Dialog will open
- Now open the plugin solution in Visual Studio and then place the break point to debug, attach the debugger to PluginRegistration.exe process.
- Click Start Plug-in Execution in the Debug Existing Plug-in dialog box
- Now the debugger will start debugging from the break point in the VS. Now you can debug the plugin in the normal way like on-premise.
- For more info on plugin debugging click . I hope it helps!!!!!!
Wednesday, November 23, 2011
Adding New Group to CRM Form in CRM 2011
Hi Friends, Now I will walk through how to add a new group to an OOB entity.
<RibbonDiffXml>
<CustomActions>
<CustomAction Id="Sample.account.form.CustomGroup.CustomAction" Location="Mscrm.Form.account.MainTab.Groups._children" Sequence="110">
<CommandUIDefinition>
<Group Id="sample.account.form.CustomGroup.Group" Command="sample.account.form.CustomGroup.Command" Title="$LocLabels:sample.account.CustomGroup.Title" Sequence="38" Template="Mscrm.Templates.Flexible2" Image32by32Popup="$webresource:new_samplebutton32x32.png">
<Controls Id="sample.account.form.CustomGroup.Controls">
<Button Id="sample.account.form.CustomGroup.Button.A" Command="sample.account.CustomGroup.Button.A.Command" Sequence="20" LabelText="$LocLabels:sample.account.CustomGroup.Button.A.LabelText" ToolTipTitle="$LocLabels:sample.account.CustomGroup.Button.A.LabelText" ToolTipDescription="$LocLabels:sample.account.CustomGroup.Button.A.Description" TemplateAlias="o1" Image16by16="$webresource:new_samplebutton16x16.png" Image32by32="$webresource:new_samplebutton32x32.png" />
</Controls>
</Group>
</CommandUIDefinition>
</CustomAction>
<CustomAction Id="sample.account.form.CustomGroup.MaxSize.CustomAction" Location="Mscrm.Form.account.MainTab.Scaling._children" Sequence="120">
<CommandUIDefinition>
<MaxSize Id="sample.account.form.CustomGroup.MaxSize" GroupId="sample.account.form.CustomGroup.Group" Sequence="21" Size="LargeLarge" />
</CommandUIDefinition>
</CustomAction>
</CustomActions>
<Templates>
<RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
</Templates>
<CommandDefinitions>
<CommandDefinition Id="sample.account.CustomGroup.Button.A.Command">
<EnableRules/>
<DisplayRules>
<DisplayRule Id="sample.account.form.DisplayRule.NotonCreate" />
</DisplayRules>
<Actions>
<JavaScriptFunction Library="$webresource:new_sample.js" FunctionName="TestFunction"></JavaScriptFunction>
</Actions>
</CommandDefinition>
<CommandDefinition Id="sample.account.form.CustomGroup.Command">
<EnableRules/>
<DisplayRules>
<DisplayRule Id="sample.account.form.DisplayRule.NotonCreate" />
</DisplayRules>
<Actions />
</CommandDefinition>
</CommandDefinitions>
<RuleDefinitions>
<TabDisplayRules />
<DisplayRules>
<DisplayRule Id="sample.account.form.DisplayRule.NotonCreate">
<FormStateRule State="Create" InvertResult="true" />
</DisplayRule>
</DisplayRules>
<EnableRules />
</RuleDefinitions>
<LocLabels>
<LocLabel Id="sample.account.CustomGroup.Button.A.Description">
<Titles>
<Title languagecode="1033" description="Custom Button Description" />
</Titles>
</LocLabel>
<LocLabel Id="sample.account.CustomGroup.Button.A.LabelText">
<Titles>
<Title languagecode="1033" description="Custom Button" />
</Titles>
</LocLabel>
<LocLabel Id="sample.account.CustomGroup.Title">
<Titles>
<Title languagecode="1033" description="Custom Group" />
</Titles>
</LocLabel>
</LocLabels>
</RibbonDiffXml>
5. Now zip the solution and import back to CRM. you will find the custom Group on the Account Form.
Hope it helps!!!
Before Adding Custom Group to Account Entity
After Adding Custom Group to Account Enity
Follow the following steps
1. Export the solution to which we wants to customize
2. Open the Customizations.xml file in edit mode
3. Find "RibbonDiffXml" tag under Account entity
4. customize the "RibbonDiffXml" in the following way to add custom group to Entity Form
<CustomActions>
<CustomAction Id="Sample.account.form.CustomGroup.CustomAction" Location="Mscrm.Form.account.MainTab.Groups._children" Sequence="110">
<CommandUIDefinition>
<Group Id="sample.account.form.CustomGroup.Group" Command="sample.account.form.CustomGroup.Command" Title="$LocLabels:sample.account.CustomGroup.Title" Sequence="38" Template="Mscrm.Templates.Flexible2" Image32by32Popup="$webresource:new_samplebutton32x32.png">
<Controls Id="sample.account.form.CustomGroup.Controls">
<Button Id="sample.account.form.CustomGroup.Button.A" Command="sample.account.CustomGroup.Button.A.Command" Sequence="20" LabelText="$LocLabels:sample.account.CustomGroup.Button.A.LabelText" ToolTipTitle="$LocLabels:sample.account.CustomGroup.Button.A.LabelText" ToolTipDescription="$LocLabels:sample.account.CustomGroup.Button.A.Description" TemplateAlias="o1" Image16by16="$webresource:new_samplebutton16x16.png" Image32by32="$webresource:new_samplebutton32x32.png" />
</Controls>
</Group>
</CommandUIDefinition>
</CustomAction>
<CustomAction Id="sample.account.form.CustomGroup.MaxSize.CustomAction" Location="Mscrm.Form.account.MainTab.Scaling._children" Sequence="120">
<CommandUIDefinition>
<MaxSize Id="sample.account.form.CustomGroup.MaxSize" GroupId="sample.account.form.CustomGroup.Group" Sequence="21" Size="LargeLarge" />
</CommandUIDefinition>
</CustomAction>
</CustomActions>
<Templates>
<RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
</Templates>
<CommandDefinitions>
<CommandDefinition Id="sample.account.CustomGroup.Button.A.Command">
<EnableRules/>
<DisplayRules>
<DisplayRule Id="sample.account.form.DisplayRule.NotonCreate" />
</DisplayRules>
<Actions>
<JavaScriptFunction Library="$webresource:new_sample.js" FunctionName="TestFunction"></JavaScriptFunction>
</Actions>
</CommandDefinition>
<CommandDefinition Id="sample.account.form.CustomGroup.Command">
<EnableRules/>
<DisplayRules>
<DisplayRule Id="sample.account.form.DisplayRule.NotonCreate" />
</DisplayRules>
<Actions />
</CommandDefinition>
</CommandDefinitions>
<RuleDefinitions>
<TabDisplayRules />
<DisplayRules>
<DisplayRule Id="sample.account.form.DisplayRule.NotonCreate">
<FormStateRule State="Create" InvertResult="true" />
</DisplayRule>
</DisplayRules>
<EnableRules />
</RuleDefinitions>
<LocLabels>
<LocLabel Id="sample.account.CustomGroup.Button.A.Description">
<Titles>
<Title languagecode="1033" description="Custom Button Description" />
</Titles>
</LocLabel>
<LocLabel Id="sample.account.CustomGroup.Button.A.LabelText">
<Titles>
<Title languagecode="1033" description="Custom Button" />
</Titles>
</LocLabel>
<LocLabel Id="sample.account.CustomGroup.Title">
<Titles>
<Title languagecode="1033" description="Custom Group" />
</Titles>
</LocLabel>
</LocLabels>
</RibbonDiffXml>
5. Now zip the solution and import back to CRM. you will find the custom Group on the Account Form.
Hope it helps!!!
Subscribe to:
Posts (Atom)