Friday, March 16, 2012

Modifying System Ribbon button functionality CRM 2011


I found ribbons in 2011 the most painful part, till i learnt how to use it. It is actually cooler than in CRM4. To modify a system button functionality: All that we need to do here is copy the button ID as is from exportedribbonxml available from  sdk\samplecode\cs\client\ribbon\exportribbonxml\exportedribbonxml\myentityribbon.xml.
In this case, i'm gonna modify my email form's send button functionality. The button definition from emailribbon.xml looks like:

<Button Id="Mscrm.Form.email.Send" Command="MSCRM.Form.email.Send.CustomCommand" Sequence="1" Alt="$Resources:Ribbon.Form.email.MainTab.Actions.Send" LabelText="$Resources:Ribbon.Form.email.MainTab.Actions.Send" Image16by16="/_imgs/SFA/SendAsEmail_16.png" Image32by32="/_imgs/SFA/SendAsEmail_32.png" TemplateAlias="o1" ToolTipTitle="$Resources:Mscrm_Form_email_MainTab_Actions_Send_ToolTipTitle" ToolTipDescription="$Resources:Mscrm_Form_email_MainTab_Actions_Send_ToolTipDescription" />

Add that buttondefinition as we would do for adding any custom button. Just match the location attribute of the Customaction tag for the button with the button ID.
i.e.  Change your CustomAction's location attribute

<CustomAction Id="Mscrm.Form.email.Send.CustomAction" Location="Mscrm.Form.email.Send" Sequence="1"><CommandUIDefinition><Button Id="Mscrm.Form.email.Send" Command="MSCRM.Form.email.Send.CustomCommand" Sequence="1" Alt="$Resources:Ribbon.Form.email.MainTab.Actions.Send" LabelText="$Resources:Ribbon.Form.email.MainTab.Actions.Send" Image16by16="/_imgs/SFA/SendAsEmail_16.png" Image32by32="/_imgs/SFA/SendAsEmail_32.png" TemplateAlias="o1" ToolTipTitle="$Resources:Mscrm_Form_email_MainTab_Actions_Send_ToolTipTitle" ToolTipDescription="$Resources:Mscrm_Form_email_MainTab_Actions_Send_ToolTipDescription" /></CommandUIDefinition></CustomAction>

After this, i define a Commanddefinition MSCRM.Form.email.Send.CustomCommand inside my command definition tag.

<CommandDefinition Id="MSCRM.Form.email.Send.CustomCommand">            <EnableRules><EnableRule Id="Mscrm.UserHasRoleForSend"/>            </EnableRules><DisplayRules><DisplayRule Id="Mscrm.CanWritePrimary" />              <DisplayRule Id="Mscrm.Form.email.InDraftOrFailedState" /></DisplayRules><Actions><JavaScriptFunction FunctionName="send" Library="/_static/activities/email.js" /></Actions></CommandDefinition>

After this, i define my customrule "Mscrm.UserHasRoleForSend" inside a javascript.

<EnableRules><EnableRule Id="Mscrm.UserHasRoleForSend"><CustomRule FunctionName="UserHasRoleForSend" Library="$webresource:customscripts_CheckUserRoleForMarketingList.js" /></EnableRule></EnableRules>

customscripts_CheckUserRoleForMarketingList.js is a webresource jscript that i've already uploaded. I'm calling a function UserHasRoleForSend in customscripts_CheckUserRoleForMarketingList.js. The function returns a true or false value.
Since the display rules are inbuilt i'm not redefining them in my customizations.xml.
Note: If not required, we can remove the displayrules from the custom command. In my case, i just needed to add an additional condition for enabling the "send" button in email form. The same can be done for HomePageGrid buttons also.



Thursday, March 8, 2012

Sample Odata Query CRM2011


function GetCity()
{
var serverUrl = "http://"+window.location.host+"/" + Xrm.Page.context.getOrgUniqueName();
  var id = Xrm.Page.getAttribute("new_courtid").getValue();
if(id!=null)
{
    var ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc";

    var retrieveReq = new XMLHttpRequest();
//replace with your odata query
    var Odata = ODataPath + "/AccountSet?$select=new_city&$filter=accountId eq guid'" + id[0].id + "'";
    retrieveReq.open("GET", Odata, true);
    retrieveReq.setRequestHeader("Accept", "application/json");
    retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    retrieveReq.onreadystatechange = function () { retrieveReqCallBack(this); };
    retrieveReq.send();
}
}

function retrieveReqCallBack(retrieveReq) {

    if (retrieveReq.readyState == 4 /* complete */) {
        if (retrieveReq.status == 200) {
            var retrieved = JSON.parse(retrieveReq.responseText).d;
//replace attribute name as in the query
            var city= retrieved.results[0]["new_city"];
            Xrm.Page.data.entity.attributes.get('new_city').setValue(city.Value);
        }
        else {
            errorHandler(retrieveReq);
            alert("Unable to Retrieve City");
        }
    }
}

Tuesday, March 6, 2012

Read Config File from a different location


ExeConfigurationFileMap cf =
                new ExeConfigurationFileMap() { ExeConfigFilename = "C:\\app.config" };


            Configuration configFile = ConfigurationManager.OpenMappedExeConfiguration(cf, ConfigurationUserLevel.None);


This by default provides KeyValuePair when you attempt to read the settings. To return KeyValuePair as NameValuePair, Use as below. 




            ExeConfigurationFileMap cf =
                new ExeConfigurationFileMap() { ExeConfigFilename = "C:\\app.config" };


            Configuration confFile = ConfigurationManager.OpenMappedExeConfiguration(cf, ConfigurationUserLevel.None);
                       NameValueCollection _collsettings = new NameValueCollection();
            foreach (string key in confFile.AppSettings.Settings.AllKeys)
            {
                 _collsettings.Add(confFile.AppSettings.Settings[key].Key, confFile.AppSettings.Settings[key].Value);
            }


If you are reading machine config file, make use of Suitable class instead of Execonfigurationfilemap.