• Microsoft Dynamics CRM 2013 --选项集的多选


    由于从Microsoft Dynamics CRM 2011到Microsoft Dynamics CRM 2013,界面的风格发生了很大的变化

    故原先在2011上开发的选项集多选在2013上面已经不再适用.

    一直想不明白的是,微软为啥还不支持选项集的多选呢?

    折腾的一番,具体效果如下,但还有很多不满意的地方,希望有兴趣的,或者已经做过类似功能的各位,提供下宝贵的意见,不甚感激!

    具体使用步骤如下:

    1.创建选项集字段,文本型字段各一个

      本文使用的字段名分别为:new_post(选项集),new_post_value(保存多选值的文本型字段)

    2.在窗体的OnLoad事件中添加ConvertToMultiPicklist事件,详细代码如下

    //表单加载时转化单选为多选
    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="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)

    //内部函数 获取属性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,就现在的版本来说)

    最最后,希望以上内容能够帮到看到此文章的各位.同时,若有更好的解决方法,希望能不吝赐教.在此谢过!

  • 相关阅读:
    js中两种定时器,setTimeout和setInterval的区别
    简单说 JavaScript实现雪花飘落效果
    CSS 浮动 float 属性
    使用jQuery做简单的图片轮播效果
    DIV+CSS中标签dl dt dd常用的用法
    CSS display的几个常用的属性值,inline , block, inline-block
    Confluence代码块(Code Block)宏
    salt总结
    快速搭建rabbitmq单节点并配置使用
    使用python脚本配置zabbix发送报警邮件
  • 原文地址:https://www.cnblogs.com/gnile/p/3429909.html
Copyright © 2020-2023  润新知