In the latest release of CRM 2016 Online there have been some great new features added to the product. One of which that solves a problem that most of us as CRM Developers have faced on multiple occasions, auto-complete/auto-suggest.
We have all had the requirement at some point in time. What the client really wants is a mixture between a free form text field, and a picklist. So they can get suggestions on values to enter, or enter in an entirely new value. With the new keypress events that we can attach to through our form scripts, we are able to provide that type of functionality. Let’s take a look at how to make that work.
New Methods
There are a couple of new functions that power this feature. Quick note: the below methods are not supported in the CRM Mobile Clients, and is only available for Update entities inside of CRM. This also means that you need the new form rendering engine (i.e. Turbo Forms) enabled.
- The new getValue method is to retrieve the value of a control. This method is different from the getValue method from the attribute because the control method is able to retrieve the value from the control as it is entered in by the user, instead of after the user has entered the value.
- To configure the auto complete portion, there is showAutoComplete/hideAutoComplete.
- And to hook up the auto complete configuration to the control, there is addOnKeyPress.
Example
The SDK example for this code is a great starting point. But this also assumes that you want to have the values for your auto complete list hard coded as an array in your form script code. This would obviously will work, but maybe isn’t exactly where we want to store this information. For this example, we will have an xml file that has our list, and our function will read the xml list into an array and attach it to a control. We are going to attach to the Salutation Field on the Lead Form.
XML File
The following xml file holds our list of Salutations.
<?xml version="1.0" encoding="utf-8" ?> <Salutations> <Salutation Name= "Mr." /> <Salutation Name= "Ms." /> <Salutation Name= "Mrs." /> <Salutation Name= "Miss" /> <Salutation Name= "Dr." /> <Salutation Name= "Prof."/> <Salutation Name= "Hon." /> <Salutation Name= "Br." /> <Salutation Name= "Sr." /> <Salutation Name= "Fr." /> <Salutation Name= "Rev." /> <Salutation Name= "Pr." /> <Salutation Name= "Pres."/> <Salutation Name= "Elder"/> </Salutations>
Javascript Function
Our JavaScript function is taken from the SDK, but parameterized, so not only can we use an XML file to power our list, but we can also now call this from any Form, or Form Script just by supplying the required parameters. Before we show the code, let’s talk about the parameters:
- xmlPath: The path to the xml file from wherever we are currently
- xmlItem: The xml node that we want to search for in case we use one xml file for all of the different lists. In our example xml file, Salutation.
- xmlAttr: The specific attribute of the node in the xml file. In our example file, Name.
- crmFieldName: The name of the CRM control that we want to hook this up to.
- commandLabel: The label of the command that appears in the autocomplete drop down.
- windowLink: The hyperlink that is connected to the command label in the autocomplete drop down.
Now that we have talked about the parameters, here is the code.
function AutoComplete(xmlPath, xmlItem, xmlAttr, crmFieldName, commandLabel, windowLink) { try { var control = Xrm.Page.getControl(crmFieldName); if (!control) return; if (typeof ($) === "undefined") { $ = parent["$"]; jQuery = parent["jQuery"]; } $.ajax({ type: "GET", url: xmlPath, dataType: "xml", success: function (data) { var autoCompleteList = []; $(data).find(xmlItem).each(function () { autoCompleteList.push({ name: $(this).attr(xmlAttr) }); }); var keyPressFcn = function (ext) { try { var userInput = Xrm.Page.getControl(crmFieldName).getValue(); var resultSet = { results: new Array(), commands: { id: "sp_commands", label: commandLabel, action: function () { // Specify what you want to do when the user // clicks the link at the bottom // of the auto-completion list. window.open(windowLink); } } }; var userInputLowerCase = userInput.toLowerCase(); for (var i = 0; i < autoCompleteList.length; i++) { if (userInputLowerCase === autoCompleteList[i].name.substring(0, userInputLowerCase.length).toLowerCase()) { resultSet.results.push({ id: i, fields: [autoCompleteList[i].name] }); } } if (resultSet.results.length > 0) { ext.getEventSource().showAutoComplete(resultSet); } else { ext.getEventSource().hideAutoComplete(); } } catch (e) { // Handle any exceptions. In the sample code, // we are just displaying the exception, if any. console.log(e); } }; Xrm.Page.getControl(crmFieldName).addOnKeyPress(keyPressFcn); } }); } catch (e) { alert("Error with AutoComplete; Description - " + e.description); } }
If we look at the above code we can break it in to 3 pieces to describe what is happening.
- We make an ajax call to go get the XML file and read it in to our array.
- Define the function that handles receiving the user input and searching our autocomplete list to show suggestions.
- Attach the function to the key press event of our control.
Bring it all Together
So we have our xml file and javascript function. Let’s see how to hook this up and get some results.
1. Upload all required files into CRM. We need jQuery since we are performing AJAX operations.
2. Set up the function to be called on the OnLoad event of the Lead Form.
3. Make sure Turbo Forms are enabled.
With all of that in place, if we navigate to a new Lead Form, click in the Salutation field, and either hit Backspace, or start typing, we should see the following.
Summary
This example showed how to add Auto Completion using an XML list to a text box control. You could see that there are other possibilities to build up our list, maybe using an entity to store the data that we could make an API call to grab, even search all current records grabbing the values that have already been entered in that field.
The nice part is that we are finally able to solve a very common problem without having to come up with some very inventive custom code as we are getting nice out of the box functions to use. Let us know if you have any questions!
Happy Coding!