Share via


Ejemplo: crear OptionSets (listas desplegables) dependientes

 

Publicado: noviembre de 2016

Se aplica a: Dynamics CRM 2015

Es un requisito común que los valores de un campo de conjunto de opciones se tengan que filtrar según un valor seleccionado de otro campo de conjunto de opciones. Este tema describe un método para hacerlo con una biblioteca de JScript reutilizable, eventos de formulario y un recurso web XML.

Para respetar y comprobar la funcionalidad de este ejemplo puede instalar la solución administrada de DependentOptionSetsSample_1_0_0_2_managed.zip desde la siguiente ubicación en la descarga de SDK: SDK\SampleCode\JS\FormScripts

Descargue el paquete de SDK de Microsoft Dynamics CRM.

Objetivos de esta solución

Esta solución está diseñada para cumplir los siguientes requisitos:

  • Proporciona una biblioteca genérica y reutilizable de JScript que se puede usar para cualquier par de campos de conjunto de opciones.

  • Permite una cadena de campos de conjunto de opciones dependientes. Dado que las opciones de cada campo de conjunto de opciones dependiente se filtran en función del valor de otro campo, se pueden filtrar opciones adicionales de campos de conjunto de opciones según la opción elegida en el primer campo de conjunto de opciones dependiente. Esto permite la posibilidad de un conjunto de campos de conjunto de opciones dependiente jerárquicamente.

  • El filtrado de las opciones dependientes se encuentra en un recurso web XML. Esto permite cambiar las asignaciones de opción sin modificar el código. Es más sencillo para los usuarios que no sean desarrolladores editar un recurso web XML para configurar las opciones con menos posibilidad de interrumpir el código.

  • La solución es compatible con varios idiomas. El filtrado se basa en solo el valor de los datos de las opciones en lugar del texto de las opciones.

  • El filtrado funciona para cualquier número de instancias de un control de atributo del formulario.

Ejemplo

Esta sección describe una aplicación de este enfoque y el procedimiento para aplicar la biblioteca de ejemplo.

El formulario de entidad de Vale (sample_ticket) tiene tres campos de conjunto de opciones que permiten la clasificación de los productos. La siguiente tabla muestra el filtrado deseado para las opciones del conjunto de opciones.

Categoría

(sample_category)

Subcategoría

(sample_subcategory)

Tipo

(sample_type)

Valor:727000000 Etiqueta: Software

Valor:727000000 Etiqueta: Productividad personal

Valor:727000000 Etiqueta: Procesador de texto

Valor:727000001 Etiqueta: Hoja de cálculo

Valor:727000002 Etiqueta: Explorador de Internet

Valor:727000003 Etiqueta: Correo electrónico

Valor:727000001 Etiqueta: Aplicaciones empresariales

Valor:727000004 Etiqueta: Administración de relaciones con el cliente

Valor:727000005 Etiqueta: Administración de recursos de empresas

Valor:727000006 Etiqueta: Administración de recursos humanos

Valor:727000002 Etiqueta: Sistemas operativos

Valor:727000007 Etiqueta: Windows Vista

Valor:727000008 Etiqueta: Windows 7

Valor:727000009 Etiqueta: Windows Server 2003

Valor:727000010 Etiqueta: Windows Server 2008

Valor:727000001 Etiqueta: Hardware

Valor:727000003 Etiqueta: Equipo de escritorio

Valor:727000011 Etiqueta: Estación de trabajo x1000

Valor:727000012 Etiqueta: Estación de trabajo x2000

Valor:727000013 Etiqueta: Estación de trabajo x3000

Valor:727000014 Etiqueta: Estación de trabajo x4000

Valor:727000004 Etiqueta: Equipo portátil

Valor:727000015 Etiqueta: Portátil serie 1000

Valor:727000016 Etiqueta: Portátil serie 2000

Valor:727000017 Etiqueta: Portátil serie 3000

Valor:727000018 Etiqueta: Portátil serie 4000

Valor:727000005 Etiqueta: Monitor

Valor:727000019 Etiqueta: CRT-XYZ de 17 pulgadas

Valor:727000020 Etiqueta: LCD-XYZ de 17 pulgadas

Valor:727000021 Etiqueta: LCD-XYZ de 21 pulgadas

Valor:727000022 Etiqueta: LCD-XYZ de 24 pulgadas

Valor:727000006 Etiqueta: Impresora

Valor:727000023 Etiqueta:Impresora serie 1000 - Privada

Valor:727000024 Etiqueta: Impresora color serie 2000 - Privada

Valor:727000025 Etiqueta: Impresora serie 9000 - Compartida

Valor:727000026 Etiqueta: Impresora color serie 9000 - Compartida

Valor:727000007 Etiqueta: Teléfono

Valor:727000027 Etiqueta: Teléfono RTC

Valor:727000028 Etiqueta: Teléfono IP

Valor:727000029 Etiqueta: Teléfono móvil

Habilitar el filtrado

  1. Convierta el filtrado de opciones deseado en el documento XML siguiente y cárguelo como un recurso web XML titulado sample_TicketDependentOptionSetConfig.xml. Los valores de etiqueta se incluyen para que el documento sea más fácil de editar pero no se usan en el script que filtra las opciones.

    
    <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. Cree un recurso web de JScript llamado sample_SDK.DependentOptionSetSample.js con el siguiente código.

    
    
    //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. Agregue el recurso web del Script sample_SDK.DependentOptionSetSample.js a las bibliotecas de JScript disponibles para el formulario.

  4. En el evento Onload del formulario, configure el controlador de eventos para llamar a la función SDK.DependentOptionSet.init y pasarle el nombre del recurso web XML como parámetro. Use el campo en el cuadro de diálogo Propiedades del controlador para introducir: "sample_TicketDependentOptionSetConfig.xml" en el campo Lista de parámetros separados por coma que se transmitirá a la función.

  5. En el evento OnChange del campo Categoría, establezca Función en SDK.DependentOptionSet.filterDependentField.

    En el cuadro de texto Lista de parámetros separados por coma que se transmitirá a la función introduzca: "sample_category", "sample_subcategory".

  6. En el evento OnChange del campo Subcategoría, establezca la Función en SDK.DependentOptionSet.filterDependentField.

    En el cuadro de texto Lista de parámetros separados por coma que se transmitirá a la función introduzca: "sample_subcategory ", "sample_type".

  7. Guarde y publique todas las personalizaciones.

Ver también

Use el modelo de objeto Xrm.Page
Escriba código para formularios de Microsoft Dynamics CRM 2015
Uso de JavaScript con Microsoft Dynamics CRM 2015
Personalizar los formularios de entidad
Atributo Xrm.Page.data.entity (referencia de cliente)
Control Xrm.Page.ui (referencia de cliente)

© 2017 Microsoft. Todos los derechos reservados. Copyright