Stefan Pienaar
I would love to change the world, but they won't give me the source code

Creating a CRM Javascript function which is accessable to all events on a form

June 26, 2009 11:56 by StefanPienaar

There might be situations where you’ll need to perform the same actions/calculations (via javascript) on different form events. Code duplication is always a bad idea so you could either include an external javascript file with your function or create the function in your form’s load event as follows:

CalculateAge = function()
{
  if(crmForm.all.new_dateofbirth.DataValue != null)
  {
     // Your javascript logic
  }
}

You can then call this function from any event on the same form. For example I could call this function right after creating it on the load event to ensure the age is always updated when the record is opened, and I can also call it from my date of birth field’s change event. To call the event, I would use this line:
 
CalculateAge();

Categories: Microsoft CRM 4
Actions: E-mail | Permalink | Comments (2)

Changing the value of a Lookup field in CRM

June 26, 2009 11:46 by stefanpienaar

You can change the value of a Lookup Field on a CRM form (for example the owner or the selected currency) by using the following piece of javascript:

var lookupObject = new Object;
var lookupObjectArray = new Array();
lookupObject.id = '<Guid of the target record>';
lookupObject.name = '<Name of the target record>';
lookupObject.typename = "<target record type>";
lookupObjectArray[0] = lookupObject;
crmForm.all.<target field>.DataValue = lookupObjectArray;
crmForm.all.<target field>.ForceSubmit = true;


Just make sure to change the values between < and > to suit your own situation. For example if I wanted to change the default currency I would change the code to the following:

var lookupObject = new Object;
var lookupObjectArray = new Array();
lookupObject.id = '{EF63EA80-02BE-DD11-8241-0017A410DDDA}';    // Rand's Guid
lookupObject.name = 'Rand';                                    // Name of currency
lookupObject.typename = "transactioncurrency";                 // Lookup's type
lookupObjectArray[0] = lookupObject;
crmForm.all.transactioncurrencyid.DataValue = lookupObjectArray;
crmForm.all.transactioncurrencyid.ForceSubmit = true;


Note that the Guid used above will be unique per installation so yours won’t necessarily match mine.The last line just ensures that the record is updated correctly if my Lookup field is disabled on the form.


Categories: Microsoft CRM 4
Actions: E-mail | Permalink | Comments (0)

Getting meaningful error messages from CRM’s Web Service

April 16, 2009 22:43 by stefanpienaar

When I first started working with CRM’s web service, I was really frustrated by the lack of a detailed error message when something went wrong, turns out there is an easy way to always get a descriptive error.

I used to only catch a generic Exception and most of the time the only error message you’ll get from that is “Server was unable to process request”. In the example below I’m creating a phone call activity and assigning it to a system user.

image_thumb1

However, when you catch a SoapException (found in the System.Web.Services.Protocols namespace) instead, you can view the SoapException’s Detail Property which has an InnerXml property.

image_thumb4

Ahhhhh, I was using a Guid for a system user which doesn’t exists… *facepalm*


Categories: Microsoft CRM 4
Actions: E-mail | Permalink | Comments (0)

Setting the focus to a specific tab in CRM

March 3, 2009 12:51 by stefanpienaar

Interesting tip I found on Ronald Lemmen’s blog. When you want to make a tab which isn’t the first tab on a form active programmatically, all you need to do is:

crmForm.all.tab1Tab.click();

 

In this case it will activate the 2nd tab on the form.


Categories: Microsoft CRM 4
Actions: E-mail | Permalink | Comments (1)

Readonly and disabled fields in CRM Forms

March 2, 2009 14:29 by stefanpienaar

Ryan Farley wrote an article explaining how to disable the various types of controls typically found on a CRM form. In his article he covers: Text and Numeric Fields (nvarchar, ntext, float, int, money), Picklist Fields, Lookups, Date Fields and Bit Fields.

View Ryan’s article

Bill Owens also wrote an excellent article covering some things you can accomplish with javascript inside MSCRM Forms: Bill Owens on Microsoft Dynamics CRM - Technical Version


Categories: Microsoft CRM 4
Actions: E-mail | Permalink | Comments (0)

Hiding a form field in MSCRM

March 2, 2009 13:47 by stefanpienaar

You can hide a form field in Microsoft CRM using javascript by using the following snippet:

crmForm.all.schemaName_c.style.display = 'none';
crmForm.all.schemaName_d.style.display = 'none';

Just be sure to replace “schemaName” in the above example with your own field.

The “_c” postfix denotes the table cell containing the label for the field while the “_d” postfix is the table cell which contains the actual input controls.

To make a field visible again, you can use the following:

crmForm.all.schemaName_c.style.display = 'inline';
crmForm.all.schemaName_d.style.display = 'inline';

Categories: Microsoft CRM 4
Actions: E-mail | Permalink | Comments (0)

MS CRM - Using Generic Methods to call Web Service

September 10, 2008 12:02 by StefanPienaar

I just started out with a company specializing in CRM deployments and customizations through the exposed web service. So naturally I've been playing around with with some of the QueryExpression and QueryByAttribute Classes.

Working though some examples in the book I have (yes I'm a total newby when it comes to CRM) I thought that there has to be a cleaner way to deal with querying data so I had a look around if anyone else has written something...

This is what I found: Microsoft CRM 3.0 Web Service Calls With Generic Methods. Now I haven't used this extensively nor am I familiar enough with CRM to know if this would have any negative impacts along the line but it looked like a clean solution which is easy to expand by writing other overloaded methods.

Here is the main method which can then be overloaded for simplicity. Have a look at the original post for some overloaded methods:

 

public static T[] FindEntities<T>(string[] attributes, object[] values, 
    ConditionOperator[] operators, string[] columns, string[] orderAttribute, 
    OrderType[] orderType) where T : BusinessEntity
{
    if (_service == null)
        _service = GetInstance();
 
    QueryExpression query = new QueryExpression();
    query.EntityName = typeof(T).Name;
 
    ConditionExpression[] conditionExpressions = null;
 
    if (attributes != null && values != null)
    {
        conditionExpressions = new ConditionExpression[attributes.Length];
 
        for (int i = 0; i < conditionExpressions.Length; i++)
        {
            ConditionExpression conditionExpression = new ConditionExpression();
            conditionExpression.AttributeName = attributes[i];
            conditionExpression.Operator = 
                operators == null ? ConditionOperator.Equal : operators[i];
            conditionExpression.Values = new object[] { values[i] };
 
            conditionExpressions[i] = conditionExpression;
        }
    }
 
    FilterExpression filterExpression = new FilterExpression();
    filterExpression.FilterOperator = LogicalOperator.And;
    filterExpression.Conditions = conditionExpressions;
    query.Criteria = filterExpression;
 
    if (orderAttribute != null)
    {
        for (int i = 0; i < orderAttribute.Length; i++)
        {
            OrderExpression order = new OrderExpression();
            order.AttributeName = orderAttribute[i];
            order.OrderType = 
                orderType[i] == null ? OrderType.Ascending : orderType[i];
            query.Orders = new OrderExpression[] { order };
        }
    }
 
    ColumnSetBase columnSet = null;
 
    if (columns == null)
    {
        columnSet = new AllColumns();
    }
    else
    {
        columnSet = new ColumnSet();
        ((ColumnSet)columnSet).Attributes = columns;
    }
 
    query.ColumnSet = columnSet;
    query.EntityName = typeof(T).Name;
 
    BusinessEntityCollection result = _service.RetrieveMultiple(query);
 
    T[] entities = new T[result.BusinessEntities.Length];
    Array.Copy(result.BusinessEntities, entities, entities.Length);
    return entities;
}

Hope that makes a fellow CRM newby's life a little easier :)


Categories: Microsoft CRM 4
Actions: E-mail | Permalink | Comments (0)