CRM 2011 – how to update read only fields with Javascript

I have had an annoying problem which had me pulling out my hair in frustration when I was testing some javascript.

I had created a field called arranged by and it was a user lookup which was read only because I didn’t want people to set it, I wanted to set it when someone booked in a date and then fill in the field.

What was happening was I was setting the field, which you can read about here but then it saved but on the reload the field was blank, AGHGHGHGG.

I then read this forum question – read only field isn’t updated after javascript save

So it turns out that read only fields are not submitted to the database to be saved.  Which in one way is good because it means less traffic going up the pipe to the database but very annoying for me who is trying to set the read only value.

So if you want to save a read only field you need to set the SubmitMode to be always, which ensures the value is sent to the database.

Xrm.Page.getAttribute("fieldName").setSubmitMode("always");

Advertisements

CRM 2011 – Setting a state and status of an entity using a plugin

I had created a charge entity.  I was creating charge entities of certain values when certain things had happened on regarding cases.  When a case was created it created a charge entity linked to the case, account and product etc for a certain value.

Then when other status were reached a workflow would fire off and create more charge entity’s.  Then at a certain point the user wanted to create an invoice for all the charge entities which had not been assigned to an invoice.

So I created a plugin which when a new invoice is created it goes off and searches for all the charge entities which are not been associated with an invoice.  It then assigns the newly created invoice, adds a date and then I wanted to make the charge entity inactive.  I created a new inactive state called Invoiced.  The reason I wanted to do this was because I didn’t want the charge entity being associated with any other invoices and you can’t change inactive records.

updating the charge entity was no problem, I did this by doing a service.update(entity) but I got errors if I tried to change the state of the entity.  I recalled the state being some what different.

To change the state and status you have to a setStateRequest, it took me a while to work this out.

Another unusualish thing is the state of active is 0 and inactive is 1.  I’m not sure that’s unusual or not.

The status is the status value you want, I had to look up my new status and then assign the value.  The reason you use numbers is because the state and status are optionSet which are set using numbers.  My new status had the value of 951850001 and the default of inactive I think has the value of -1.

Here is the code

public void updateChargeState(Guid chargeId)
{

SetStateRequest setState = new SetStateRequest();

setState.EntityMoniker = new EntityReference();

setState.EntityMoniker.Id = chargeId;

setState.EntityMoniker.Name = "Charge";

setState.EntityMoniker.LogicalName = new_charge.EntityLogicalName;

setState.State = new OptionSetValue(1);
setState.Status = new OptionSetValue(951850001);
SetStateResponse setStateResponse = (SetStateResponse)service.Execute(setState);
}

CRM 2011 – Update Rollup 7 for Microsoft Dynamics CRM 2011 (KB 2600643)

The rollups keep rolling up for CRM 2011 and this means we are closers to R8 and the big enhancements coming our way.

I have updated the wiki page with the all the rollup numbers and version which you can see by clicking the link below

CRM 2011 Build and version numbers

 

To download rollup 7 click the release below

http://www.microsoft.com/download/en/details.aspx?id=29221

Version: 05.00.9690.2165

The KB article is KB2600643

Just to remind you, you will need to have rollup 6 installed to use this.

It seems to have a lot of fixes in this release but I can’t really make out any new major functionality.

Enjoy

CRM 2011 – QueryExpressions where a field is null

I had to write some code today which retrieved some entities which didn’t have a value in a field, so basically I had to write a query to find all the entities which had a null value.

I finally found some sample code on the Microsoft SDK

FilterExpression null_filter = new FilterExpression(LogicalOperator.And);
null_filter.FilterOperator = LogicalOperator.And;
null_filter.AddCondition("leadid", ConditionOperator.Null);

below is my full code.  I am selecting my custom charges entity where the invoice lookup value is null

</pre>
public IEnumerable<meta_charge> getCharges(IOrganizationService service)
{
try
{

ConditionExpression condition1 = new ConditionExpression();

condition1.AttributeName = "new_invoice";
condition1.Operator = ConditionOperator.Null;
FilterExpression filter1 = new FilterExpression();
filter1.Conditions.Add(condition1);

QueryExpression query = new QueryExpression(new_charge.EntityLogicalName);
query.ColumnSet = new ColumnSet(true);

query.Criteria.AddFilter(filter1);

EntityCollection result1 = service.RetrieveMultiple(query);

IEnumerable<new_charge> charges = result1.Entities.Cast<new_charge>();
return charges;

}
catch (Exception)
{
// You can handle an exception here or pass it back to the calling method.
return null;
}
}
<pre>

CRM 2011 – Setting a user lookup with the logged in user with Javascript

Sometimes you need to log the current user in a User Lookup.

Xrm.Page.context.getUserId()

if you wanted to set a user lookup field you would need to do this


var setUservalue = new Array();
 setUservalue[0] = new Object();
 setUservalue[0].id = Xrm.Page.context.getUserId();
 setUservalue[0].entityType = 'systemuser';
//setUservalue[0].name = retrievedUser.FullName;

Xrm.Page.getAttribute("meta_aurarrangedby").setValue(setUservalue)

meta_aurarrangedby is a user lookup field

This will set the correct guid but the user name will be blank until the page is reloaded if you want to add the user name then you need to retrieve the user name using the guid the example code below will do this using an OData query but you will have to add the json2.js file to the entity so it can be called from your javascript.

function Getinfo() {
 var context;
 var serverUrl;
 var UserID;
 var ODataPath;
 context = Xrm.Page.context;
 serverUrl = context.getServerUrl();
 UserID = context.getUserId();
 ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc";
 var retrieveUserReq = new XMLHttpRequest();
 retrieveUserReq.open("GET", ODataPath + "/SystemUserSet(guid'" + UserID + "')", true);
 retrieveUserReq.setRequestHeader("Accept", "application/json");
 retrieveUserReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
 retrieveUserReq.onreadystatechange = function () {
 retrieveUserReqCallBack(this);
 };
 retrieveUserReq.send();

}

function retrieveUserReqCallBack(retrieveUserReq) {
if (retrieveUserReq.readyState == 4 /* complete */) {

if (retrieveUserReq.status == 200) {
 var retrievedUser = this.parent.JSON.parse(retrieveUserReq.responseText).d;
 if (retrievedUser.FullName != null)

var setUservalue = new Array();
 setUservalue[0] = new Object();
 setUservalue[0].id = Xrm.Page.context.getUserId();
 setUservalue[0].entityType = 'systemuser';
 setUservalue[0].name = retrievedUser.FullName;

Xrm.Page.getAttribute("meta_aurarrangedby").setValue(setUservalue)
 }

else {

 }
 }
}

The Xrm.Page.context has quite a few useful functions the functions are listed on this page

The getServerUrl is very useful as is the getUserRoles

Xrm.Page.context provides access to the following functions:

  • getAuthenticationHeader: A deprecated method that returns the encoded SOAP header necessary to use Microsoft Dynamics CRM Web service calls using JScript.
  • getCurrentTheme Returns a string representing the current Microsoft Office Outlook theme chosen by the user.
  • getOrgLcid: Returns the LCID value that represents the Microsoft Dynamics CRM Language Pack that is the base language for the organization.
  • getOrgUniqueName: Returns the unique text value of the organizations name.
  • getQueryStringParameters: Returns an array of key value pairs representing the query string arguments that were passed to the page.
  • getServerUrl: Returns the base server URL. When a user is working offline with Microsoft Dynamics CRM for Microsoft Office Outlook, the URL is to the local Microsoft Dynamics CRM Web services.
  • getUserId: Returns the GUID value of the SystemUser.id value for the current user.
  • getUserLcid: Returns the LCID value that represents the Microsoft Dynamics CRM Language Pack that is the user selected as their preferred language.
  • getUserRoles: Returns an array of strings representing the GUID values of each of the security roles that the user is associated with.
  • isOutlookClient: Returns a Boolean value indicating if the user is using Microsoft Dynamics CRM for Microsoft Office Outlook.
  • isOutlookOnline: Returns a Boolean value indicating whether the user is connected to the Microsoft Dynamics CRM server while using Microsoft Dynamics CRM for Microsoft Office Outlook with Offline Access. When this function returns false, the user is working offline without a connection to the server. They are interacting with an instance of Microsoft Dynamics CRM running on their local computer.
  • prependOrgName: Prepends the organization name to the specified path.

CRM 2011 – defaulting the Customer lookup to contacts on the case form

There are a few lookups in CRM call Customer lookups and can be either Accounts or Contacts.

I have to say I often find these annoying.  Often on the Case form I have to add an account lookup so the user can specify an account and a contact.  The problem is when I use the Customer lookup it defaults to account lookup.

The Customer record is locked onto the form so you can’t get rid of it (you can hide it and assign it a value if you wanted but that’s a bit messy and extra fields etc.)

So on this form I added an account lookup and then used the customer lookup to specify a contact and I wanted a way to default the lookup to be a contact lookup.

I found some code shown below on the blog MSCRM Bing’d which is written by CRM MVP Rhett Clinton.

document.getElementById("customerid").setAttribute("defaulttype", "2");
<pre>Xrm.Page.getControl("customerid").setDefaultView("a2d479c5-53e3-4c69-addd-802327e67a0d");

To get this solution to work I had to go and get the guid of the contact view and in this case I wanted the Active Contacts and replaced the SetDefaultView guid with my guid and then I put the code into the onload event.

Then when I clicked on the customer lookup it defaults to contacts and the view I specified in the guid.

The only downside is if you search in the box without pressing the lookup button it does still search contacts and accounts.

So a big thanks to Rhett for helping resolve a problem which had annoyed me for quite a while.


CRM 2011 – Solutions and publisher prefix

When I modify an organisation I usually make a new Publisher with Metaphorix the company I work for and other details.

I also change the prefix on the publisher to meta, so I can easily tell all the fields I have added.

When you create an organisation CRM automatically creates a publisher called default publisher <name of organisation>

So after I had made my Publisher I would then make a solution and add the entities I would be customizing.

The problem is if you want to use the functionality of using the customization buttons on a form (which you only see if you have the role of System Administrator or System Customizer). If you edit a form and add a field then it uses the default publisher prefix which is new.

I also thought initially changes to entities in my solution would only be recorded if I made them inside my solution but the reality is if you have the account entity in your solution and you edit it using the system customization rather than going through the solution interface then these changes will still be shown in your solution, the only difference is any fields you would have added will have the prefix of new.

well the easy and obvious way around this is to just change the prefix on the default Publisher in your CRM system and then hey presto all your fields will now have the same prefix.