Here is another update of CRM Web Service Toolkit for JavaScript that I released to codeplex site today, most likely this is going to be the last release before CRM5. This new release is based on previous version (v1.0), and it comes with a few more enhancements:
- A new method called queryByAttribute() has been added, which allows to retrieve a specific entity's record by using one or more than one pair of attribute and value
- Three new methods have been added to help facilitate user and user security role related queries, including getCurrentUserId(), getCurrentUserRoles(), isCurrentUserInRole()
- The toBoolean() prototype function that I added to JavaScript Number type in the previous version is now obsolete, instead I have added a new prototype function to the toolkit's BusinessEntity object. So if you want to retrieve a CRM Boolean type field's value, you should use something like this: businessEntity.getValueAsBoolean('new_mybooleanfield')
- A new prototype function called getValueAsLookup has been added to the toolkit's BusinessEntity object, which allows you to parse the values of a CRM lookup field that you retrieved through the toolkit and convert it to a CRM lookup control's DataValue. For instance, you could do something like this: crmForm.all.new_mylookup.DataValue = businessEntity.getValueAsLookup("new_mylookup", "new_mylookupentity")
- Use CrmServiceToolkit.Create() to create a CRM record.
// Use CrmServiceToolkit. Create() to create a CRM contact record. var contact = new CrmServiceToolkit.BusinessEntity("contact"); contact.attributes["firstname"] = "Diane"; contact.attributes["lastname"] = "Morgan"; contact.attributes["gendercode"] = 2; contact.attributes["familystatuscode"] = 1; // Picklist : Single - 1 contact.attributes["creditlimit"] = 3000; var createResponse = CrmServiceToolkit.Create(contact); - Use CrmServiceToolkit.Update() to update a CRM record.
//Use CrmServiceToolkit.Update() to update a CRM contact record. var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C'; var contact = new CrmServiceToolkit.BusinessEntity("contact"); contact.attributes["contactid"] = contactId; contact.attributes["firstname"] = "Diane"; contact.attributes["lastname"] = "Lopez"; contact.attributes["familystatuscode"] = 2; // Married var updateResponse = CrmServiceToolkit.Update(contact); - Use CrmServiceToolkit.Retrieve() to retrieve a CRM record.
// Use CrmServiceToolkit.Retrieve() to retrieve a CRM contact record. var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C'; var cols = ["firstname", "lastname", "familystatuscode", "creditlimit", "birthdate", "donotemail"]; var retrievedContact = CrmServiceToolkit.Retrieve("contact", contactId, cols); alert(retrievedContact.getValue('lastname')); alert(retrievedContact.getValue('firstname')); alert(retrievedContact.getValue('familystatuscode')); // Picklist's value (integer) alert(retrievedContact.getValue('familystatuscode', 'name')); // Picklist's selected text alert(retrievedContact.getValue('creditlimit')); // Currency field's value alert(retrievedContact.getValue('creditlimit', 'formattedvalue')); // Currency field's formatted value (string) alert(retrievedContact.getValue('birthdate')); // Datetime field's date/time value alert(retrievedContact.getValue('birthdate', 'date')); // Datetime field's date string alert(retrievedContact.getValue('birthdate', 'time')); // Datetime field's time string alert(retrievedContact.getValueAsBoolean('donotemail')); // Bit field's value - Use CrmServiceToolkit.RetrieveMultiple() to retrieve a collection of CRM records.
// Retrieve all contacts whose first name is John. var firstname = 'John'; var query = [ "<q1:EntityName>contact</q1:EntityName>", "<q1:ColumnSet xsi:type='q1:ColumnSet'>", "<q1:Attributes>", "<q1:Attribute>firstname</q1:Attribute>", "<q1:Attribute>lastname</q1:Attribute>", "<q1:Attribute>familystatuscode</q1:Attribute>", "<q1:Attribute>ownerid</q1:Attribute>", "<q1:Attribute>creditlimit</q1:Attribute>", "<q1:Attribute>birthdate</q1:Attribute>", "<q1:Attribute>donotemail</q1:Attribute>", "</q1:Attributes>", "</q1:ColumnSet>", "<q1:Distinct>false</q1:Distinct>", "<q1:Criteria>", "<q1:FilterOperator>And</q1:FilterOperator>", "<q1:Conditions>", "<q1:Condition>", "<q1:AttributeName>firstname</q1:AttributeName>", "<q1:Operator>Equal</q1:Operator>", "<q1:Values>", "<q1:Value xsi:type='xsd:string'>", firstname, "</q1:Value>", "</q1:Values>", "</q1:Condition>", "</q1:Conditions>", "</q1:Criteria>" ].join(""); var retrievedContacts = CrmServiceToolkit.RetrieveMultiple(query); alert(retrievedContacts.length); alert(retrievedContacts[0].getValue('lastname')); alert(retrievedContacts[0].getValue('firstname')); alert(retrievedContacts[0].getValue('familystatuscode'); alert(retrievedContacts[0].getValue('familystatuscode', 'name')); alert(retrievedContacts[0].getValue('creditlimit')); alert(retrievedContacts[0].getValue('creditlimit', 'formattedvalue')); alert(retrievedContacts[0].getValue('birthdate')); alert(retrievedContacts[0].getValue('birthdate', 'date')); alert(retrievedContacts[0].getValue('birthdate', 'time')); alert(retrievedContacts[0].getValueAsBoolean('donotemail')); - Use CrmServiceToolkit.Fetch() to retrieve a collection of CRM records using FetchXML query.
// Fetch all contact records whose first name is John using FetchXML query var firstname = 'John'; var fetchXml = [ "<fetch mapping='logical'>", "<entity name='contact'>", "<attribute name='contactid' />", "<attribute name='firstname' />", "<attribute name='lastname' />", "<attribute name='familystatuscode' />", "<attribute name='ownerid' />", "<attribute name='creditlimit' />", "<attribute name='birthdate' />", "<attribute name='accountrolecode' />", "<attribute name='donotemail' />", "<filter>", "<condition attribute='firstname' operator='eq' value='", firstname, "' />", "</filter>", "</entity>", "</fetch>" ].join(""); var fetchedContacts = CrmServiceToolkit.Fetch(fetchXml); alert(fetchedContacts.length); alert(fetchedContacts[0].getValue('lastname')); alert(fetchedContacts[0].getValue('firstname')); alert(fetchedContacts[0].getValue('familystatuscode'); alert(fetchedContacts[0].getValue('familystatuscode', 'name')); alert(fetchedContacts[0].getValue('creditlimit')); alert(fetchedContacts[0].getValue('creditlimit', 'formattedvalue')); alert(fetchedContacts[0].getValue('birthdate')); alert(fetchedContacts[0].getValue('birthdate', 'date')); alert(fetchedContacts[0].getValue('birthdate', 'time')); alert(fetchedContacts[0].getValueAsBoolean('donotemail')); - Use CrmServiceToolkit.Delete() to delete a CRM record.
// Use CrmServiceToolkit.Delete() to delete a CRM contact record. var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C'; var deleteResponse = CrmServiceToolkit.Delete("contact", contactId); alert(deleteResponse); - Use CrmServiceToolkit.Execute() to execute a message.
// Use CrmServiceToolkit.Execute() to execute a message. var whoAmI = CrmServiceToolkit.Execute("<Request xsi:type='WhoAmIRequest' />"); currentUserId = whoAmI.getElementsByTagName("UserId")[0].childNodes[0].nodeValue; alert("Current user's ID is " + currentUserId); - Use CrmServiceToolkit.queryByAttribute() to retrieve a CRM record using one criterion.
// Use CrmServiceToolkit.queryByAttribute() to retrieve a set of CRM records. var retrievedContacts = CrmServiceToolkit.queryByAttribute("contact", "firstname", "John"); // Retrieve all contacts whose first name is John. alert(retrievedContacts[0].getValue('lastname')); alert(retrievedContacts[0].getValue('firstname'));NOTE: In this example, I didn't specify columnSet parameter, so it will return all available fields of the contact entity, which is a really BAD practice. You should always specify what you want to get, if that's possible.
NOTE: The signature of this method has been changed in v2.1, please refer to the latest release page if you are using v2.1.
- Use CrmServiceToolkit.queryByAttribute() to retrieve a CRM record using more than one criterion, with specified column set and sorting order.
// Use CrmServiceToolkit.queryByAttribute() to retrieve a set of CRM records using more than one criterion with specified column set or sorting order var attributes = ["firstname", "lastname"]; var values = ["John", "Wayne"]; var cols = ["familystatuscode", "ownerid", "creditlimit", "birthdate", "donotemail", "donotphone"]; var orderby = ["jobtitle"]; // Sort by Job Title var retrievedContacts = CrmServiceToolkit.queryByAttribute("contact", attributes, values, cols, orderby); alert(retrievedContacts[0].getValue('middlename'));NOTE: Again, the signature of this method has been changed in v2.1, please refer to the latest release page if you are using v2.1.
- Use CrmServiceToolkit.getCurrentUserId() to get the current user's ID.
// Use CrmServiceToolkit.getCurrentUserId() to get the current user's ID. var currentUserId = CrmServiceToolkit.getCurrentUserId(); alert(currentUserId);
- Use CrmServiceToolkit.getCurrentUserRoles() to get all the system roles that the current user has been assigned to.
// Use CrmServiceToolkit.getCurrentUserRoles() to get all the system roles that the current user has been assigned to. var roles = CrmServiceToolkit.getCurrentUserRoles(); alert(roles[0]); // Prompt the user's first role.
- Use CrmServiceToolkit.isCurrentUserInRole() to check if the current user has a particular role.
// Use CrmServiceToolkit.isCurrentUserInRole() to check if the current user has a particular role. var isSystemAdministrator = CrmServiceToolkit.isCurrentUserInRole("System Administrator"); alert("I " + (isSystemAdministrator ? "AM" : "AM NOT") + " a System Administrator. ");
- The following CRM JavaScript functions have been used in order to keep the file size minimal (Aside from this reason, I am not a big fan of reinventing the wheel).
- GenerateAuthenticationHeader() function
- _HtmlEncode() function
- CrmEncodeDecode.CrmXmlDecode() function
- CrmEncodeDecode.CrmXmlEecode() function
If you ever need to run the toolkit out of the context of a CRM form, you'll need to make the above functions available to the toolkit script.
- When you retrieve records from CRM using the toolkit's Fetch, Retrieve, RetrieveMultiple, or the new queryByAttribute methods, what you get will be the instance(s) of CrmServiceToolkit.BusinessEntity, which contains all CRM attributes (fields) that have been returned from CRM. However, you should not try to access those attributes directly, instead you use the instance function - getValue() or getValueAsBoolean() to get the value of the CRM field. The reason behind this is, CRM doesn't return anything if a field's value is null, in which case your JS code will blow up if you try to access the field (attribute) directly. With that being said, you should also be informed that a CRM filed's value could be null, be sure to handle it properly in your JS code.
- As mentioned previously, when dealing with the value of CRM bit data type that you have retrieved from CRM (Only Fetch, Retrieve, RetrieveMultiple, queryByAttribute methods are really concerned), you should use getValueAsBoolean() method to get the value. This seems to be the only field type that the toolkit cannot detect correctly. For all other type of CRM fields, you can pretty much use getValue() instance method to do the job.
- The toolkit will throw error if the CRM service calls failed with any exceptions, it's always a good idea to use try/catch block to manage the potential errors. An example would be:
// It's always a good idea to contain any errors that could be thrown be the toolkit. try { var contactId = '3210F2BC-1630-EB11-8AB1-0003AAA0123C'; var cols = ["firstname", "lastname", "familystatuscode", "creditlimit", "birthdate", "donotemail"]; var retrievedContact = CrmServiceToolkit.Retrieve("contact", contactId, cols); // Do the rest of work } catch(err) { var errMsg = "There was an error when retrieving the contact information...\n\n"; errMsg += "Error: " + err.description + "\n"; alert(errMsg); } - CRM's Execute message is a versatile message. Anything that you cannot easily achieve through the other 6 messages, you should resort to the toolkit’s Execute() method. Again, please refer to MSCRM 4.0 SDK for more CRM messages.
- The toolkit release has a test page included (CrmServiceToolkitTest.aspx), which utilizes QUnit as the test engine. In order to run the test script, you should deploy it along with all other files to ISV/CrmServiceToolkit folder (Please create this folder first), then you can launch http://crmserver:port/MyOrgName/ISV/CrmServiceToolkit/CrmServiceToolkitTest.aspx to run it. If you are in good luck, you should see a screen like this:
NOTE: The unit tests will actually write a contact record to your CRM database, and it will be deleted as part of the unit tests.
[CREDITS] The idea behind CrmServiceToolkit.BusinessEntity was inspired by Ascentium CrmService JavaScript Library, after I have finished most of version 1.0 coding. Hats off to Ascentium CRM practice team.
P.S. You should probably have noticed that I have repeated most of the content in my previous toolkit release page, the reason is that I want to provide a single updated page for you to have all the information, so you don't have to go back and forth between the old release page and this release page.
Have fun with the toolkit, hope the toolkit can help you become a more productive CRM developper.
[UPDATE - July 4, 2010] A new version has been released at http://danielcai.blogspot.com/2010/07/crm-web-service-toolkit-for-javascript.html, please ensure to check out.
