You certainly know the empty space on the top of all entity forms in Dynamics CRM 2011 between the entity name on the left and the entity selector on the right-hand side. Here's what I mean:
Probably I'm not the only one askinkg himself why so much visible and valuable space on the form is left unused. So I wrote a JScript that adds a table in here and renders the attributes passed to the OnLoad event handler. Here's are the steps I took to add attributes to that area:
1. Create a JScript Webresource called yourprefix_AccountForm.js and paste the following into the source code:
function setFormTitle(titleFields) {
// get the title container
var titleDIV = document.getElementById("form_title_div");
// prepare the table
var titleTable = document.createElement("table");
var titleTableBody = document.createElement("tbody");
titleTable.appendChild(titleTableBody);
var titleTableRow = document.createElement("tr");
titleTableRow.setAttribute("min-height", "25");
// prepare the left cell with entity name
var leftTableCell = document.createElement("td");
leftTableCell.setAttribute("colSpan", "2");
leftTableCell.className = "ms-crm-Field-Data-Print";
leftTableCell.style.paddingRight = "30px";
// prepare the holding nodes for the entity name
var cloneNodes = new Array();
// move the name nodes into the left table cell
for (var i = titleDIV.childNodes.length - 1; i >= 0; i--) {
// clone the child of the title container
cloneNodes[i] = titleDIV.childNodes[i].cloneNode(true);
// remove the child form the title container
titleDIV.removeChild(titleDIV.childNodes[i]);
// and append the clone to the left container
leftTableCell.insertBefore(cloneNodes[i], leftTableCell.firstChild);
}
// apend the left cell to the table row
titleTableRow.appendChild(leftTableCell);
// append new cells for the fields to the right
for (var f = 0; f < titleFields.length; ++f) {
// prepatre the cell
var titleTableCell = document.createElement("td");
titleTableCell.setAttribute("colSpan", "2");
titleTableCell.className = "ms-crm-Field-Data-Print";
titleTableCell.style.paddingRight = "10px";
// get the label and the data of the field
var titleField = Xrm.Page.ui.controls.get(titleFields[f]);
var attributeField = Xrm.Page.data.entity.attributes.get(titleField.getName());
var dataField = "";
// this is what a standard header field looks like
var labelDiv = document.createElement("div");
labelDiv.className = "ms-crm-Field-Label-Print ms-crm-FieldLabel-LeftAlign";
// create and append the container for the label
var labelSpan = document.createElement("span");
labelSpan.className = "ms-crm-Field-Label-Print ms-crm-FieldLabel-LeftAlign";
var myText = document.createTextNode(titleField.getLabel().replace("Kundenstatus ", ""));
labelSpan.appendChild(myText);
labelDiv.appendChild(labelSpan);
titleTableCell.appendChild(labelDiv);
// create and append the container for the data
var dataDiv = document.createElement("div");
dataDiv.className = "ms-crm-Field-Data-Print";
dataDiv.setAttribute("colspan", "2");
var dataSubDiv = document.createElement("div");
dataSubDiv.className = "ms-crm-Field-Data-Print";
dataSubDiv.style.paddingBottom = "0px";
// handle different types
var dataNode = null;
switch (attributeField.getAttributeType()) {
case "optionset":
var optionValue = attributeField.getSelectedOption();
if (optionValue != null) {
dataNode = document.createTextNode(optionValue.text);
}
break;
case "lookup":
// this is an array of objects with properties: entityType, id, name
var lookupValue = attributeField.getValue();
if (lookupValue != null) {
dataNode = document.createElement("span");
dataNode.setAttribute("title", attributeField.getValue()[0].name);
dataNode.className = "ms-crm-Lookup-Item";
dataNode.setAttribute("contentEditable", "false");
dataNode.setAttribute("onclick", "openlui()");
dataNode.setAttribute("oncontextmenu", "handleGridRightClick()");
dataNode.setAttribute("otypename", lookupValue[0].entityType);
dataNode.setAttribute("otype", "8");
dataNode.setAttribute("oid", attributeField.getValue()[0].id);
// append the the icon
var entityCode = getEntityCode(attributeField.getValue()[0].entityType);
if (entityCode != "0" && entityCode != null) {
iconNode = document.createElement("img");
iconNode.className = "ms-crm-Lookup-Item";
iconNode.alt = "";
iconNode.src = "/_imgs/ico_16_" + entityCode + ".gif";
//iconNode.complete= "complete";
dataNode.appendChild(iconNode);
}
// append the text
dataNode.appendChild(document.createTextNode(attributeField.getValue()[0].name));
}
break;
default: // all other types
dataNode = document.createTextNode(attributeField.getValue());
}
if (dataNode != null) {
dataSubDiv.appendChild(dataNode);
}
dataDiv.appendChild(dataSubDiv);
titleTableCell.appendChild(dataDiv);
// append the cell
titleTableRow.appendChild(titleTableCell);
}
// append the row
titleTableBody.appendChild(titleTableRow);
// append the table
titleDIV.appendChild(titleTable);
}
2. Create a second JScript webresource called yourprefix_EntityCodes.js an paste the following into the source code. This is needed to retrieve the proper icon for lookup attributes but you can use this function any time you need to retrieve the typecode for a given entity name:function getEntityCode(name) {
switch (name) {
case "account": return "1"; break;
case "contact": return "2"; break;
case "opportunity": return "3"; break;
case "lead": return "4"; break;
case "annotation": return "5"; break;
case "businessunitmap": return "6"; break;
case "owner": return "7"; break;
case "systemuser": return "8"; break;
case "team": return "9"; break;
case "businessunit": return "10"; break;
case "principalobjectaccess": return "11"; break;
case "roleprivileges": return "12"; break;
case "systemuserlicenses": return "13"; break;
case "systemuserprincipals": return "14"; break;
case "systemuserroles": return "15"; break;
case "accountleads": return "16"; break;
case "contactinvoices": return "17"; break;
case "contactquotes": return "18"; break;
case "contactorders": return "19"; break;
case "servicecontractcontacts": return "20"; break;
case "productsalesliterature": return "21"; break;
case "contactleads": return "22"; break;
case "teammembership": return "23"; break;
case "leadcompetitors": return "24"; break;
case "opportunitycompetitors": return "25"; break;
case "competitorsalesliterature": return "26"; break;
case "leadproduct": return "27"; break;
case "roletemplateprivileges": return "28"; break;
case "subscription": return "29"; break;
case "filtertemplate": return "30"; break;
case "privilegeobjecttypecodes": return "31"; break;
case "salesprocessinstance": return "32"; break;
case "subscriptionsyncinfo": return "33"; break;
case "subscriptiontrackingdeletedobject": return "35"; break;
case "clientupdate": return "36"; break;
case "subscriptionmanuallytrackedobject": return "37"; break;
case "teamroles": return "40"; break;
case "principalentitymap": return "41"; break;
case "systemuserbusinessunitentitymap": return "42"; break;
case "principalattributeaccessmap": return "43"; break;
case "principalobjectattributeaccess": return "44"; break;
case "incident": return "112"; break;
case "competitor": return "123"; break;
case "documentindex": return "126"; break;
case "kbarticle": return "127"; break;
case "subject": return "129"; break;
case "businessunitnewsarticle": return "132"; break;
case "activityparty": return "135"; break;
case "usersettings": return "150"; break;
case "activitymimeattachment": return "1001"; break;
case "attachment": return "1002"; break;
case "internaladdress": return "1003"; break;
case "competitoraddress": return "1004"; break;
case "competitorproduct": return "1006"; break;
case "contract": return "1010"; break;
case "contractdetail": return "1011"; break;
case "discount": return "1013"; break;
case "kbarticletemplate": return "1016"; break;
case "leadaddress": return "1017"; break;
case "organization": return "1019"; break;
case "organizationui": return "1021"; break;
case "pricelevel": return "1022"; break;
case "privilege": return "1023"; break;
case "product": return "1024"; break;
case "productassociation": return "1025"; break;
case "productpricelevel": return "1026"; break;
case "productsubstitute": return "1028"; break;
case "systemform": return "1030"; break;
case "userform": return "1031"; break;
case "role": return "1036"; break;
case "roletemplate": return "1037"; break;
case "salesliterature": return "1038"; break;
case "savedquery": return "1039"; break;
case "stringmap": return "1043"; break;
case "uom": return "1055"; break;
case "uomschedule": return "1056"; break;
case "salesliteratureitem": return "1070"; break;
case "customeraddress": return "1071"; break;
case "subscriptionclients": return "1072"; break;
case "statusmap": return "1075"; break;
case "discounttype": return "1080"; break;
case "kbarticlecomment": return "1082"; break;
case "opportunityproduct": return "1083"; break;
case "quote": return "1084"; break;
case "quotedetail": return "1085"; break;
case "userfiscalcalendar": return "1086"; break;
case "salesorder": return "1088"; break;
case "salesorderdetail": return "1089"; break;
case "invoice": return "1090"; break;
case "invoicedetail": return "1091"; break;
case "savedqueryvisualization": return "1111"; break;
case "userqueryvisualization": return "1112"; break;
case "ribbontabtocommandmap": return "1113"; break;
case "ribboncontextgroup": return "1115"; break;
case "ribboncommand": return "1116"; break;
case "ribbonrule": return "1117"; break;
case "ribboncustomization": return "1120"; break;
case "ribbondiff": return "1130"; break;
case "replicationbacklog": return "1140"; break;
case "fieldsecurityprofile": return "1200"; break;
case "fieldpermission": return "1201"; break;
case "systemuserprofiles": return "1202"; break;
case "teamprofiles": return "1203"; break;
case "annualfiscalcalendar": return "2000"; break;
case "semiannualfiscalcalendar": return "2001"; break;
case "quarterlyfiscalcalendar": return "2002"; break;
case "monthlyfiscalcalendar": return "2003"; break;
case "fixedmonthlyfiscalcalendar": return "2004"; break;
case "template": return "2010"; break;
case "contracttemplate": return "2011"; break;
case "unresolvedaddress": return "2012"; break;
case "territory": return "2013"; break;
case "queue": return "2020"; break;
case "license": return "2027"; break;
case "queueitem": return "2029"; break;
case "userentityuisettings": return "2500"; break;
case "userentityinstancedata": return "2501"; break;
case "integrationstatus": return "3000"; break;
case "connectionrole": return "3231"; break;
case "connectionroleassociation": return "3232"; break;
case "connectionroleobjecttypecode": return "3233"; break;
case "connection": return "3234"; break;
case "equipment": return "4000"; break;
case "service": return "4001"; break;
case "resource": return "4002"; break;
case "calendar": return "4003"; break;
case "calendarrule": return "4004"; break;
case "resourcegroup": return "4005"; break;
case "resourcespec": return "4006"; break;
case "constraintbasedgroup": return "4007"; break;
case "site": return "4009"; break;
case "resourcegroupexpansion": return "4010"; break;
case "interprocesslock": return "4011"; break;
case "emailhash": return "4023"; break;
case "displaystringmap": return "4101"; break;
case "displaystring": return "4102"; break;
case "notification": return "4110"; break;
case "activitypointer": return "4200"; break;
case "appointment": return "4201"; break;
case "email": return "4202"; break;
case "fax": return "4204"; break;
case "incidentresolution": return "4206"; break;
case "letter": return "4207"; break;
case "opportunityclose": return "4208"; break;
case "orderclose": return "4209"; break;
case "phonecall": return "4210"; break;
case "quoteclose": return "4211"; break;
case "task": return "4212"; break;
case "serviceappointment": return "4214"; break;
case "commitment": return "4215"; break;
case "userquery": return "4230"; break;
case "recurrencerule": return "4250"; break;
case "recurringappointmentmaster": return "4251"; break;
case "emailsearch": return "4299"; break;
case "list": return "4300"; break;
case "listmember": return "4301"; break;
case "campaign": return "4400"; break;
case "campaignresponse": return "4401"; break;
case "campaignactivity": return "4402"; break;
case "campaignitem": return "4403"; break;
case "campaignactivityitem": return "4404"; break;
case "bulkoperationlog": return "4405"; break;
case "bulkoperation": return "4406"; break;
case "import": return "4410"; break;
case "importmap": return "4411"; break;
case "importfile": return "4412"; break;
case "importdata": return "4413"; break;
case "duplicaterule": return "4414"; break;
case "duplicaterecord": return "4415"; break;
case "duplicaterulecondition": return "4416"; break;
case "columnmapping": return "4417"; break;
case "picklistmapping": return "4418"; break;
case "lookupmapping": return "4419"; break;
case "ownermapping": return "4420"; break;
case "importlog": return "4423"; break;
case "bulkdeleteoperation": return "4424"; break;
case "bulkdeletefailure": return "4425"; break;
case "transformationmapping": return "4426"; break;
case "transformationparametermapping": return "4427"; break;
case "importentitymapping": return "4428"; break;
case "relationshiprole": return "4500"; break;
case "relationshiprolemap": return "4501"; break;
case "customerrelationship": return "4502"; break;
case "customeropportunityrole": return "4503"; break;
case "audit": return "4567"; break;
case "entitymap": return "4600"; break;
case "attributemap": return "4601"; break;
case "plugintype": return "4602"; break;
case "plugintypestatistic": return "4603"; break;
case "pluginassembly": return "4605"; break;
case "sdkmessage": return "4606"; break;
case "sdkmessagefilter": return "4607"; break;
case "sdkmessageprocessingstep": return "4608"; break;
case "sdkmessagerequest": return "4609"; break;
case "sdkmessageresponse": return "4610"; break;
case "sdkmessageresponsefield": return "4611"; break;
case "sdkmessagepair": return "4613"; break;
case "sdkmessagerequestfield": return "4614"; break;
case "sdkmessageprocessingstepimage": return "4615"; break;
case "sdkmessageprocessingstepsecureconfig": return "4616"; break;
case "serviceendpoint": return "4618"; break;
case "asyncoperation": return "4700"; break;
case "workflowwaitsubscription": return "4702"; break;
case "workflow": return "4703"; break;
case "workflowdependency": return "4704"; break;
case "isvconfig": return "4705"; break;
case "workflowlog": return "4706"; break;
case "applicationfile": return "4707"; break;
case "organizationstatistic": return "4708"; break;
case "sitemap": return "4709"; break;
case "processsession": return "4710"; break;
case "webwizard": return "4800"; break;
case "wizardpage": return "4802"; break;
case "wizardaccessprivilege": return "4803"; break;
case "timezonedefinition": return "4810"; break;
case "timezonerule": return "4811"; break;
case "timezonelocalizedname": return "4812"; break;
case "solution": return "7100"; break;
case "publisher": return "7101"; break;
case "publisheraddress": return "7102"; break;
case "solutioncomponent": return "7103"; break;
case "dependency": return "7105"; break;
case "dependencynode": return "7106"; break;
case "invaliddependency": return "7107"; break;
case "post": return "8000"; break;
case "postrole": return "8001"; break;
case "postregarding": return "8002"; break;
case "postfollow": return "8003"; break;
case "postcomment": return "8005"; break;
case "postlike": return "8006"; break;
case "report": return "9100"; break;
case "reportentity": return "9101"; break;
case "reportcategory": return "9102"; break;
case "reportvisibility": return "9103"; break;
case "reportlink": return "9104"; break;
case "transactioncurrency": return "9105"; break;
case "mailmergetemplate": return "9106"; break;
case "importjob": return "9107"; break;
case "webresource": return "9333"; break;
case "sharepointsite": return "9502"; break;
case "sharepointdocumentlocation": return "9508"; break;
case "goal": return "9600"; break;
case "goalrollupquery": return "9602"; break;
case "metric": return "9603"; break;
case "rollupfield": return "9604"; break;
default: return 0;
}
}
3. Add both webresources to the form of the entity you want to fill with data. Here's what it should like: 4. Finally pass an array of the attribute names you want to show as an array:
new Array("name", "primarycontactid", "address1_shippingmethodcode")