domingo, 19 de septiembre de 2010

Limitar el número de registros asociados a una entidad

Partamos del siguiente ejemplo:
Se tiene la entidad personalizada jlc_documento la cual está asociada a las entidades contact y account. Siendo contact y account las entidades que tengan la vista asociada y jlc_documento los lookups. (El lookup creado de la relación contact-jlc_documento es jlc_documentocontactid y el lookup creado de la relación account-jlc_documento es jlc_documentoaccountid)
Se desea poder registrar como máximo 10 jlc_documentos por cada registro de contact y account.
La solución a este problema podría ser la siguiente:

var clienteId;
var nroRegistros;
var authenticationHeader;
var xml;
if (crmForm.FormType == 1) {
    if (crmForm.all.jlc_documentoaccountid.DataValue[0].id != null || crmForm.all.jlc_documentocontactid.DataValue[0].id != null) {
        if (crmForm.all.jlc_documentoaccountid.DataValue[0].id != null) {
            clienteId = crmForm.all.jlc_documentoaccountid.DataValue[0].id;
        }
        else {
            clienteId = crmForm.all.jlc_documentocontactid.DataValue[0].id;
        }

        authenticationHeader = GenerateAuthenticationHeader();
        //Prepare the SOAP message.
        xml = "<?xml version='1.0' encoding='utf-8'?>" +
        "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'" +
        " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
        " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
        authenticationHeader +
        "<soap:Body>" +
        "<Fetch xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
        "<fetchXml>&lt;fetch mapping='logical'&gt;" +
        "&lt;entity name='jlc_documento'&gt;" +
        "&lt;filter type='or'&gt;" +
        "&lt;condition attribute='jlc_documentoaccountid' operator='eq' value='" + clienteId + "'/&gt;" +
        "&lt;condition attribute='jlc_documentocontactid' operator='eq' value='" + clienteId + "'/&gt;" +
        "&lt;/filter&gt;" +
        "&lt;/entity&gt;" +
        "&lt;/fetch&gt;</fetchXml>" +
        "</Fetch>" +
        "</soap:Body>" +
        "</soap:Envelope>";

        //Prepare the xmlHttpObject and send the request.
        var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
        xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
        xHReq.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
        xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        xHReq.setRequestHeader("Content-Length", xml.length);
        xHReq.send(xml);
        //Capture the result
        var resultXml = xHReq.responseXML;
        //Check for errors.
        var errorCount = resultXml.selectNodes('//error').length;
        if (errorCount != 0) {
            var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
            alert(msg);
        }
        //Process and display the results.
        else {

            //Capture the result and UnEncode it.
            var resultSet = new String();
            resultSet = resultXml.text;
            resultSet.replace('&lt;', '<');
            resultSet.replace('&gt;', '>');

            // Create an XML document that you can parse.
            var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            oXmlDoc.async = false;
            // Load the XML document that has the UnEncoded results.
            oXmlDoc.loadXML(resultSet);
            //Display the results.
            var results = oXmlDoc.getElementsByTagName('result');
            nroRegistros = results.length;
            if (nroRegistros == 10) {
                alert("Se han registrado el número máximo de asociaciones");
                window.close();
            }
        }
    }
}


miércoles, 8 de septiembre de 2010

Ejecutar OnChange sin perder el foco

El evento OnChange de los campos de un formulario de Dync CRM tienen una peculariedad ... el evento se ejecuta cuando se pierde el foco. Este detalle podría crearnos ciertas dificultades para lo cual tendríamos que forzar a que dicho evento se ejecute inmediatamente después de cambiar su valor y no después que se haya perdido el foco del campo. Veamos el siguiente ejemplo:
ESCENARIO
Se tiene el campo checkbox "valor" y un campo de caja de texto "descripcion". El campo "descripcion" deberá estar deshabilitado a menos que se haya seleccionado el campo "valor".

SOLUCION FALLIDA
En el evento OnChange de "valor" colocar:
if(crmForm.all.valor.DataValue==true)
   crmForm.all.descripcion.Disabled=false;
La opción arriba mencionda funciona sí y sólo sí luego de haber colocado un check en el campo "valor" se da un clic en cualquier otra parte del formulario o si se presiona la tecla TAB.

Para lograr nuestro cometido emplearemos "attachEvent" y que se ejecute en el momento que se haga check en "valor"
SOLUCION CORRECTA
En el evento OnLoad del formulario colocaremos lo siguiente 
function MiFuncion(){
   if(crmForm.all.valor.DataValue==true)
      crmForm.all.descripcion.Disabled=false;
}
crmForm.all.valor.attachEvent('onclick',MiFuncion);