lunes, 11 de junio de 2012

Javascript: Formulario dinámico desde Web Resource (DynamicForm 1.0)

Hola, partiendo de la base de mi último post en donde ocultábamos campos de forma declarativa desde un XML y dinámica dependiendo de un valor seleccionado de un desplegable, he decidido avanzar con la misma idea para crear una especie de componente algo mas “robusto”. Al que he llamado “DynamicForm”.
La idea sigue siendo la misma que planteé aquella vez, pero con mas opciones.
El resumen de la funcionalidad propuesta hoy es el siguiente:
Formulario: Cuenta
Evento: OnLoad() y OnChange()
Atributos: para este ejemplo, el desplegable de Categoría.
Funcionalidad: La idea es que dependiendo del valor de un desplegable, se realicen acciones en el formulario, como ocultar campos, secciones, o tabs y cambiar el nivel de requerimiento de campos. Está lógica se define en un Web Resource en formato XML.
Todo este ejemplo estará como siempre disponible en Codeplex:
http://elblogdedynamicscrm.codeplex.com/documentation
Para estas nuevas funcionalidades, he tenido que hacer el XML de configuración, algo mas completo:

    
    

Básicamente, los atributos del xml quedaría definido así:


  • name: nombre del campo que definirá el “disparo” de las acciones


  • value: valor del campo que definirá el disparo de las acciones


  • showattributes/hideattributes: define los campos a mostrar/ocultar, separados por comas (,).


  • showsections/hidesections: para introducir las secciones a ocultar/mostrar. para esto se debe añadir con el formato “nombre_tab/nombre_sección” además de poder añadir varias secciones separadas por comas (,).


  • showtabs/hidetabs: para añadir nombres de tabs o pestañas a ocultar/mostrar


  • setrequiredlevel: para modificar el nivel de requerimiento de uno o varios campos, separados por comas (,). El formato es el siguiente: “required|recommended|none:campo1-campo2-campo3”


Bien, una vez definido y explicado el tema del xml con las acciones que queremos disparar, veamos como nos queda el código javascript, algo mas largo, pero lo he ordenado algo mejor:


/*
DynamicForm method.
*/
function DynamicForm()
{
   LoadXmlWebResource("new_test_xml");
   
   var nodePath = "//attributes/attribute";
   var nodelist = doc.selectNodes(nodePath);
   for (var i = 0; i < nodelist.length; i++) 
   {
      var attributes=nodelist(i).attributes;
	  
	  
      var attributename= attributes.getNamedItem("name").nodeValue;
      var attributevalue= attributes.getNamedItem("value").nodeValue;
      var showattributes= attributes.getNamedItem("showattributes").nodeValue;
      var hideattributes= attributes.getNamedItem("hideattributes").nodeValue;
	  var showsections= attributes.getNamedItem("showsections").nodeValue;
	  var hidesections= attributes.getNamedItem("hidesections").nodeValue;
	  var showtabs= attributes.getNamedItem("showtabs").nodeValue;
	  var hidetabs= attributes.getNamedItem("hidetabs").nodeValue;
	  var setrequiredlevel=attributes.getNamedItem("setrequiredlevel").nodeValue;
	  
if (attributevalue==""+getValue(attributename))
      {
		/*Mostrar campos*/
		var arrshowattributes=showattributes.split(","); 
		for (j=0;j<arrshowattributes.length;j++) 
		{
			showhideAttribute(arrshowattributes[j],true);
		}
		
		/*Ocultar campo*/
		var arrhideattributes=hideattributes.split(","); 
		for (j=0;j<arrhideattributes.length;j++) 
		{
            showhideAttribute(arrhideattributes[j],false);
		}
		
		/*Mostrar secciones*/
		var arrshowsections=showsections.split(","); 
		for (j=0;j<arrshowsections.length;j++) 
		{
			var tab_section=arrshowsections[j].split("/");
			var tabname=tab_section[0];
			var sectionname=tab_section[1];
            showhideSection(tabname, sectionname,true);
		}
		
		/*Ocultar secciones*/
		var arrhidesections=hidesections.split(","); 
		for (j=0;j<arrhidesections.length;j++) 
		{
			var tab_section=arrhidesections[j].split("/");
			var tabname=tab_section[0];
			var sectionname=tab_section[1];
            showhideSection(tabname, sectionname,false);
		}
		
		/*Mostrar tabs*/
		var arrshowtabs=showtabs.split(","); 
		for (j=0;j<arrshowtabs.length;j++) 
		{
             showhideTab(arrshowtabs[j],true);
		}
		
		/*Ocultar tabs		*/
		var arrhidetabs=hidetabs.split(","); 
		for (j=0;j<arrhidetabs.length;j++) 
		{
             showhideTab(arrhidetabs[j],false);
		}
		
		/*Requiredlevel de los atributos*/
		
		var arrsetrequiredlevel=setrequiredlevel.split(","); 
		for (j=0;j<arrsetrequiredlevel.length;j++) 
		{
			/*required:fax-address1_city,recommended:address1_name*/
			var req_level=arrsetrequiredlevel[j].split(":");
			var slevel=req_level[0];
			var attrs_req=req_level[1].split("-");
			for (v=0;v<attrs_req.length;v++) 
			{
				setRequiredLevel(attrs_req[v],slevel);
			}
		}
      }
   }
}

          
La idea de esta parte del código, es simplemente leer e interpretar el XML y disparar las acciones que hay definidas en el mismo.
Todas las funciones genéricas las he definido aparte:
/*
Métodos comunes de Dynamics CRM 2011 Forms.
*/
function getValue(attributename)
{
	if (Xrm.Page.getAttribute(attributename))
		return Xrm.Page.getAttribute(attributename).getValue();
	else
		return null;
}

function showhideAttribute(attributename,show)
{
	if (Xrm.Page.getControl(attributename))
		Xrm.Page.getControl(attributename).setVisible(show);
}

function showhideSection(tabname, sectionname, show) {
    var tab = Xrm.Page.ui.tabs.get(tabname);
    if (tab != null && sectionname != null) {
        var section = tab.sections.get(sectionname);
        if (section != null) { section.setVisible(show); }
    }
}
function showhideTab(tabname,show) 
{ 
	if (Xrm.Page.ui.tabs.get(tabname))
		Xrm.Page.ui.tabs.get(tabname).setVisible(show);
}

function setRequiredLevel(attributename,req_level)
{
	if (Xrm.Page.getAttribute(attributename))
		Xrm.Page.getAttribute(attributename).setRequiredLevel(req_level);
}


var xml_loaded=false;
var xmlPath = "../WebResources/";
var doc = new ActiveXObject("Microsoft.XMLDOM");
function LoadXmlWebResource(WebResource_name)
{
   if (!xml_loaded)
   {
      doc.preserveWhiteSpace = true;
      doc.async = false;
      doc.load(xmlPath+WebResource_name);
      xml_loaded=true;
   }
}
El listado de métodos definidos el es siguiente:
  • getValuegetValue(attributename): recoger el valor de un campo
  • showhideAttribute(attributename,show): ocultar/mostrar campos
  • showhideSection(tabname, sectionname, show): ocultar/mostrar secciones
  • showhideTab(tabname,show) : ocultar/mostrar tabs (o pestañas)
  • setRequiredLevel(attributename,req_level): para cambiar campos a nivel requerido, recomendado u opcional.
  • LoadXmlWebResource(WebResource_name): para cargar un XML desde un WebResource
Vamos a ver este código de ejemplo en acción:
image image

No hay comentarios:

Publicar un comentario