因爲從Microsoft Dynamics CRM 2011到Microsoft Dynamics CRM 2013,界面的風格發生了很大的變化javascript
故原先在2011上開發的選項集多選在2013上面已經再也不適用.css
一直想不明白的是,微軟爲啥還不支持選項集的多選呢?html
折騰的一番,具體效果以下,但還有不少不滿意的地方,但願有興趣的,或者已經作過相似功能的各位,提供下寶貴的意見,不甚感激!java
具體使用步驟以下:web
1.建立選項集字段,文本型字段各一個app
本文使用的字段名分別爲:new_post(選項集),new_post_value(保存多選值的文本型字段)dom
2.在窗體的OnLoad事件中添加ConvertToMultiPicklist事件,詳細代碼以下async
//表單加載時轉化單選爲多選 function ConvertToMultiPicklist(entityName, fieldSchema) { var picklistValue = $("#" + fieldSchema + "" + "_value" + "").text(); //step1:經過SOAP獲取picklist的value,text列表(返回類型爲Object Array,格式爲[100000000,測試text]) var optionSetValueList = GetOptionSet1(entityName, fieldSchema, 2052, false); if (optionSetValueList != null && optionSetValueList.length > 0) { //step2.1:先清空原先picklist的內容(html) $("#" + fieldSchema + "" + "_d" + "").html(""); //step2.2:開始構建多選所需的html var appendHtml = ""; //border:1px solid #f3f1f2; appendHtml += "<div style=\"padding-top:0px;padding-left:0px;padding-bottom:20px;padding-right:20px; margin-left:15px;\">"; appendHtml += "<ul style=\"list-style:none;\">"; for (var i = 0; i < optionSetValueList.length; i++) { var checkboxId = "cb_" + fieldSchema + "_" + i; appendHtml += "<li style=\"float:left;display:block;padding-left:5px;\">"; appendHtml += "<input type=\"checkbox\" value=\"" + optionSetValueList[i][0] + "\" style=\"width:auto;\" class=\"" + fieldSchema + "\" id=\"" + checkboxId + "\" "; //step2.3:加載已經保存的選項 if (picklistValue.indexOf(optionSetValueList[i][0] + ":" + optionSetValueList[i][1] + ";") > -1) { appendHtml += "checked=\"checked\""; } appendHtml += "/>"; appendHtml += "<label for=\"" + checkboxId + "\">" + optionSetValueList[i][1] + "</label>"; appendHtml += "</li>"; } appendHtml += "</ul>"; appendHtml += "</div>"; //step3:用構建好的html替換原先的picklist的html $("#" + fieldSchema + "" + "_d" + "").html(appendHtml); } }
與ConvertToMultiPicklist函數相關其餘函數以下函數
function GetOptionSet1(entitySchema, attributeSchema, languageCode, mode) { var xmlHttpRequest = RetrieveAttribute(entitySchema, attributeSchema, mode); var optionSet = []; if (xmlHttpRequest.status == 200) { //將responseText轉爲responseXml var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0"); xmlDoc.async = false; xmlDoc.loadXML(xmlHttpRequest.responseText); oXml = xmlDoc; var optionMetadataNodes = oXml.selectNodes("//c:OptionMetadata"); for (var i = 0; i < optionMetadataNodes.length; i++) { optionSet[i] = []; optionSet[i][0] = optionMetadataNodes[i].selectSingleNode("c:Value").text; optionSet[i][1] = ""; var localizedLabelsData = optionMetadataNodes[i].selectSingleNode("c:Label/a:LocalizedLabels"); for (var j = 0; j < localizedLabelsData.childNodes.length; j++) { var localizedLabelData = localizedLabelsData.childNodes[j]; if (localizedLabelData.selectSingleNode("a:LanguageCode").text == languageCode) { optionSet[i][1] = localizedLabelData.selectSingleNode("a:Label").text; } } } } else { var errorMessage = ParseError(xmlHttpRequest.responseXML); alert("獲取選項集集合失敗,錯誤信息:" + errorMessage); } return optionSet; }
不知啥緣由,在調用GetOptionSet1,獲取httpXmlRequest.responseXml的時候,一直出現未明的錯誤..而responseText則是正常的,故上面用的是responseText,而後再把responseText轉爲responseXml(轉換過程當中用到了ActiveXObject,因此,以上方法暫時只支持IE)post
//內部函數 獲取屬性MetaData function RetrieveAttribute(entitySchema, attributeSchema, mode) { var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>"; request += "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"; request += "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">"; request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">"; request += "<a:KeyValuePairOfstringanyType>"; request += "<b:key>MetadataId</b:key>"; request += "<b:value i:type=\"c:guid\" xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/\">00000000-0000-0000-0000-000000000000</b:value>"; request += "</a:KeyValuePairOfstringanyType>"; request += "<a:KeyValuePairOfstringanyType>"; request += "<b:key>RetrieveAsIfPublished</b:key>"; request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">true</b:value>"; request += "</a:KeyValuePairOfstringanyType>"; request += "<a:KeyValuePairOfstringanyType>"; request += "<b:key>EntityLogicalName</b:key>"; request += "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + entitySchema + "</b:value>"; request += "</a:KeyValuePairOfstringanyType>"; request += "<a:KeyValuePairOfstringanyType>"; request += "<b:key>LogicalName</b:key>"; request += "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + attributeSchema + "</b:value>"; request += "</a:KeyValuePairOfstringanyType>"; request += "</a:Parameters>"; request += "<a:RequestId i:nil=\"true\" />"; request += "<a:RequestName>RetrieveAttribute</a:RequestName>"; request += "</request>"; request += "</Execute>"; request += "</s:Body></s:Envelope>"; var serverUrl = this.GetServerUrl(); var xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.open("POST", serverUrl + "/XRMServices/2011/Organization.svc" + "/web", mode); xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute"); xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); xmlHttpRequest.setRequestHeader("Content-Length", request.length); xmlHttpRequest.send(request); return xmlHttpRequest; }
相信看到這裏,聰明的你已經會有如此的疑問:不過一個小小的功能,爲啥要用SOAP的方式去獲取選項集的內容?
答案:
其實我也不想的.原先的代碼是直接在窗體加載的時候,去獲取以前定義好的new_post(選項集)的option,可在作完這個以後,發現,在IE8,IE9,Chrome下面,竟然沒效果?
因爲個人系統是win8,故用的是IE10.因此在開發過程當中一直沒發現問題的所在.
琢磨了許久,發現2013在加載控件的時候,首先加載的是一個div層,當你點擊div以後,纔會加載選項集的select.然而,在IE8,IE9,Chrome下面,選項集的select在頁面onload完以後並無立刻出現,而是在onload完以後,大概接近1分鐘後,dom纔會去加載選項集的selec.而IE10卻沒有這樣的狀況.
不得已的狀況下,才採用上面的方式.
另外附上原先的狀況代碼:
1 //表單加載時轉化單選爲多選 2 function ConvertToMultiPicklist(fieldSchema) { 3 4 var picklist = document.getElementById(fieldSchema); 5 var picklistValue = document.getElementById(fieldSchema + "_value").innerText; 6 7 if (picklist != null && picklistValue != null) { 8 9 //step1:獲取原始picklist 10 originalSelectOption = document.getElementById(fieldSchema + "_i"); 11 12 if (originalSelectOption != null && originalSelectOption != undefined) { 13 14 var checkBoxHtml = ""; 15 16 var originalChildCount = originalSelectOption.parentElement.childElementCount; 17 18 var originalSelectOptionClone = originalSelectOption; 19 20 var selectOptionWrap = document.getElementById(fieldSchema + "_d"); 21 22 //step2:移除td下的子節點 23 for (var i = 0; i < selectOptionWrap.childElementCount ; i++) { 24 selectOptionWrap.removeChild(selectOptionWrap.childNodes[0]); 25 } 26 27 28 //↓step3:開始構建多選所需的HTML標籤---begin 29 var divAdd = document.createElement("div"); 30 //divAdd.style.border = "1px solid #f3f1f2"; 31 divAdd.style.paddingTop = "0px"; 32 divAdd.style.paddingRight = "20px"; 33 divAdd.style.paddingBottom = "20px"; 34 divAdd.style.paddingLeft = "0px"; 35 divAdd.style.marginLeft = "15px"; 36 37 var ulAdd = document.createElement("ul"); 38 ulAdd.style.listStyle = "none"; 39 40 for (var i = 1; i < originalSelectOptionClone.childNodes.length; i++) { 41 var checkboxId = "cb_" + fieldSchema + "_" + i; 42 43 var liAdd = document.createElement("li"); 44 liAdd.style.cssFloat = "left"; 45 liAdd.style.display = "block"; 46 liAdd.style.paddingLeft = "5px"; 47 48 var checkboxAdd = document.createElement("input"); 49 checkboxAdd.type = "checkbox"; 50 checkboxAdd.id = checkboxId; 51 checkboxAdd.value = originalSelectOptionClone[i].value; 52 checkboxAdd.style.width = "auto"; 53 checkboxAdd.className = fieldSchema; 54 55 var labelAdd = document.createElement("label"); 56 ////labelAdd.for = checkboxId;// 這樣寫不知爲什麼不起效果 57 ////labelAdd.setAttribute("for", checkboxId); 58 labelAdd.innerText = originalSelectOptionClone[i].text; 59 60 if (picklistValue.indexOf(checkboxAdd.value + ":" + labelAdd.innerText+";")>-1) { 61 checkboxAdd.checked = "checked"; 62 } 63 64 liAdd.appendChild(checkboxAdd); 65 liAdd.appendChild(labelAdd); 66 ulAdd.appendChild(liAdd); 67 68 } 69 70 divAdd.appendChild(ulAdd); 71 selectOptionWrap.appendChild(divAdd); 72 //↑step3:開始構建多選所需的HTML標籤---end 73 74 } 75 } 76 }
3.最後,還須要一個OnSave事件,以下
//表單保存時保存多選值 function SaveMultiPicklist(fieldSchema) { //var checkBoxList = document.getElementsByClassName(fieldSchema); //if (checkBoxList.length <= 0) return; //var saveValues = ""; //for (var i = 0; i < checkBoxList.length; i++) { // if (checkBoxList[i].checked) { // saveValues += checkBoxList[i].value + ":" + checkBoxList[i].nextSibling.innerText + ";"; // } //} //因爲IE8不支持getElemenetsByClassName,故採起下面的方式 2014年1月3日 13:54:44
var saveValues = "";
$("." + fieldSchema).each(function () {
if (this.checked) {
saveValues +=this.value + ":" + this.nextSibling.innerText + ";";
}
});
Xrm.Page.getAttribute(fieldSchema + "_value").setValue(saveValues); }
其中,new_post_value字段保存的文本格式如100000000:密碼修改;100000001:會員註冊;100000002:活動查詢
最後,因爲從vs2012開始,微軟已經在其web項目集成了jQuery,故,在crm2013裏,能夠不引用jQuery類庫了.這個確實很方面.(2013裏集成的jQuery版本爲1.7.2,就如今的版原本說)
最最後,但願以上內容可以幫到看到此文章的各位.同時,如有更好的解決方法,但願能不吝賜教.在此謝過!