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
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>
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) && (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); } };
Agregue el recurso web del Script sample_SDK.DependentOptionSetSample.js a las bibliotecas de JScript disponibles para el formulario.
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.
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".
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".
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