在MS CRM系统中,有一种字段类型是partylist,该类型的字段可以存储多个lookup值,例如电子邮件实体中的收件人、抄送以及密件抄送等字段都是partylist类型的。PartyList类型字段的使用效果截屏如下图所示。
点击控件右侧的 图标,进行查找时,PartyList类型的字段所对应的查找对话框是lookupmulti对话框,而普通的lookup类型字段所对应的查找对话框是lookupsingle对话框。两种对话框的对比如下图所示。
LookupMulti对话框 |
LookupSingle对话框 |
很不幸的是,CRM实施人员无法创建PartyList类型的字段——在创建字段时,字段的数据类型列表中没有PartyList这一条目。字段数据类型列表如下图所示
而很多时候,最终用户希望能够使用PartyList类型的字段。怎么办呢,首先是试图说服客户,这种字段我们无能为力;其次呢,在客户坚持需要的情况下,只好模拟一个吧——客户总是上帝,上帝都说话了,我们就遵守吧——虽然,我的信仰是佛祖。
创建PartyList字段的步骤,主要是两步,第一,创建字段,用于存储数据;第二,创建脚本,完成界面渲染以及数据保存。
工作目标:在电子邮件表单中,添加架构名称为new_partylistfield的字段,该字段具有收件人的外观特性,而且,该字段对应的查找对话框的数据类型只能够是系统用户。
为了上面的目标努力吧:
第一步, 在电子邮件实体中添加两个字段,架构名称分别是new_partylistfield以及new_partylistcontent,两个字段的属性信息如下图所示。
new_partylistfield字段信息 |
new_partylistcontent字段信息 |
向电子邮件表单中添加这两个字段,最终的界面效果如下图。
第二步,编写脚本,
OnLoad事件的脚本如下所示
function onLoad()
{
var fieldName = "new_partylistfield";
var input = document.getElementById(fieldName);
var tabIndex = input.tabIndex;
var label = document.getElementById(fieldName + "_c").innerText;
var str = "<TABLE style='TABLE-LAYOUT: fixed' class=ms-crm-Lookup cellSpacing=0 cellPadding=0 width='100%'>" +
"<TBODY>" +
"<TR>" +
"<TD>";
if (crmForm.all.new_partylistcontent.DataValue != null)
{
str += "<DIV class=ms-crm-Lookup tabIndex=" + (parseInt(tabIndex) + 1).toString() + " ime-mode='auto'>";
//<r><u id="" n="" /><u id="" n=""/></r>
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(crmForm.all.new_partylistcontent.DataValue);
var nodeList = xmlDoc.getElementsByTagName("u");
for (var i = 0; i < nodeList.length; i++)
{
var systemUserId = nodeList[i].getAttribute("id");
var systemUserName = nodeList[i].getAttribute("n");
str += "<SPAN class=ms-crm-Lookup-Item contentEditable=false onclick=openlui() unselectable='on' otypename='systemuser' otype='8' oid='" + systemUserId + "' data='' ?=''>";
str += "<SPAN contentEditable=false unselectable='on' wrapper='true'>";
str += "<IMG class=ms-crm-Lookup-Item alt=' ' src='/_imgs/ico_16_8.gif'></IMG>" + systemUserName;
str += "<a tabIndex='-1' title='" + systemUserName + "' class='atLink' id='at" + systemUserId + "' contentEditable='false' onclick='return false;' href='javascript:onclick();' target='_self'></a>";
str += "<b class='IMG_lu_htc_b'></b>";
str += "</SPAN>";
str += "</SPAN>";
}
str += "</DIV>";
}
else
{
str += "<DIV style='WIDTH: 100%' class='ms-crm-Lookup ' tabIndex=" + (parseInt(tabIndex) + 1).toString() + " ime-mode='auto'></DIV>";
}
str += "<LABEL class=ms-crm-Hidden-NoBehavior for=" + fieldName + "_ledit>" + label + "</LABEL>";
str += "<INPUT id=" + fieldName + "_ledit class=ms-crm-Hidden-NoBehavior tabIndex=" + tabIndex + " maxLength=1000 ime-mode='auto'>" +
"</TD>" +
"<TD class=Lookup_RenderButton_td width=25>" +
"<IMG style='IME-MODE: auto' id=" + fieldName + " class=ms-crm-Lookup-Party src='/_imgs/btn_off_lookup.gif' req='0' resolveemailaddress='0' showproperty='1' autoresolve='1' defaulttype='0' lookupstyle='multi' lookupbrowse='0' lookupclass='ActivityRecipient' lookuptypeIcons='/_imgs/ico_16_8.gif' lookuptypenames='systemuser:8' lookuptypes='8'>" +
"<A tabIndex=-1 onclick='previousSibling.click();' href='#'></A>" +
"</TD>" +
"</TR>" +
"</TBODY>" +
"</TABLE>";
input.parentNode.innerHTML = str;
}
这段函数主要的作用就是根据new_partylistcontent字段中的内容填充new_partylistfield字段的展现样式以及其中包含的数据。
OnSave事件的脚本如下:
function onSave()
{
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML("<r></r>");
var root = xmlDoc.firstChild;
var fieldName = "new_partylistfield";
var tbl = document.getElementById(fieldName + "_d").firstChild;
var div = tbl.rows[0].cells[0].firstChild;
for (var i = 0; i < div.childNodes.length; i++)
{
var uNode = root.appendChild(xmlDoc.createElement("u"));
uNode.setAttribute("id", div.childNodes[i].oid);
uNode.setAttribute("n", div.childNodes[i].firstChild.innerText);
}
crmForm.all.new_partylistcontent.DataValue = xmlDoc.xml;
crmForm.all.new_partylistfield.DataValue = null;
}
这段代码,就是解析new_partylistfield字段中的数据信息,将其转换为xml格式的字符串,以保存到new_partylistcontent字段中。
为表单创建了事件处理脚本后,保存,发布,打开电子邮件表单,看一下效果。如下图所示:
当然,为了界面显示的需要,可以将new_partylistcontent字段进行隐藏。