샘플: 종속 OptionSets(선택 목록) 만들기
게시 날짜: 2016년 11월
적용 대상: Dynamics CRM 2015
한 옵션 집합 필드의 값을 다른 옵션 집합 필드에서 선택한 값으로 필터링해야 하는 일반적인 요구 사항입니다. 이 항목에서는 재사용 가능한 JScript 라이브러리, 양식 이벤트 및 XML 웹 리소스로 이 작업을 수행하는 한 가지 방법에 대해 설명합니다.
이 샘플의 기능을 관찰하고 확인하기 위해 SDK 다운로드 SDK\SampleCode\JS\FormScripts에서 DependentOptionSetsSample_1_0_0_2_managed.zip 관리형 솔루션을 설치할 수 있습니다.
Microsoft Dynamics CRM SDK 패키지를 다운로드합니다.
이 솔루션에 대한 목표
이 솔루션 다음 요구 사항을 충족하기 위한 것입니다.
옵션 집합 필드 쌍에 사용할 수 있는 일반적인 재사용 가능한 JScript 라이브러리를 제공합니다.
종속 옵션 집합 필드의 체인을 사용할 수 있습니다. 각 종속 옵션 집합 필드 옵션은 다른 필드의 값에 따라 필터링되므로 추가 옵션 집합 필드 옵션은 첫 번째 종속 옵션 집합 필드에서 선택한 옵션으로 필터링할 수 있습니다. 계층 구조적으로 종속 옵션 집합 필드 집합일 가능성이 있습니다.
종속 옵션의 필터링은 XML 웹 리소스에 설정됩니다. 따라서 코드를 변경하지 않고 옵션 매핑을 변경할 수 있습니다.XML 웹 리소스 편집은 적은 기회로 비개발자가 옵션을 구성하여 코드를 풀기 더 쉽습니다.
솔루션은 여러 언어를 지원합니다. 필터링은 옵션의 텍스트 보다는 전적으로 옵션의 데이터 값에 따라 달라집니다.
필터링은 양식에서 특성 컨트롤의 인스턴스에 대해 작동합니다.
예제
이 섹션에서는 이 방법의 한 응용 프로그램과 샘플 라이브러리를 적용할 프로시저에 대해 설명합니다.
Ticket(sample_ticket) 엔터티 양식에는 세 가지 옵션 집합 필드와 제품 분류를 허용하는 옵션이 있습니다. 다음 표는 옵션 집합 옵션의 원하는 필터링을 보여 줍니다.
범주 (sample_category) |
하위 범주 (sample_subcategory) |
유형 (sample_type) |
---|---|---|
값:727000000 레이블: 소프트웨어 |
값:727000000 레이블: 개인 생산성 |
값:727000000 레이블: 워드 프로세서 |
값:727000001 레이블: 스프레드시트 |
||
값:727000002 레이블: 인터넷 브라우저 |
||
값:727000003 레이블: 전자 메일 |
||
값:727000001 레이블: 비즈니스 응용 프로그램 |
값:727000004 레이블: 고객 관계 관리 |
|
값:727000005 레이블: 기업 자원 관리 |
||
값:727000006 레이블: 기업 자원 관리 |
||
값:727000002 레이블: 운영 체제 |
값:727000007 레이블: Windows Vista |
|
값:727000008 레이블: Windows 7 |
||
값:727000009 레이블: Windows Server 2003 |
||
값:727000010 레이블: Windows Server 2008 |
||
값:727000001 레이블: 하드웨어 |
값:727000003 레이블: 데스크톱 컴퓨터 |
값:727000011 레이블: 워크스테이션 x 1000 |
값:727000012 레이블: 워크스테이션 x 2000 |
||
값:727000013 레이블: 워크스테이션 x 3000 |
||
값:727000014 레이블: 워크스테이션 x 4000 |
||
값:727000004 레이블: 랩톱 컴퓨터 |
값:727000015 레이블: 랩톱 1000시리즈 컴퓨터 |
|
값:727000016 레이블: 랩톱 2000시리즈 |
||
값:727000017 레이블: 랩톱 3000 시리즈 |
||
값:727000018 레이블: 랩톱 4000 시리즈 |
||
값:727000005 레이블: 모니터 |
값:727000019 레이블: CRT-XYZ 17 인치 |
|
값:727000020 레이블: LCD-XYZ 17인치 |
||
값:727000021 레이블: LCD-XYZ 21인치 |
||
값:727000022 레이블: LCD-XYZ24인치 |
||
값:727000006 레이블: 프린터 |
값:727000023 레이블:시리즈 1000 프린터 - 개인 |
|
값:727000024 레이블: 시리즈 2000 컬러 프린터 - 개인 |
||
값:727000025 레이블: 시리즈 9000 프린터 - 공유 |
||
값:727000026 레이블: 시리즈 9000 컬러 프린터 - 공유 |
||
값:727000007 레이블: 전화 |
값:727000027 레이블: PSTN 전화 |
|
값:727000028 레이블: IP 전화 |
||
값:727000029 레이블: 휴대폰 |
필터링 활성화
옵션의 원하는 필터링을 다음 XML 문서로 변환하고 sample_TicketDependentOptionSetConfig.xml이라는 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 웹 리소스를 만듭니다.
//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 스크립트 웹 리소스를 양식에 대해 사용할 수 있는 JScript 라이브러리에 추가합니다.
양식에 대한 Onload 이벤트에서 이벤트 처리기를 구성하여 SDK.DependentOptionSet.init 함수를 호출하고 매개 변수로 XML 웹 리소스의 이름에 전달합니다.처리기 속성 대화 상자에서 필드를 사용하여 "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.entity 특성(클라이언트 쪽 참조)
Xrm.Page.ui 컨트롤(클라이언트 쪽 참조)
© 2017 Microsoft. All rights reserved. 저작권 정보