Microsoft Dynamics CRM 2013 --選項集的多選

因爲從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,就如今的版原本說)

最最後,但願以上內容可以幫到看到此文章的各位.同時,如有更好的解決方法,但願能不吝賜教.在此謝過!

相關文章
相關標籤/搜索