Showing posts with label Ribbon Button. Show all posts
Showing posts with label Ribbon Button. Show all posts

Wednesday, November 6, 2013

How to restore a hidden button on the CRM 2013 Command Bar

The new Dynamics CRM 2013’s command bar has deliberatly limited space for buttons due to the ‘intentionally constrained’ user interface design. The idea being that if you limit the space for buttons, then designers will be forced to only show those that are absolutely necessary and the user experience will be improved. As result, many of the buttons from the CRM 2011 Ribbon Bar have been removed from the CRM 2013 Command Bar.
The CRM2011 Ribbon Buttons are still there, but hidden using a new RibbonXml Display Rule named 'Mscrm.HideOnCommandBar'. This article shows you how to restore those buttons to the Command Bar that your users absolutely must have using the Ribbon Workbench for CRM2013.
1. Create a solution containing the entities that you wish to restore buttons for. This example uses the ‘Case’ entity, and we are restoring the ‘Connect’ button on the ‘Form’ command bar.
Before customising, the Form Command Bar looks like the following:
You’ll notice that only 5 buttons are shown until buttons are added to the ‘overflow’ menu. The ‘Connect’ button is not here since it was deemed unessential.
2. Open the solution containing the Case entity in the Ribbon Workbench for CRM 2013 and select the ‘incident’ entity if not already selected. You will see by default the Command Bar is selected.
 
3. In order to locate the button we want to restore, click on the ‘Ribbon’ selector to show the Ribbon. This will show the Ribbon Design surface.
4. Select the ‘Form’ ribbon using the dropdown on the top right of the design surface, then select the ‘Connect’ button and Right-Click ‘Customize Command’
5. Locate the Customised Command in the ‘Solution Elements’ tab under ‘Commands’
6.  In the Edit Display Rules dialog, select the ‘Mscrm.HideOnCommandBar’ rule and click the ‘<Remove’ button.
7.  Important: Locate the following Display Rules, and set the ‘IsCore’ property to ‘True’ – this will prevent them from being customised as well:
a.      Mscrm.HideOnCommandBar
b.      Mscrm.CreateConnection
c.      Mscrm.IsConnectionsEnabledPrimary
d.      Mscrm.HideOnModern
8. Important: Locate the ‘Mscrm.FormStateExistingOrReadOnlyOrDisabled’ Enable Rule, and set the ‘IsCore’ property to ‘True’
9. Click ‘Publish’
10 Now when you refresh the Case Form, you will see the Connect button again.
11  You’ll notice that only the default button is shown – so if you use the drop down, you’ll only get the ‘Connect to Another’ option. To enable the ‘To Me’ button repeat the process for the ‘To Me’ button:
Remember to make sure that only the buttons that are really needed are included - the Command Bar has been constrained intentially to give your users the best experience.

Monday, November 5, 2012

Open Silverlight application on click of custom ribbon button in CRM 2011


First Create a Silverlight application and upload on Webresource in CRM.
Then second step create a HTML web Page like below.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
 
<head>
    <title>ExpenseNote</title>
    <style type="text/css">
    html, body {
        height: 100%;
        overflow: auto;
    }
    body {
        padding: 0;
        margin: 0;
    }
    #silverlightControlHost {
        height: 100%;
        text-align:center;
    }
    </style>
    <script type="text/jscript" src="../../ClientGlobalContext.js.aspx"></script>
   1:  
   2:     <script type="text/javascript" src="../JavaScripts/Silverlight.js">
   1: </script>
   2:     <script type="text/javascript">
   3:       function onSilverlightError(sender, args) {
   4:         
   5:             var appSource = "";
   6:             if (sender != null && sender != 0) {
   7:               appSource = sender.getHost().Source;
   8:             }
   9:             
  10:             var errorType = args.ErrorType;
  11:             var iErrorCode = args.ErrorCode;
  12:  
  13:             if (errorType == "ImageError" || errorType == "MediaError") {
  14:               return;
  15:             }
  16:  
  17:             var errMsg = "Unhandled Error in Silverlight Application " +  appSource + "\n" ;
  18:  
  19:             errMsg += "Code: "+ iErrorCode + "    \n";
  20:             errMsg += "Category: " + errorType + "       \n";
  21:             errMsg += "Message: " + args.ErrorMessage + "     \n";
  22:  
  23:             if (errorType == "ParserError") {
  24:                 errMsg += "File: " + args.xamlFile + "     \n";
  25:                 errMsg += "Line: " + args.lineNumber + "     \n";
  26:                 errMsg += "Position: " + args.charPosition + "     \n";
  27:             }
  28:             else if (errorType == "RuntimeError") {           
  29:                 if (args.lineNumber != 0) {
  30:                     errMsg += "Line: " + args.lineNumber + "     \n";
  31:                     errMsg += "Position: " +  args.charPosition + "     \n";
  32:                 }
  33:                 errMsg += "MethodName: " + args.methodName + "     \n";
  34:             }
  35:  
  36:             throw new Error(errMsg);
  37:         }
  38:     
</script>
</head>
<body>
    <form id="form1" runat="server" style="height:100%">
    <div id="silverlightControlHost">
      <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
          <param name="source" value="../XAP/Treeview.xap"/>
          <param name="onError" value="onSilverlightError" />
          <param name="background" value="white" />
          <param name="minRuntimeVersion" value="4.0.50826.0" />
          <param name="autoUpgrade" value="true" />
          <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration:none">
               <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
          </a>
        </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
    </form>
</body>
</html>




Note:

1) In the source parameter specify the path of your xap webresource correctly.
Here name of the webresource is ink_/XAP/Treeview.xap and so the value for source is "../XAP/Treeview.xap", a relative path.

2) Also add the SilverLight.js file as a webresource. You can find the Silverlight.js file in sdk in the Silverlight example projects.

Now create a webresource and upload this html file. We have named this html webresource as Treeview.html.

Now we need to open this html file on click of a button.

For this we will create a button. You can create button using the Visual Ribbon editor. To use Visual Ribbon Editor refer this link
http://microsoftcrmkartik.blogspot.in/2012/10/create-mark-complete-function-button-in.html

In Action you can either directly specify a URL which will be accessed on button click or you can specify a javascript function which is defined within a webresource of type javascript file. In this example we would be using a javascript function defined within a webresource.

Here OpenSilverLightControl is the function that contains code to open the Treeview.html file.



function OpenSilverLightControl()
 {
var serverUrl = Xrm.Page.context.getServerUrl();         
window.showModalDialog(serverUrl+'/WebResources/ink_/html/Treeview.html', " ","dialogWidth:800px ; dialogHeight:600px; center:yes;resizable:yes");
}

Friday, October 5, 2012

Create Mark Complete Function Button in Custom Entity.


I have one requirement that i have to create same functionality that we have in Phone call Activity like Mark Complete.

Please Follow the Below steps to create Mark Complete Functionality.

1.First Go to Settings->Customization->Select Entity->Field->open Status Reason Field->Select In Active Dropdown->Add new ->Completed and save and publish.

2.Now Go to We Resource and Add PNG File for Mark Complete Button with name new_imgComplete.

3.Go to Setting->Solution(Under Customization)->Then Create a New Solution->Save and Close.

4.Open the Newly Created Solution->Add Existing->Entity and select the Entity to which you want to Add the Mark Complete Button.->Save and Close.

5.Now select the Solution and Export(Unmanaged) the Solution.

6.Open customizations.xml File.

7. under <RibbonDiffXml>.......</RibbonDiffXml> paste the Following line

<RibbonDiffXml>
 <CustomActions>
          <CustomAction Id="Form.CustomAction" Location="Mscrm.Form.hov_meeting.MainTab.Save.Controls._children" Sequence="1">
            <CommandUIDefinition>
              <Button Id="Form.Button.CompleteMeeting" Command="Form.CommandDef" LabelText="$LocLabels:Lable.Text" ToolTipTitle="$LocLabels:Lable.ToolTip" ToolTipDescription="$LocLabels:Lable.ToolTip" TemplateAlias="o1" Image32by32="$webresource:new_imgComplete" />
            </CommandUIDefinition>
          </CustomAction>
        </CustomActions>
        <Templates>
          <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
        </Templates>
        <CommandDefinitions>
          <CommandDefinition Id="Form.CommandDef">
            <EnableRules>
              <EnableRule Id="EnableRule.NotNew" />
              <EnableRule Id="EnableRule.WebClient" />
              <EnableRule Id="EnableRule.CustomButton" />
            </EnableRules>
            <DisplayRules>
              <DisplayRule Id="DisplayRule.FormStateNotNew" />
              <DisplayRule Id="DisplayRule.WebClient" />
            </DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:new_MeetingFunctions" FunctionName="MarkComplete" />
            </Actions>
          </CommandDefinition>
        </CommandDefinitions>
        <RuleDefinitions>
          <TabDisplayRules />
          <DisplayRules>
            <DisplayRule Id="DisplayRule.FormStateNotNew">
              <FormStateRule State="Create" InvertResult="true" />
            </DisplayRule>
            <DisplayRule Id="DisplayRule.WebClient">
              <CrmClientTypeRule Type="Web" />
            </DisplayRule>
          </DisplayRules>
          <EnableRules>
            <EnableRule Id="EnableRule.CustomButton">
              <CustomRule Library="$webresource:new_MeetingFunctions" FunctionName="test" />
            </EnableRule>
            <EnableRule Id="EnableRule.NotNew">
              <FormStateRule State="Create" InvertResult="true" />
            </EnableRule>
            <EnableRule Id="EnableRule.WebClient">
              <CrmClientTypeRule Type="Web" />
            </EnableRule>
          </EnableRules>
        </RuleDefinitions>
        <LocLabels>
          <LocLabel Id="Lable.Text">
            <Titles>
              <Title languagecode="1033" description="Mark Complete" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Lable.ToolTip">
            <Titles>
              <Title languagecode="1033" description="Mark Complete" />
            </Titles>
          </LocLabel>
        </LocLabels>
</RibbonDiffXml>

8.Now Zip the all File again with the same name that you export the solution and import again in solution.

9.Now create one .js file with name new_MeetingFunctions and Add the script in WebResource.be sure that if you give the another name then you have to change it in Customizations.xml file under

<Actions>
         <JavaScriptFunction Library="$webresource:new_MeetingFunctions" FunctionName="MarkComplete" />
</Actions>

10.Now paste the Following lines in .js File

function MarkComplete()
{
   alert(Xrm.Page.context.getServerUrl());
    //SetStateRequest(Entity Name, Xrm.Page.data.entity.getId(), 1,100000000);
    SetStateRequest("hov_meeting", Xrm.Page.data.entity.getId(), 1,100000000);
    window.location.reload(true);
}

function RetrieveOptionsetLabel(entityLogicalName ,RetrieveAttributeName,optionValue,AssignAttributeName,Id  )
{
    // Calling Metadata service to get Optionset Label
    SDK.MetaData.RetrieveEntityAsync(SDK.MetaData.EntityFilters.Attributes, entityLogicalName, null, false, function (entityMetadata) { successRetrieveEntity(entityLogicalName, entityMetadata, RetrieveAttributeName, optionValue,AssignAttributeName,Id); }, errorDisplay);

}

function successRetrieveEntity(logicalName, entityMetadata, RetrieveAttributeName, OptionValue,AssignAttributeName,Id)
{

    var success = false;
    for (var i = 0; i < entityMetadata.Attributes.length; i++) {
        var AttributeMetadata = entityMetadata.Attributes[i];
        if (success) break;
        if (AttributeMetadata.SchemaName.toLowerCase() == RetrieveAttributeName.toLowerCase()) {
            for (var o = 0; o < AttributeMetadata.OptionSet.Options.length; o++) {
                var option = AttributeMetadata.OptionSet.Options[o];
                if (option.OptionMetadata.Value == OptionValue)
                {

                    //Xrm.Page.getAttribute(AssignAttributeName).setValue(option.OptionMetadata.Label.UserLocalizedLabel.Label);
   var serverUrl = location.protocol + '//' + location.host + '/' + Xrm.Page.context.getOrgUniqueName(); //Xrm.Page.context.getServerUrl();

var meetinglink = "<a href='javascript: void(0);' onclick=\"window.open(\'" + serverUrl + "/main.aspx?etn=hov_meeting&pagetype=entityrecord&id={" + Id + "}\', \'windowname1\', \'resizable=1, scrollbars=1\');  return false;\" style='color:blue;text-decoration:underline !important'>" + option.OptionMetadata.Label.UserLocalizedLabel.Label + "</a>";

                    document.getElementById("header_" + AssignAttributeName + "_d").childNodes[0].innerHTML=meetinglink;
                    success = true;
                    break;
                }
            }
        }
    }
}



function SetStateRequest(_entityname, entityid, _state, _status)
{
    var requestMain = ""
    requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
    requestMain += "  <s:Body>";
    requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
    requestMain += "      <request i:type=\"b:SetStateRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
    requestMain += "        <a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
    requestMain += "          <a:KeyValuePairOfstringanyType>";
    requestMain += "            <c:key>EntityMoniker</c:key>";
    requestMain += "            <c:value i:type=\"a:EntityReference\">";
    requestMain += "              <a:Id>" + entityid + "</a:Id>";
    requestMain += "              <a:LogicalName>" + _entityname + "</a:LogicalName>";
    requestMain += "              <a:Name i:nil=\"true\" />";
    requestMain += "            </c:value>";
    requestMain += "          </a:KeyValuePairOfstringanyType>";
    requestMain += "          <a:KeyValuePairOfstringanyType>";
    requestMain += "            <c:key>State</c:key>";
    requestMain += "            <c:value i:type=\"a:OptionSetValue\">";
    requestMain += "              <a:Value>" + _state + "</a:Value>";
    requestMain += "            </c:value>";
    requestMain += "          </a:KeyValuePairOfstringanyType>";
    requestMain += "          <a:KeyValuePairOfstringanyType>";
    requestMain += "            <c:key>Status</c:key>";
    requestMain += "            <c:value i:type=\"a:OptionSetValue\">";
    requestMain += "              <a:Value>" + _status + "</a:Value>";
    requestMain += "            </c:value>";
    requestMain += "          </a:KeyValuePairOfstringanyType>";
    requestMain += "        </a:Parameters>";
    requestMain += "        <a:RequestId i:nil=\"true\" />";
    requestMain += "        <a:RequestName>SetState</a:RequestName>";
    requestMain += "      </request>";
    requestMain += "    </Execute>";
    requestMain += "  </s:Body>";
    requestMain += "</s:Envelope>";
    var req = new XMLHttpRequest();
    req.open("POST", _getServerUrl(), false)  
    req.setRequestHeader("Accept", "application/xml, text/xml, */*");
    req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
    var successCallback = null;
    var errorCallback = null;
    req.onreadystatechange = function () { SetStateResponse(req, successCallback, errorCallback); };
    req.send(requestMain);
}

function SetStateResponse(req, successCallback, errorCallback)
{

    if (req.readyState == 4)
    {
        if (req.status == 200)
        {
            if (successCallback != null)
            { successCallback(); }
        }
        else
        {
            _getError(req.responseXML);
        }
    }
}

function successCallback()
{
alert('test');
}

function _getServerUrl()
{
    var OrgServicePath = "/XRMServices/2011/Organization.svc/web";
    var serverUrl = "";
    if (typeof GetGlobalContext == "function")
    {
        var context = GetGlobalContext();
        serverUrl = context.getServerUrl();
    }
    else
    {
        if (typeof Xrm.Page.context == "object")
        {
            serverUrl = location.protocol + '//' + location.host+ '/' + Xrm.Page.context.getOrgUniqueName();
           //If you are using the Trail vesrion of CRM means CRM Online then
           // serverUrl = location.protocol + '//' + location.host;
        }
        else
        { throw new Error("Unable to access the server URL"); }
    }
    if (serverUrl.match(/\/$/))
    {
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);
    }
    return serverUrl + OrgServicePath;
}

function _getError(faultXml)
{
    var errorMessage = "Unknown Error (Unable to parse the fault)";
    if (typeof faultXml == "object")
    {
        try
        {
            var bodyNode = faultXml.firstChild.firstChild;
            //Retrieve the fault node
            for (var i = 0; i < bodyNode.childNodes.length; i++)
            {
                var node = bodyNode.childNodes[i];
                if ("s:Fault" == node.nodeName)
                {
                    for (var j = 0; j < node.childNodes.length; j++)
                    {
                        var faultStringNode = node.childNodes[j];
                        if ("faultstring" == faultStringNode.nodeName)
                        {
                            errorMessage = faultStringNode.text;
                            break;
                        }
                    }
                    break;
                }
            }
        }
        catch (e) { };
    }
    return new Error(errorMessage);
}

function GetOptionsetLabel(entityLogicalName ,RetrieveAttributeName,optionValue,AssignAttributeName)
{
    // Calling Metadata service to get Optionset Label
    SDK.MetaData.RetrieveEntityAsync(SDK.MetaData.EntityFilters.Attributes, entityLogicalName, null, false, function (entityMetadata) { successGetEntity(entityLogicalName, entityMetadata, RetrieveAttributeName, optionValue,AssignAttributeName); }, errorDisplay);

}

function successGetEntity(logicalName, entityMetadata, RetrieveAttributeName, OptionValue,AssignAttributeName)
{
    var success = false;
    for (var i = 0; i < entityMetadata.Attributes.length; i++) {
        var AttributeMetadata = entityMetadata.Attributes[i];
        if (success) break;
        if (AttributeMetadata.SchemaName.toLowerCase() == RetrieveAttributeName.toLowerCase()) {
            for (var o = 0; o < AttributeMetadata.OptionSet.Options.length; o++) {
                var option = AttributeMetadata.OptionSet.Options[o];
                if (option.OptionMetadata.Value == OptionValue)
                {
                    Xrm.Page.getAttribute(AssignAttributeName).setValue(option.OptionMetadata.Label.UserLocalizedLabel.Label);  
                    success = true;
                    break;
                }
            }
        }
    }
}

function GetRequestObject()
{
    if (window.XMLHttpRequest)
        return new window.XMLHttpRequest;
    else
    {
        try
        {
            return new ActiveXObject("MSXML2.XMLHTTP.3.0");
        }
        catch (ex)
        {
            return null;
        }
    }
}

function errorDisplay(XmlHttpRequest, textStatus, errorThrown)
{
     alert(errorThrown);
}

function trim(str)
{
    if(!str || typeof str != 'string')
        return null;

    return str.replace(/^[\s]+/,'').replace(/[\s]+$/,'').replace(/[\s]{2,}/,' ');
}

11.Now Open the Form and Add Javascript Library  from Web Resource. and Save it and publish the Form.

12.Thats it and just check now.Create the Record from and Save and Close.and again open the Record and Click on Mark Complete Button.