我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复378或者20191117可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!
刚开始学的人对于使用JavaScript来做客户端编程可以参考官方文档:Walkthrough: Write your first client script ,Dynamics 365提供了哪些客户端API可以参考 Client API Reference for model-driven apps ,我这里自己也做了个示例,两个选项集字段(省份和城市)的联动效果。当然,对于可选项目很多,容易变化的建议用查找字段(Lookup)来替代。
根据推荐,选项集字段建议使用全局选项集,所以我先创建全局选项集(Global Optionset,选择解决方案中的【选项集】节点后点击右边的【新建】按钮创建的便是全局选项集),示例如下,我这里编码特意用了新的数字,这是为后面演示特别准备的编码(城市编码的前两位和省份编码的前两位相同的则表示这个城市属于这个省份)。我这里建立三个,湖南的编码是430000,湖北的编码是420000,广东的编码是440000。
然后我再创建一个全局选项集-城市,并录入了一些城市,比如长沙(430100),株洲市(430200),广州市(440100),深圳市(440300),武汉市(420100)等等。
我再在实体中新建两个选项集字段,分别使用这两个选项集,并将其放置到表单上并发布更改。
默认情况下,这两个字段可以选择任何值,比如我可以选择广东省,长沙市,这个是不合理的,需要让其只能选择省下面的城市。
首先我将城市字段在表单(Form)界面上设置默认为只读(不可编辑),我让其等待选择了省份字段后再解锁可以编辑,如下:
然后我撰写如下代码,每个代码行为了初学者我都做了注释。
//定义命名空间,我一般用项目统一前缀加上实体去掉前缀后的架构名称(每个单词首字母大写) var LuoYongWorkOrder = window.LuoYongWorkOrder || {}; (function () { //表单上省份字段的OnChange事件处理函数,记得第一个参数用来接受传递过来的executionContext this.ProvinceOnChange = function (executionContext) { var formContext = executionContext.getFormContext(); //获取省份字段改变后的新值 var provinceValue = formContext.getAttribute("ly_province").getValue(); //将城市字段的值设置为空值 formContext.getAttribute("ly_city").setValue(null); //将城市字段设置为可以更改,表单上已经设置该字段为只读 formContext.getControl("ly_city").setDisabled(false); //获取城市字段的所有可用选项信息 var cityValidOptions = formContext.getAttribute("ly_city").getOptions(); //获取城市字段的现在可选的选项信息(用formContext.getControl(arg).removeOption(value)移除的选项不会包括在本结果中) var cityCurrentOptions = formContext.getControl("ly_city").getOptions(); //城市是否展示给用户可以选择 var cityIsExist = false; cityValidOptions.forEach( function (element) { cityIsExist = false; cityCurrentOptions.forEach(function (ele){ if (element.value == ele.value) { cityIsExist = true;//城市展示给用户可以选择 } }); //如果这个城市需要显示在可选列表中 if (element.value >= provinceValue && element.value < provinceValue + 10000) { if (!cityIsExist) {//如果没有显示需要将其添加进来显示 formContext.getControl("ly_city").addOption({"value":element.value,"text":element.text}); } } else {//这个城市不需要显示在可选列表中 if (cityIsExist) {//如果已经显示,需要将其移除 formContext.getControl("ly_city").removeOption(element.value); } } console.log(element); } ); } }).call(LuoYongWorkOrder);
我再在解决方案中新建一个Web 资源,名称需要在整个组织的Web资源名称中唯一,我一般定义一个命名规范,一般是 /{实体去掉前缀后的逻辑名称}/js/{实体去掉前缀后的逻辑名称}{form|ribbon}.js,方便知道这个是给哪个实体用的,是用于表单编程的,还是命令栏的,用 / 符号来构建相对路径。显示名称我一般和我建立的实际文件名称保持一致。类型选择 脚本(JScript) ,语言可以选可以不选,然后点击选择文件(Choose File)按钮选择自己的JavaScript文件,保存后发布。
再打开工单实体窗体类型为【主要】的窗体,点击Ribbon区的【窗体属性】按钮。
点击【添加】按钮。
选择前面步骤创建的Web资源后点击【确定】按钮关闭,我这里不涉及到在窗体的【OnLoad】或者【OnSave】事件执行我撰写的代码。
然后需要为表单上的省份字段关联字段值变更后执行的代码,双击表单上的【省份】字段(或者选择【省份】字段后点击Ribbon区的【更改属性】按钮),在打开的【字段属性】窗口中,切换到【事件】这个Tab,默认事件是OnChange,刚好是我需要的,所以不需要更改,直接点击【添加】按钮。
设置如下,库选择我们前面步骤上传的Web资源,函数我这里输入LuoYongWorkOrder.ProvinceOnChange,记得【将执行上下文作为第一个参数传递】这个选项勾选,然后点击【确定】按钮关闭,保存并发布,刷新工单实体的表单页面(F5或者使用强制刷新Ctrl+F5) 就可以测试了。
我测试了一下,实现了选项集的联动。