示例:创建从属选项集(选择列表)
发布日期: 2016年11月
适用于: Dynamics CRM 2015
通常要求一个选项集字段中的值由另一个选项集字段中选择的值进行筛选。 本主题介绍通过可重复使用的 JScript 库、窗体事件和 XML Web 资源实现此要求的方法。
若要观察和核实这个示例的功能,您可从 SDK 下载中的以下位置安装 DependentOptionSetsSample_1_0_0_2_managed.zip 托管解决方案:SDK\SampleCode\JS\FormScripts
下载 Microsoft Dynamics CRM SDK 包。
此解决方案的目标
此解决方案旨在满足以下要求:
它提供可用于任何选项集字段对的常规、可重复使用 JScript 库。
它可用于相关选项集字段链。 由于每个相关选项集字段选项都根据另一个字段的值进行筛选,因此可通过在第一个相关选项集字段中选择的选项来筛选其他选项集字段选项。 这样便可用于一组在层次结构上相关的选项集字段。
相关选项的筛选在 XML Web 资源中设置。 这样便可更改选项映射,无需更改代码。 编辑 XML Web 资源对于配置选项且很少会破坏代码的非开发人员而言更为容易。
该解决方案支持多种语言。 筛选仅基于选项的数据值,而不是选项中的任何文本。
筛选适用于窗体上任意数量的属性控件实例。
示例
本节介绍此方法的应用以及应用示例库的过程。
票证 (sample_ticket) 实体窗体有三个选项集字段以及允许对产品分类的选项。 下表显示选项集选项的所需筛选。
类别 (sample_category) |
子类别 (sample_subcategory) |
类型 (sample_type) |
---|---|---|
值:727000000 标签:软件 |
值:727000000 标签:个人生产力 |
值:727000000 标签:文字处理软件 |
值:727000001 标签:电子表格 |
||
值:727000002 标签:Internet 浏览器 |
||
值:727000003 标签:电子邮件 |
||
值:727000001 标签:商业应用程序 |
值:727000004 标签:客户关系管理 |
|
值:727000005 标签:企业资源管理 |
||
值:727000006 标签:人力资源管理 |
||
值:727000002 标签:操作系统 |
值:727000007 标签:Windows Vista |
|
值:727000008 标签:Windows 7 |
||
值:727000009 标签:Windows Server 2003 |
||
值:727000010 标签:Windows Server 2008 |
||
值:727000001标签:硬件 |
值:727000003 标签:台式计算机 |
值:727000011 标签:工作站 x1000 |
值:727000012 标签:工作站 x2000 |
||
值:727000013 标签:工作站 x3000 |
||
值:727000014 标签:工作站 x4000 |
||
值:727000004 标签:便携式计算机 |
值:727000015 标签:便携式计算机 1000 系列 |
|
值:727000016 标签:便携式计算机 2000 系列 |
||
值:727000017 标签:便携式计算机 3000 系列 |
||
值:727000018 标签:便携式计算机 4000 系列 |
||
值:727000005 标签:显示器 |
值:727000019 标签: CRT-XYZ 17 英寸 |
|
值:727000020 标签:LCD-XYZ 17 英寸 |
||
值:727000021 标签:LCD-XYZ 21 英寸 |
||
值:727000022 标签:LCD-XYZ 24 英寸 |
||
值:727000006 标签:打印机 |
值:727000023 标签:系列 1000 打印机 - 专用 |
|
值:727000024 标签:系列 2000 色彩打印机 - 专用 |
||
值:727000025 标签:系列 9000 打印机 - 专用 |
||
值:727000026 标签:系列 9000 色彩打印机 - 公用 |
||
值:727000007 标签:电话 |
值:727000027 标签:PSTN 电话 |
|
值:727000028 标签:IP 电话 |
||
值:727000029 标签:移动电话 |
启用筛选
将所需的选项筛选转换为以下 XML 文档并将其作为 XML Web 资源上传,标题为 sample_TicketDependentOptionSetConfig.xml。 包括标签值是为了使文档更易于编辑,但标签值不用在筛选选项的脚本中。
<DependentOptionSetConfig entity="sample_ticket" > <ParentField id="sample_category" label="Category"> <DependentField id="sample_subcategory" label="Sub Category" /> <Option value="727000000" label="Software"> <ShowOption value="727000000" label="Personal Productivity" /> <ShowOption value="727000001" label="Business Applications" /> <ShowOption value="727000002" label="Operating Systems" /> </Option> <Option value="727000001" label="Hardware"> <ShowOption value="727000003" label="Desktop Computer" /> <ShowOption value="727000004" label="Laptop Computer" /> <ShowOption value="727000005" label="Monitor" /> <ShowOption value="727000006" label="Printer" /> <ShowOption value="727000007" label="Telephone" /> </Option> </ParentField> <ParentField id="sample_subcategory" label="Sub Category"> <DependentField id="sample_type" label="Type" /> <Option value="727000000" label="Personal Productivity"> <ShowOption value="727000000" label="Word Processor" /> <ShowOption value="727000001" label="Spreadsheet" /> <ShowOption value="727000002" label="Internet Browser" /> <ShowOption value="727000003" label="E-mail" /> </Option> <Option value="727000001" label="Business Applications"> <ShowOption value="727000004" label="Customer Relationship Management" /> <ShowOption value="727000005" label="Enterprise Resource Management" /> <ShowOption value="727000006" label="Human Resource Managment" /> </Option> <Option value="727000002" label="Operating Systems"> <ShowOption value="727000007" label="Windows Vista" /> <ShowOption value="727000008" label="Windows 7" /> <ShowOption value="727000009" label="Windows Server 2003" /> <ShowOption value="727000010" label="Windows Server 2008" /> </Option> <Option value="727000003" label="Desktop Computer"> <ShowOption value="727000011" label="Workstation x1000" /> <ShowOption value="727000012" label="Workstation x2000" /> <ShowOption value="727000013" label="Workstation x3000" /> <ShowOption value="727000014" label="Workstation x4000" /> </Option> <Option value="727000004" label="Laptop Computer"> <ShowOption value="727000015" label="Laptop 1000 series" /> <ShowOption value="727000016" label="Laptop 2000 series" /> <ShowOption value="727000017" label="Laptop 3000 series" /> <ShowOption value="727000018" label="Laptop 4000 series" /> </Option> <Option value="727000005" label="Monitor"> <ShowOption value="727000019" label="CRT-XYZ 17 inch" /> <ShowOption value="727000020" label="LCD-XYZ 17 inch" /> <ShowOption value="727000021" label="LCD-XYZ 21 inch" /> <ShowOption value="727000022" label="LCD-XYZ 24 inch" /> </Option> <Option value="727000006" label="Printer"> <ShowOption value="727000023" label="Series 1000 Printer - Private" /> <ShowOption value="727000024" label="Series 2000 Color Printer - Private" /> <ShowOption value="727000025" label="Series 9000 Printer - Shared" /> <ShowOption value="727000026" label="Series 9000 Color Printer - Shared" /> </Option> <Option value="727000007" label="Telephone"> <ShowOption value="727000027" label="PSTN Phone" /> <ShowOption value="727000028" label="IP Phone" /> <ShowOption value="727000029" label="Mobile Phone" /> </Option> </ParentField> </DependentOptionSetConfig>
使用以下代码创建一个名为 sample_SDK.DependentOptionSetSample.js 的 JScript Web 资源。
//If the SDK namespace object is not defined, create it. if (typeof (SDK) == "undefined") { SDK = {}; } // Create Namespace container for functions in this library; SDK.DependentOptionSet = {}; SDK.DependentOptionSet.init = function (webResourceName) { //Retrieve the XML Web Resource specified by the parameter passed var clientURL = Xrm.Page.context.getClientUrl(); var pathToWR = clientURL + "/WebResources/" + webResourceName; var xhr = new XMLHttpRequest(); xhr.open("GET", pathToWR, true); xhr.setRequestHeader("Content-Type", "text/xml"); xhr.onreadystatechange = function () { SDK.DependentOptionSet.completeInitialization(xhr); }; xhr.send(); }; SDK.DependentOptionSet.completeInitialization = function (xhr) { if (xhr.readyState == 4 /* complete */) { if (xhr.status == 200) { xhr.onreadystatechange = null; //avoids memory leaks var JSConfig = []; var ParentFields = xhr.responseXML.documentElement.getElementsByTagName("ParentField"); for (var i = 0; i < ParentFields.length; i++) { var ParentField = ParentFields[i]; var mapping = {}; mapping.parent = ParentField.getAttribute("id"); mapping.dependent = SDK.Util.selectSingleNode(ParentField, "DependentField").getAttribute("id"); mapping.options = []; var options = SDK.Util.selectNodes(ParentField, "Option"); for (var a = 0; a < options.length; a++) { var option = {}; option.value = options[a].getAttribute("value"); option.showOptions = []; var optionsToShow = SDK.Util.selectNodes(options[a], "ShowOption"); for (var b = 0; b < optionsToShow.length; b++) { var optionToShow = {}; optionToShow.value = optionsToShow[b].getAttribute("value"); optionToShow.text = optionsToShow[b].getAttribute("label"); option.showOptions.push(optionToShow); } mapping.options.push(option); } JSConfig.push(mapping); } //Attach the configuration object to DependentOptionSet //so it will be available for the OnChange events SDK.DependentOptionSet.config = JSConfig; //Fire the onchange event for the mapped optionset fields // so that the dependent fields are filtered for the current values. for (var depOptionSet in SDK.DependentOptionSet.config) { var parent = SDK.DependentOptionSet.config[depOptionSet].parent; Xrm.Page.data.entity.attributes.get(parent).fireOnChange(); } } } }; // This is the function set on the onchange event for // parent fields SDK.DependentOptionSet.filterDependentField = function (parentField, childField) { for (var depOptionSet in SDK.DependentOptionSet.config) { var DependentOptionSet = SDK.DependentOptionSet.config[depOptionSet]; /* Match the parameters to the correct dependent optionset mapping*/ if ((DependentOptionSet.parent == parentField) && (DependentOptionSet.dependent == childField)) { /* Get references to the related fields*/ var ParentField = Xrm.Page.data.entity.attributes.get(parentField); var ChildField = Xrm.Page.data.entity.attributes.get(childField); /* Capture the current value of the child field*/ var CurrentChildFieldValue = ChildField.getValue(); /* If the parent field is null the Child field can be set to null */ if (ParentField.getValue() == null) { ChildField.setValue(null); ChildField.setSubmitMode("always"); ChildField.fireOnChange(); // Any attribute may have any number of controls // So disable each instance var controls = ChildField.controls.get() for (var ctrl in controls) { controls[ctrl].setDisabled(true); } return; } for (var os in DependentOptionSet.options) { var Options = DependentOptionSet.options[os]; var optionsToShow = Options.showOptions; /* Find the Options that corresponds to the value of the parent field. */ if (ParentField.getValue() == Options.value) { var controls = ChildField.controls.get(); /*Enable the field and set the options*/ for (var ctrl in controls) { controls[ctrl].setDisabled(false); controls[ctrl].clearOptions(); for (var option in optionsToShow) { controls[ctrl].addOption(optionsToShow[option]); } } /*Check whether the current value is valid*/ var bCurrentValueIsValid = false; var ChildFieldOptions = optionsToShow; for (var validOptionIndex in ChildFieldOptions) { var OptionDataValue = ChildFieldOptions[validOptionIndex].value; if (CurrentChildFieldValue == OptionDataValue) { bCurrentValueIsValid = true; break; } } /* If the value is valid, set it. If not, set the child field to null */ if (bCurrentValueIsValid) { ChildField.setValue(CurrentChildFieldValue); } else { ChildField.setValue(null); } ChildField.setSubmitMode("always"); ChildField.fireOnChange(); break; } } } } }; SDK.Util = {}; //Helper methods to merge differences between browsers for this sample SDK.Util.selectSingleNode = function (node, elementName) { if (typeof (node.selectSingleNode) != "undefined") { return node.selectSingleNode(elementName); } else { return node.getElementsByTagName(elementName)[0]; } }; SDK.Util.selectNodes = function (node, elementName) { if (typeof (node.selectNodes) != "undefined") { return node.selectNodes(elementName); } else { return node.getElementsByTagName(elementName); } };
将该 sample_SDK.DependentOptionSetSample.js 脚本 Web 资源添加到可供窗体使用的 JScript 库中。
在窗体的 Onload 事件中,配置事件处理程序,以调用 SDK.DependentOptionSet.init 函数,并将 XML Web 资源的名称作为参数来传入。 使用“处理程序属性”对话框上的字段输入:"sample_TicketDependentOptionSetConfig.xml" 至字段“将传入函数的参数逗号分隔列表”。
在“类别”字段的 OnChange 事件中,将“函数”设置为 SDK.DependentOptionSet.filterDependentField。
在“将传入函数的参数逗号分隔列表”文本框中输入:"sample_category", "sample_subcategory"。
在“子类别”字段的 OnChange 事件中,将“函数”设置为 SDK.DependentOptionSet.filterDependentField。
在“将传入函数的参数逗号分隔列表”文本框中输入:"sample_subcategory ", "sample_type"。
保存并发布所有自定义设置。
另请参阅
使用 Xrm.Page 对象模型
为 Microsoft Dynamics CRM 2015 窗体编写代码
通过 Microsoft Dynamics CRM 2015 使用 JavaScript
自定义实体窗体
Xrm.Page.data. 实体属性(客户端引用)
Xrm.Page.ui 控制方法(客户端引用)
© 2017 Microsoft。 保留所有权利。 版权