Zoeken in deze blog

maandag 12 oktober 2009

Test

Calling the CRM Web Service with JavaScript

Plenty of examples can be found on how to call web services with JavaScript (see here and here). With respect to CRM, almost every example lacks a good explanation of A) what the code is doing (and why), and most importantly B) what to do with the result (to be fair, the answer to this is largely dependent on what data you are retrieving). The intent of this post is to provide enough insight so that you can easily take the ideas presented here and utilize them to suit your needs.

The basic process is this:

  1. Connect to the web service.
  2. Construct and send data containing the request.
  3. Grab the results returned by the web service.
  4. Parse the results to extract the relevant data.

Connect to the CRM Web Service

In order to connect to a web service with JavaScript, we use the XMLHTTPRequest object. There are 2 ways you can create the object:

// ALL MODERN BROWSERS (INCLUDING IE 7)

var xmlhttp=new XMLHttpRequest();

// IE 5 AND 6 (INCLUDING IE 7)

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

When developing for MSCRM, the second method is preferred, unless you are certain there are no prior versions of IE in use. Now that we've created the object, we need to use the Open method to specify the web service connection we will be using. The Open method has three arguments: Method, URL, and Async. So, to connect with our CRM web service, we use the following line:

// OPEN THE CONNECTION

xmlhttp.open('GET', 'http://crmserver/mscrmservices/2006/crmservice.asmx', false);

We will be using the GET method because we are receiving data back from the web service. For the URL, simply replace "crmserver" with the your appropriate server name. Notice we set the Async argument to false. Setting this to true tells the browser to continue running the rest of the code in the background before the data is returned - that's not what we want in this case.

Construct and Send the XML Request

Okay, so we've initialized the web service connection, now what? The CRM web service accepts requests as an XML string. The structure and content of the XML you send is dependent on what type of request you are making. First, we need to set some properties of the request:

// SET REQUEST PROPERTIES

xmlhttp.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
xmlhttp.setRequestHeader('SOAPAction', 'http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple');

These two lines allow us to set the HTTP headers of the data that will be sent to the server. The first specifies that we are sending data in text format with utf-8 encoding. The second specifies what process (or "action") we want to carry out on the server. In this case, we want to execute the RetrieveMultiple method of the MSCRM web service. To see which methods are available, browse to 'http://crmserver/mscrmservices/2006/crmservice.asmx' (be sure to update the server name).

Now, we need to specify which data the web service should return - basically, we want to create our query. We do this by creating some XML that represents a QueryByAttribute object. The structure of the QueryByAttribute looks like this:

<? 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'>

<soap:Body>

<query xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' xsi:type='q1:QueryByAttribute' xmlns='http://schemas.microsoft.com/crm/2006/WebServices'>

<q1:EntityName>ENTITY_NAME</q1:EntityName>

<q1:ColumnSet xsi:type="q1:ColumnSet">

<q1:Attributes>

<q1:Attribute>ATTRIBUTE1</q1:Attribute>

<q1:Attribute>ATTRIBUTE2</q1:Attribute>

</q1:Attributes>

</q1:ColumnSet>

<q1:Attributes>

<q1:Attribute>CRITERIA_ATTRIBUTE</q1:Attribute>

</q1:Attributes>

<q1:Values>

<q1:Value xsi:type="xsd:string">CRITERIA_VALUE</q1:Value>

</q1:Values>

</query>

</soap:Body>

</soap:Envelope>

This XML represents a QueryByAttribute that returns ATTRIBUTE1 and ATTRIBUTE2 from the ENTITY_NAME entity where the CRITERIA_ATTRIBUTE value equals CRITERIA_VALUE. To carry out the query, we would build a string containing the above XML structure and then use the Send() method to send that string to the web service for processing.

In a real world usage scenario, here's how we'd get a list of all Contacts from California:

// BUILD THE XML REQUEST STRING

var xmlPost = "<?xml version='1.0' encoding='utf-8'?>"+"\n\n"+"<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">'+
    ' <soap:Body>' +
    ' <query xmlns:q1="http://schemas.microsoft.com/crm/2006/Query" xsi:type="q1:QueryByAttribute" xmlns="http://schemas.microsoft.com/crm/2006/WebServices">'+
    ' <q1:EntityName>contact</q1:EntityName>'+
    ' <q1:ColumnSet xsi:type="q1:ColumnSet">'+
    ' <q1:Attributes>'+
    ' <q1:Attribute>contactid</q1:Attribute>'+
    ' <q1:Attribute>fullname</q1:Attribute>'+
    ' </q1:Attributes>'+
    ' </q1:ColumnSet>'+
    ' <q1:Attributes>'+
    ' <q1:Attribute>address1_stateorprovince</q1:Attribute>'+
    ' </q1:Attributes>'+
    ' <q1:Values>'+
    ' <q1:Value xsi:type="xsd:string">CA</q1:Value>'+
    ' </q1:Values>'+
    ' </query>'+
    ' </soap:Body>'+
    ' </soap:Envelope>';

// SEND THE REQUEST

xmlhttp.send(xmlPost);

 
 

Grab and Parse the Results

We've made our request, so now what? Well, we have to grab the response (remember that MSCRM utilizes the Request-Response philosophy). In order to work with the response, we create a variable to store the XML data we receive back from MSCRM:

// GET THE RESPONSE
var xmlResponse = xmlhttp.responseXML;

Now we have our return data, but we still need to parse out the XML and get the meaningful values. I've seen several different techniques to do this, and I think most of them are pretty hokey and try to parse out data manually. You know that the data is XML and not just a string, so why not use the XML functionality you already have? Not only is it more robust, but it's just easier to work with.

The above code creates the xmlResponse variable, which ends up being an XML data type. To parse this, we create an node list by using the selectNodes method of the xmlResponse object:

// PARSE NODES

var contacts = xmlResponse.selectNodes("//BusinessEntity/contactid");

var names = xmlResponse.selectNodes("//BusinessEntity/fullname");

The above code creates two lists containing all of the values found in the contactid and fullname columns of the query. If you are ever unsure of exactly how the result XML is structured, you can always output the XML string using document.write during development to give you an idea of how to construct the search strings you need to use with selectNodes().

To access these values, we simply loop through the lists:

// LOOP THROUGH VALUES
for(var i = 0; i < contacts.length; i++)
{
    document.write("The contactid for ",names[i].text," is: ", contacts[i].text);
}

The above code loops through the nodes and writes data from the query.

Wrap-Up

So that's pretty much it. Hopefully I've presented enough information here to allow you to really understand how to perform MSCRM web service calls. You can call other web services with the stuff I've shown here - the main difference is MSCRM utilizes XML for the input and output, so you have to do a little more work in that respect.

How did I know how to structure the XML for the QueryByAttribute? I didn't - I just had that from one of the first examples I found online. There are few ways to figure out how you need to shape the request XML:

  1. Enable Tracing: This will allow you to capture and view the Request and Response SOAP messages so you can see how they are constructed (and so you know how to parse them out). You'll then have to have some activity going against CRM to generate the SOAP messages. Be sure to disable tracing when you are finished - this can really eat up some disk space.
  2. Take a look at the WSDL: Navigate to http://<servername>/mscrmservices/2006/crmservice.asmx?WSDL and take in the nuts and bolts in all its glory. Not for the faint of heart, but you can see how every single type is constructed.
  3. Use a generic SOAP client (such as XMLSpy) to inspect the request and response SOAP messages. There are many references to a free utility called .NET WebServiceStudio 2.0 that was hosted on GotDotNet, but it has since disappeared. From all accounts, it was a wonderful utility for just this kind of work.
  4. Last, but not least - Check out Stunnware.

maandag 5 oktober 2009

Marktlijsten

Marktlijst actief en op slot
- contactpersoon inactief zetten: geen probleem. Wordt in de marktlijst ook op inactief gezet.
- contactpersoon mergen: kan niet. De melding "ongeldige bewerking als de marktlijst is vergrendeld" wordt getoond.

Marktlijst inactief en niet op slot
- contactpersoon inactief zetten: geen probleem. Wordt in de marktlijst ook op inactief gezet.
- contactpersoon mergen: geen probleem. De gemergde contactpersoon wordt in de marktlijst ook op inactief gezet.

Marktlijst inactief en op slot
- contactpersoon inactief zetten: geen probleem. Wordt in de marktlijst ook op inactief gezet.
- contactpersoon mergen: kan niet. De melding "ongeldige bewerking als de marktlijst is vergrendeld" wordt getoond.

Searchable Property Attribute Updater

Om massaal de optie "Kan worden doorzocht" op veldniveau te kunnen aanpassen, is een handig tooltje beschikbaar.

http://mscrmtools.blogspot.com/2008/11/hi-previous-post-was-not-last-one.html

Thanks Tanguy!

maandag 28 september 2009

SQL-controlequery toegevoegde marktlijstleden

SELECT FilteredListMember.listmemberid, FilteredListMember.createdbyname, FilteredListMember.modifiedon, FilteredList.listname, DATEPART(m, FilteredListMember.createdon) AS Maand, DATEPART(yy, FilteredListMember.createdon) AS Jaar, DATEPART(dd, FilteredListMember.createdon) AS Dag, FilteredListMember.createdby

FROM FilteredListMember INNER JOIN FilteredList ON FilteredListMember.listid = FilteredList.listid

WHERE (FilteredListMember.listid = '6E093B6F-E775-DE11-B303-005056940368') AND (DATEPART(m, FilteredListMember.createdon) = 8) AND (DATEPART(yy, FilteredListMember.createdon) = 2009) AND (DATEPART(dd, FilteredListMember.createdon) = 18) AND (FilteredListMember.createdby = 'A26FF5EE-AF22-DE11-8C4D-005056940368')

ORDER BY FilteredListMember.modifiedon DESC

woensdag 26 augustus 2009

Creëer masker op veld

function OnCrmPageLoad()
{
Mask( "telephone2" , "+(###)-(#)###-###" );
Mask( "gi_visa" , "####-####-####-####" );
Mask( "gi_scid" , "#-########-#" );
}

function Mask( fieldId , mask )
{
field = document.getElementById(fieldId);
field.mask = mask.split("");
field.regex = new RegExp(escapeRegEx(mask.replace(/#/gi,"").split("")),"gi");
field.title += " " + mask;
field.attachEvent( "onchange" , MaskOnFieldChange );
}

function escapeRegEx( chars )
{
var regChars = "+_)(*^$[]-?{}"; //Add all regexp chars id needed
var regExprs = "";
var run2Index = chars.length - 1;

for( var i = 0 ; i < run2Index ; i++ ) Concat( chars[i] , "|" );

Concat(chars[run2Index]);

function Concat( c , d ){
regExprs += (( regChars.indexOf(c) != -1 )? "\\":"" ) + c + d;
}

return regExprs;
}

function MaskOnFieldChange()
{
var field = event.srcElement;
if( field.DataValue == null ) return;

var arrDataValue = field.DataValue.replace(field.regex,"").split("");
var arrResult = [];

for(var i=0 , j=0 ; i < field.mask.length ;i++)
arrResult[i] = (field.mask[i] != "#")?field.mask[i]:arrDataValue[j++];

field.DataValue = arrResult.join("");
}

OnCrmPageLoad();

Opvragen fetch vanuit Advanced Find

javascript:void( new function(){ prompt("Fetch Parameters:",getFetchParams());function getFetchParams(){ return "FetchXml:\n" + advFind.FetchXml + "\n\n" + "LayoutXml:\n" + advFind.LayoutXml + "\n\n" + "EntityName:\n" + advFind.EntityName + "\n\n" + "DefaultAdvancedFindViewId:\n" + advFind.DefaultAdvancedFindViewId } } )

maandag 17 augustus 2009

Soap: ophalen lookup uit gekoppelde entiteit

//Get the lookup ownerid

GetSalesteam = function()
{
var lookupItem = crmForm.all.ownerid.DataValue; //Dit is de de lookup waarbij je extra gegevens op wilt halen

// check if there is data in the field, get the salesteam
if(lookupItem != null && lookupItem[0] != null)
{
var sb=new StringBuilder();
sb.Append('<?xml version="1.0" encoding="utf-8"?>');
sb.Append('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/%22 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22 xmlns:xsd="http://www.w3.org/2001/XMLSchema%22>');
sb.Append(GenerateAuthenticationHeader());
sb.Append('<soap:Body>');
sb.Append(' <RetrieveMultiple xmlns="'+CRM2007_WEBSERVICE_NS+'">');
sb.Append(' <query xmlns:q1="http://schemas.microsoft.com/crm/2006/Query%22 xsi:type="q1:QueryExpression">');
sb.Append(' <q1:EntityName>systemuser</q1:EntityName>'); //Dit is de gekoppelde entiteit waaruit je gegevens op wilt halen
sb.Append(' <q1:ColumnSet xsi:type="q1:ColumnSet"><q1:Attributes><q1:Attribute>sgt_salesteamid</q1:Attribute></q1:Attributes></q1:ColumnSet>'); //Dit is het veld dat je uit de gekoppelde entiteit wilt ophalen
sb.Append(' <q1:Criteria>');
sb.Append(' <q1:FilterOperator>And</q1:FilterOperator>');
sb.Append(' <q1:Conditions><q1:Condition>');
sb.Append(' <q1:AttributeName>systemuserid</q1:AttributeName>');
sb.Append(' <q1:Operator>Equal</q1:Operator>');
sb.Append(' <q1:Values><q1:Value xsi:type="xsd:string">' + lookupItem[0].id + '</q1:Value></q1:Values>');
sb.Append(' </q1:Condition></q1:Conditions>');
sb.Append(' </q1:Criteria>');
sb.Append(' </query>');
sb.Append(' </RetrieveMultiple>');
sb.Append('</soap:Body>');
sb.Append('</soap:Envelope>');
var xml=sb.ToString();

var xmlHttpRequest=new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.open('POST','/mscrmservices/2007/CrmService.asmx',false);
xmlHttpRequest.setRequestHeader('SOAPAction',CRM2007_WEBSERVICE_NS+'/RetrieveMultiple');
xmlHttpRequest.setRequestHeader('Content-Type','text/xml; charset=utf-8');
xmlHttpRequest.setRequestHeader('Content-Length',xml.length);
xmlHttpRequest.send(xml);
var xmlDoc=xmlHttpRequest.responseXML;
// look for response
if ( xmlDoc.selectSingleNode('//q1:sgt_salesteamid') != null ) //Controle of het veld dat je op wilt halen wel data bevat
{
var salesteam = new Array();
salesteam[0] = new LookupControlItem(
xmlDoc.selectSingleNode('//q1:sgt_salesteamid').text, 10001, //10001 is het nummer van de entiteit waaruit je gegevens op wilt halen
xmlDoc.selectSingleNode('//q1:sgt_salesteamid').getAttribute('name'));
// assign new lookup to the field
crmForm.all.sgt_salesteamid.DataValue = salesteam;
}
else
{
// make the field empty, for the contactpersoon is null
crmForm.all.sgt_salesteamid.DataValue = null;
}
}
}
GetSalesteam();

donderdag 23 juli 2009

Expiratiedatum bepalen o.b.v. Aanvraagtype en Prioriteit

var caseTypeCodeName=crmForm.all.casetypecode.SelectedText;
var priorityCodeName=crmForm.all.prioritycode.SelectedText;

switch(priorityCodeName.toLowerCase())
{
case 'hoog':
switch(caseTypeCodeName.toLowerCase())
{
case 'incident':
crmForm.all.followupby.DataValue=getFollowUpDate(1);
break;
case 'vraag':
crmForm.all.followupby.DataValue=getFollowUpDate(2);
break;
case 'wijziging':
case 'nieuw':
crmForm.all.followupby.DataValue=getFollowUpDate(5);
break;
}
break;
case 'normaal':
switch(caseTypeCodeName.toLowerCase())
{
case 'incident':
case 'vraag':
crmForm.all.followupby.DataValue=getFollowUpDate(3);
break;
case 'wijziging':
case 'nieuw':
crmForm.all.followupby.DataValue=getFollowUpDate(10);
break;
}
break;
case 'laag':
switch(caseTypeCodeName.toLowerCase())
{
case 'incident':
case 'vraag':
crmForm.all.followupby.DataValue=getFollowUpDate(10);
break;
case 'wijziging':
case 'nieuw':
crmForm.all.followupby.DataValue=getFollowUpDate(20);
break;
}
break;
}

function getFollowUpDate(nrOfDays)
{
var weekday=new Array(7);
weekday[0]='sunday';
weekday[1]='monday';
weekday[2]='tuesday';
weekday[3]='wednesday';
weekday[4]='thursday';
weekday[5]='friday';
weekday[6]='saturday';
var date
if(!IsNull(crmForm.all.createdon) && !IsNull(crmForm.all.createdon.DataValue))
date=crmForm.all.createdon.DataValue;
else
date=new Date();
// Calculate the new followup date
var followupDate=new Date();
followupDate.setFullYear(date.getFullYear(),date.getMonth(),date.getDate()+nrOfDays);
var followupDay=weekday[followupDate.getDay()];
// If followupday is on saterday or sunday, set the followupday to monday
if(followupDay=='saturday')
nrOfDays=2;
else if(followupDay=='sunday')
nrOfDays=1;
else
nrOfDays=0;
// Set the new followup date
date.setFullYear(followupDate.getFullYear(),followupDate.getMonth(),followupDate.getDate()+nrOfDays);
return date;
}

Tellen van het aantal notities in een aanvraag

//COUNT NUMBER OF NOTES
var totalNotes = getTotalNotes(crmForm.ObjectId);
setNoteTabName(totalNotes);

function setNoteTabName(count) {
    /* update note tab */
    if (crmForm.FormType != 1) {
        var cells = document.getElementsByTagName("A");

        for (var i = 0; i < cells.length; i++) {
            if (cells[i].innerText == "Opmerkingen") {
                if (count > 0) {
                        cells[i].innerText = "Opmerkingen (" + count + ")";
                        document.all.crmTabBar.style.width = "auto";
                }
                break;
            }
        }
    }
}

// Helper method to return the total notes associated with an object
function getTotalNotes(objectId) {
        // Define SOAP message
        var 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\">",
        GenerateAuthenticationHeader(),
        "<soap:Body>",
        "<RetrieveMultiple xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>",
        "<query xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' ",
        "xsi:type='q1:QueryExpression'>",
        "<q1:EntityName>annotation</q1:EntityName>",
        "<q1:ColumnSet xsi:type=\"q1:ColumnSet\"><q1:Attributes><q1:Attribute>createdon</q1:Attribute></q1:Attributes></q1:ColumnSet>",
        "<q1:Distinct>false</q1:Distinct><q1:Criteria><q1:FilterOperator>And</q1:FilterOperator>",
        "<q1:Conditions><q1:Condition><q1:AttributeName>objectid</q1:AttributeName><q1:Operator>Equal</q1:Operator>",
        "<q1:Values><q1:Value xsi:type=\"xsd:string\">",
        objectId,
        "</q1:Value></q1:Values></q1:Condition></q1:Conditions></q1:Criteria>",
        "</query>",
        "</RetrieveMultiple>",
        "</soap:Body>",
        "</soap:Envelope>"
        ].join("");
        var resultXml = executeSoapRequest("RetrieveMultiple", xml);
        return getMultipleNodeCount(resultXml, "q1:createdon");
}

// Helper method to execute a SOAP request
function executeSoapRequest(action, xml) {
    var actionUrl = "http://schemas.microsoft.com/crm/2007/WebServices/";
    actionUrl += action;

    var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
    xmlHttpRequest.setRequestHeader("SOAPAction", actionUrl);
    xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
    xmlHttpRequest.send(xml);

    var resultXml = xmlHttpRequest.responseXML;
    return resultXml;
}

// Helper method to return total # of nodes from XML
function getMultipleNodeCount(tree, el) {
    var e = null;
    e = tree.getElementsByTagName(el);
    return e.length;
}

Locatie automatisch vullen vanuit het veld Betreft bij toevoegen afspraak in CRM

Maak een workflow aan op de entiteit Afspraak die afgaat wanneer de afspraak toegevoegd wordt of wanneer het veld Locatie in de afspraak wordt gewijzigd.

Outlook synchronisatie van contactpersonen

Stap 1:
Maak een workflow op de entiteit Outlook synchronisatie die op de contactpersoonkaart een aantal-veld ophoogt met 1 wanneer een nieuw record in deze entiteit wordt aangemaakt of wanneer één van deze records van eigenaar veranderd.


Stap 2:
Zorg bij de lokale datagroepen in de Outlook client dat deze naar de nieuwe entiteit Outlook synchronisatie kijkt.

maandag 13 juli 2009

Getal opmaken met duizendtallen

if(crmForm.all.cov_landid_ba.DataValue != null)
{
LookupItem = crmForm.all.cov_landid_ba.DataValue;

if(LookupItem[0].name == 'België')
{
Ondernemingsnummer = crmForm.all.cov_ondernemingsnummer.DataValue;
Ondernemingsnummer = Ondernemingsnummer.replace(/[^+ 0-9]/g, "");

var Temp = Ondernemingsnummer.substr(0,4) + "." + Ondernemingsnummer.substr(4,3) + "." + Ondernemingsnummer.substr(7);

crmForm.all.cov_ondernemingsnummer.DataValue = "BE" + Temp;

if(Ondernemingsnummer.length != 10)
{
alert("Aantal cijfers in het veld Ondernemingsnummer is niet gelijk aan 10!");
}
}
}

dinsdag 2 juni 2009

maandag 25 mei 2009

Pagina full-screen

window.moveTo(0,0);
window.resizeTo(screen.availWidth, screen.availHeight);

donderdag 7 mei 2009

dinsdag 5 mei 2009

IFRAME N:N

if(crmForm.FormType != 1)
{
function OnCrmPageLoad()
{
/* Create a ne N2NViewer and give it the IFRAME (container) id */
var n2nViewer = new N2NViewer('IFRAME_account_association');
/* Set the role order - use iedevtoolber for exact parameters */
n2nViewer.RoleOrder = 1;
/* assing the relationship name */
n2nViewer.TabsetId = "gi_account_account";
/* Do the trick... */
n2nViewer.Load();
}
function N2NViewer(iframeId)
{
if (!document.all[iframeId])
{
alert(iframeId + " is missing!");
return;
}
var viewer = this;
var _locAssocObj = null;
viewer.IFRAME = document.all[iframeId];
viewer.RoleOrder;
viewer.TabsetId;
viewer.Load = function()
{
/* Construct a valid N2N IFRAME url */
viewer.IFRAME.src = "areas.aspx?oId=" + crmForm.ObjectId + "&oType=" + crmForm.ObjectTypeCode + "&security=" + crmFormSubmit.crmFormSubmitSecurity.value + "&roleOrd=" + viewer.RoleOrder + "&tabSet=" + viewer.TabsetId;
viewer.IFRAME.onreadystatechange = viewer.StateChanged;
}
viewer.StateChanged = function()
{
if (viewer.IFRAME.readyState != 'complete')
{
return;
}
var iframeDoc = viewer.IFRAME.contentWindow.document;
/* Reomve scrolling space */
iframeDoc.body.scroll = "no";
/* Remove crmGrid Default padding */
iframeDoc.body.childNodes[0].rows[0].cells[0].style.padding = 0;
/* Save MS locAssocObj */
_locAssocObj = locAssocObj;
/* Override MS locAssocObj */
locAssocObj = viewer.locAssocObj;
}
viewer.locAssocObj = function(iType , sSubType, sAssociationName, iRoleOrdinal)
{
/* Open the Dialog */
_locAssocObj(iType , sSubType, sAssociationName, iRoleOrdinal);
/* Refresh only if our iframe contains the correnct tabset name */
if (sAssociationName == viewer.TabsetId)
{
viewer.IFRAME.contentWindow.document.all.crmGrid.Refresh();
}
}
}
//Entry Point
OnCrmPageLoad();
}

Verwijderen van de button “Bestaande ……toevoegen”

//Hiden button
HideAssociatedViewButtons('cov_contact_cov_outlooksynchronisatie', ['Bestaande Outlook synchronisatie toevoegen aan deze record']);

function HideAssociatedViewButtons(loadAreaId, buttonTitles)
{
var navElement = document.getElementById('nav_' + loadAreaId);
if (navElement != null)
{
navElement.onclick = function LoadAreaOverride() {
// Call the original CRM method to launch the navigation link and create area iFrame
loadArea(loadAreaId);
HideViewButtons(document.getElementById(loadAreaId + 'Frame'), buttonTitles);
}
}
}

function HideViewButtons(Iframe, buttonTitles)
{
if (Iframe != null ) {
Iframe.onreadystatechange = function HideTitledButtons()
{
if (Iframe.readyState == 'complete')
{
var iFrame = frames[window.event.srcElement.id];
var liElements = iFrame.document.getElementsByTagName('li');

for (var j = 0; j < buttonTitles.length; j++)
{
for (var i = 0; i < liElements.length; i++)
{
if (liElements[i].getAttribute('title') == buttonTitles[j])
{
liElements[i].style.display = 'none';
break;
}
}
}
}
}
}
}

Let op: het blauwe gedeelte is de aanverwante entiteit. Het rode gedeelte is de titel van de knop. Deze kun je o.a. achterhalen met de IE-Developer toolbar.

maandag 4 mei 2009

Twee lookup-fields koppelen

In de OnLoad:

//FILTEREN VAN CONTACTPERSONEN O.B.V. KLANTID
ContactpersonFilter = function()
{
if(crmForm.all.cov_bedrijfid.DataValue != null)
{
crmForm.all.customerid.lookupbrowse = 1;
crmForm.all.customerid.additionalparams = "search=<fetch mapping='logical'><entity name='contact'><all-attributes /><filter type='and'><condition attribute='parentcustomerid' operator='eq' value='" + crmForm.all.cov_bedrijfid.DataValue[0].id + "'/></filter></entity></fetch>";
}
}
ContactpersonFilter()

In de OnChange:

//LEEGMAKEN CONTACTPERSOON BIJ WIJZIGEN BEDRIJFSID
crmForm.all.customerid.DataValue = null;

//FILTEREN VAN CONTACTPERSONEN O.B.V. KLANTID
ContactpersonFilter();

IFRAME 1:N

if(crmForm.FormType != 1)
{
function OnCrmPageLoad()
{
/* Create a N2NViewer and give it the IFRAME (container) id */
var n2nViewer = new N2NViewer('IFRAME_Test');
/* assing the relationship name */
n2nViewer.TabsetId = "new_account_new_test";
/* Do the trick... */
n2nViewer.Load();
}
function N2NViewer(iframeId)
{
if (!document.all[iframeId])
{
alert(iframeId + " is missing!");
return;
}
var viewer = this;
var _locAssocObj = null;
viewer.IFRAME = document.all[iframeId];
viewer.RoleOrder;
viewer.TabsetId;
viewer.Load = function()
{
/* Construct a valid IFRAME url */
viewer.IFRAME.src = "areas.aspx?oId=" + crmForm.ObjectId + "&oType=" + crmForm.ObjectTypeCode + "&security=" + crmFormSubmit.crmFormSubmitSecurity.value + "&tabSet=" + viewer.TabsetId;
viewer.IFRAME.onreadystatechange = viewer.StateChanged;
}
viewer.StateChanged = function()
{
if (viewer.IFRAME.readyState != 'complete')
{
return;
}
var iframeDoc = viewer.IFRAME.contentWindow.document;
/* Remove scrolling space */
iframeDoc.body.scroll = "no";
/* Remove crmGrid Default padding */
iframeDoc.body.childNodes[0].rows[0].cells[0].style.padding = 0;
/* Save MS locAssocObj */
_locAssocObj = locAssocObj;
/* Override MS locAssocObj */
locAssocObj = viewer.locAssocObj;
}
viewer.locAssocObj = function(iType , sSubType, sAssociationName, iRoleOrdinal)
{
/* Open the Dialog */
_locAssocObj(iType , sSubType, sAssociationName, iRoleOrdinal);
}
}
crmForm.all.IFRAME_Test.setAttribute("isArea",1);

//Entry Point
OnCrmPageLoad();
}

donderdag 23 april 2009

Lookup-field default vullen zonder zonder GUID

countryPA = document.all.cov_landid_pa_d.getElementsByTagName("DIV")[0];
countryPA.innerText = "Nederland";
crmForm.all.cov_landid_pa.Lookup(true, true, "Nederland", true);

dinsdag 14 april 2009

FireOnChange

Wanneer je scripting gebruikt om de inhoud van een veld te wijzigen, wordt het OnChange script van dit veld niet automatisch getriggerd zoals dat wel gebeurt wanneer je handmatig iets in ditzelfde veld zou wijzigen. Om het OnChange script toch te triggeren, gebruik je onderstaand commando:

crmForm.all.yourfield.FireOnChange();

woensdag 1 april 2009