我是微軟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) 就可以測試了。
我測試了一下,實現了選項集的聯動。