サンプル: 依存オプション セット (候補リスト) の作成

 

公開日: 2016年11月

対象: Dynamics CRM 2015

あるオプション セット フィールドの値を、別のオプション セット フィールドで選択された値によってフィルター処理するという一般的な要件があります。 このトピックでは、再利用可能な JScript ライブラリ、フォーム イベント、および XML Web リソースを使用して、これを実現する 1 つの方法を説明します。

このサンプルの機能を監視および確認するために、SDK のダウンロードの場所 DependentOptionSetsSample_1_0_0_2_managed.zip から SDK\SampleCode\JS\FormScripts 管理ソリューションをインストールできます。

Microsoft Dynamics CRM SDK パッケージをダウンロードします。

この解決方法の目標

この解決方法の目的は次の要件を満たすことです。

  • オプション セット フィールドの任意のペアに対して使用できる、汎用の再利用可能 JScript ライブラリを提供します。

  • 依存オプション セット フィールドの連鎖に対応できます。 各依存オプション セット フィールドのオプションは、別のフィールドの値に基づいてフィルター処理されるため、さらに他のオプション セット フィールドのオプションが、最初の依存オプション セット フィールドで選択されたオプションによってフィルター処理される可能性があります。 階層的な依存関係がある一連のオプション セット フィールドに対応できます。

  • 依存オプションのフィルター処理は、XML Web リソースで設定されます。 こうすることで、コードを変更せずにオプションのマッピングを変更できます。XML Web リソースの編集は、開発者以外でもオプションの構成を容易に行うことができ、コードを破損する可能性が高くありません。

  • この解決方法では複数の言語がサポートされます。 フィルター処理は、オプションのテキストではなくデータ値のみに基づきます。

  • フィルター処理は、フォームにおける 1 つの属性コントロールのいくつのインスタンスに対しても機能します。

このセクションでは、この方法の 1 つの適用例とサンプル ライブラリの適用手順について説明します。

Ticket (sample_ticket) エンティティ フォームには、製品を分類するための 3 つのオプション セット フィールドとオプションがあります。 以下の表に、オプション セットのオプションで必要なフィルター処理を示します。

カテゴリ

(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 ラベル: Workstation x1000

値:727000012 ラベル: Workstation x2000

値:727000013 ラベル: Workstation 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 ラベル: Series 1000 Printer - Private

値: 727000024 ラベル: Series 2000 プリンター - 個人用

値:727000025 ラベル: Series 9000 プリンター - 個人用

値:727000026 ラベル: Series 9000 カラー プリンター - 共用

値:727000007 ラベル: 電話

値:727000027 ラベル: 公衆電話

値:727000028 ラベル: IP 電話

値:727000029 ラベル: モバイル電話

フィルター処理を有効にする

  1. オプションの必要なフィルター処理を次の XML ドキュメントに変換し、sample_TicketDependentOptionSetConfig.xml という名前の XML Web リソースとしてアップロードします。 ラベル値は、ドキュメントを編集しやすくするために含まれていますが、オプションをフィルター処理するスクリプトでは使用されません。

    
    <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>
    
  2. 次のコードを使用して、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) &amp;&amp; (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);
      }
     };
    
  3. sample_SDK.DependentOptionSetSample.js スクリプト Web リソースを、フォームで使用できる JScript ライブラリに追加します。

  4. フォームの Onload イベントで、イベント ハンドラーが SDK.DependentOptionSet.init 関数を呼び出して、XML Web リソースの名前をパラメーターとして渡すように構成します。[ハンドラのプロパティ] ダイアログ ボックスのフィールドを使用して、"sample_TicketDependentOptionSetConfig.xml" を [関数に渡されるパラメーターのコンマ区切り一覧] フィールドに入力します。

  5. [カテゴリ] フィールドの OnChange イベントで、[関数]SDK.DependentOptionSet.filterDependentField に設定します。

    [関数に渡されるパラメーターのコンマ区切り一覧] テキスト ボックスに、"sample_category", "sample_subcategory" を入力します。

  6. [サブ カテゴリ] フィールドの OnChange イベントで、[関数]SDK.DependentOptionSet.filterDependentField. に設定します。

    [関数に渡されるパラメーターのコンマ区切り一覧] テキスト ボックスに、"sample_subcategory ", "sample_type" を入力します。

  7. すべてのカスタマイズを保存し、公開します。

関連項目

Xrm.Page オブジェクト モデルの使用
Microsoft Dynamics CRM 2015 フォームのコードを記述する
Microsoft Dynamics CRM 2015 での JavaScript の使用
エンティティ フォームのカスタマイズ
Xrm.Page.data.entity 属性 (クライアント側の参照)
Xrm.Page.ui コントロール (クライアント側の参照)

© 2017 Microsoft. All rights reserved. 著作権