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")