Friday, December 14, 2012

Add/Remove a Tab in an entity form using plug-in.

    CRM 2011 allows you to customize the entity form by adding/removing Tabs,Sections,IFrames or Fields programmatically using plug-in/C#. In this example we have two major methods called AddTab and RemoveTab. AddTab will add the new Tab with name "TestTab" which is pointing to an html page 'new_/TestTab.htm' to specified entity form. And RemoveTab method will remove the existing tab with name "TestTab" from the specified entity form.


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/// <summary>
/// Method to Add a Tab to entity form.
/// </summary>
/// <param name="entityName">The string.</param>
private void AddTab(string entityName)
{
    Entity entity = GetEntity(entityName);
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(entity.Attributes["formxml"].ToString());
       
    XPathNavigator nav = xmlDoc.CreateNavigator();
    string validateTab = "//tabs/tab[@name='TestTab']";
    string validateTabs = "//tabs";

    string newTab = "<tab name=\"TestTab\" id=\"{3ddb3353-a6ca-3d43-23c2-66ddb019cc50}\" IsUserDefined=\"0\" locklevel=\"0\" showlabel=\"true\" expanded=\"false\">"+
                  "<labels>" +
                  "<label description=\"Test Tab\" languagecode=\"1033\" />" +
                  "</labels>" +
                  "<columns>" +
                  "<column width=\"100%\">" +
                  "<sections>" +
                  "<section name=\"TestTab_Section\" showlabel=\"false\" showbar=\"false\" locklevel=\"0\" id=\"{be95d8ba-6789-d739-4d88-733c9bb914d4}\" IsUserDefined=\"0\" layout=\"varwidth\" columns=\"11\" labelwidth=\"115\" celllabelalignment=\"Left\" celllabelposition=\"Left\">" +
                  "<labels>" +
                  "<label description=\"Test Tab\" languagecode=\"1033\" />" +
                  "</labels>" +
                  "<rows>" +
                  "<row>" +
                  "<cell id=\"{76e6e362-c9d4-1549-25c7-a812d78a16d1}\" showlabel=\"false\" colspan=\"1\" auto=\"false\" rowspan=\"26\">" +
                  "<labels>" +
                  "<label description=\"Entities Test Tab\" languagecode=\"1033\" />" +
                  "</labels>" +
                  "<control id=\"WebResource_EntitiesTestTab\" classid=\"{9FDF5F91-88B1-47f4-AD53-C11EFC01A01D}\">" +
                  "<parameters>" +
                  "<Url>new_/TestTab.htm</Url>" +
                  "<PassParameters>false</PassParameters>" +
                  "<Security>false</Security>" +
                  "<Scrolling>auto</Scrolling>" +
                 "<Border>true</Border>" +
                  "</parameters>" +
                  "</control>" +
                  "<events>" +
                  "<event name=\"onload\" application=\"0\">" +
                  "<dependencies />" +
                  "</event>" +
                  "</events>" +
                  "</cell>" +
                  "</row>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "<row/>" +
                  "</rows>" +
                  "</section>" +
                  "</sections>" +
                  "</column>" +
                  "</columns>" +
                  "</tab>";
       
    XPathNodeIterator iterator = nav.Select(nav.Compile(validateTab));
    if(iterator.Count > 0)
    {
        if(nav.CanEdit)
        {
            XPathNodeIterator xExpression = nav.Compile(validateTabs + "/tab");
            iterator = nav.Select(xExpression);

            if(iterator.Count > 0)
            {
                while(iterator.MoveNext())
                {
                    if(iterator.CurrentPosition == iterator.Count)
                        iterator.Current.InsertAfter(newTab);
                }

                UpdateAndPublishEntityCustomization(entity, entityName, xmlDoc);
            }
        }
    }
}



/// <summary>
/// Method to Add Tab.
/// </summary>
/// <param name="entityName">The string.</param>
private void RemoveTab(string entityName)
{
    Entity entity = GetEntity(entityName);
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(entity.Attributes["formxml"].ToString());
       
    XPathNavigator nav = xmlDoc.CreateNavigator();
    string validateTab = "//tabs/tab[@name='TestTab']";
    XPathNodeIterator iterator = nav.Select(nav.Compile(validateTab));

    if(iterator.Count > 0)
    {
        if(CheckTab(xmlDoc,"TestTab"))
        {
            XmlNode tabXML = xmlDoc.SelectSingleNode(validateTab);
            if(tabXML != null)
               {
                   tabXML.ParentNode.RemoveChild(tabXML);
                   UpdateAndPublishEntityCustomization(entity, entityName, xmlDoc);
               }
        }
    }
}



/// <summary>
/// Method to retrieve entity.
/// </summary>
/// <param name="entityName">The Entity.</param>
/// <return>The Entity</return>
private Entity GetEntity(string entityName)
{
    RetrieveMultipleResponse results = null;
    RetrieveEntityRequest entityReq = new RetrieveEntityRequest();
    entotyReq.EntityFilters = EntityFilters.Entity;
    entotyReq.LogicalName = entityName;
    RetrieveEntityResponse resp = (RetrieveEntityResponse)service.Execute(entityReq);
    var typeCode = resp.EntityMetadata.ObjectTypeCode.Value;

    QueryExpression query = new QueryExpression("systemform");
    query.ColumnSet = new ColumnSet("formxml");
    query.Criteria.AddCondition(new ConditionExpression("type",ConditionOperator.Equal,2));
    query.Criteria.AddCondition(new ConditionExpression("objecttypecode",ConditionOperator.Equal,typeCode));

    RetrieveMultipleRequest multiReq = new RetrieveMultipleRequest();
    multiReq.Query = query;

    results = (RetrieveMultipleResponse)service.Execute(multiReq);
    Entity entity = results.EntityCollection.Entities.FirstOrDefault();

    return entity;
}



/// <summary>
/// Update the form XML and publish the customization.
/// </summary>
/// <param name="entity">The Entity.</param>
/// <param name="entityName">The string.</param>
/// <param name="xmlDoc">The XmlDocument.</param>
private void UpdateAndPublishEntityCustomization(string entity, string entityName, XmlDocument xmlDoc)
{
    entity.Attributes["formxml"] = xmlDoc.InnerXml;
    service.Update(entity);

    PublishXmlRequest publishXmlReq = new PublishXmlRequest();
    publishXmlReq.ParameterXml = @"<importexportxml>" +
                                  "<entities>" +
                                  "<entity>" + entityName + "</entity>" +
                                  "</entities>" +
                                  "</importexportxml>";
    PublishXmlResponse publishXmlResponse = (PublishXmlResponse)service.Execute(publishXmlReq);
}



/// <summary>
/// Check whether the specified Tab is already exist or not
/// </summary>
/// <param name="xmlDoc">The XmlDoc.</param>
/// <param name="tabName">The string.</param>
private bool CheckTab(XmlDocument xmlDoc, string tabName)
{
    bool present = false;
    XmlNodeList Tabs = xmlDoc.GetElementByTagName("tabs");

    foreach(XmlNode tabs in Tabs)
    {
        foreach(XmlNode tab in tabs)
        {
            XmlAttributeCollection Attributes = tab.Attributes;

            foreach(XmlAttribute Attribute in Attributes)
            {
                if(Attribute.Name = "name" && Attribute.Value = tabName)
                    present = true;
            }
        }
    }
    return present;
}

4 comments:

  1. Thank you code.
    I have called AddTab in PreValidateContactCreate and deployed.
    - Clicked "New Contact" added info, on save TestTab xml added and published..
    but it is not displaying in the contact form.
    Is anything am I missing. please help me..

    ReplyDelete
    Replies
    1. On which action I need to create the plugin.
      - My requirement is displaying details of user in a web resource (which has to be created dynamically if not exists).

      Delete