Monday, April 8, 2013

Adding Standard text to CRM 2011 Notes

The Notes section in the entity record is a easy way to keep track of changes to the record. The user text is automatically saved on "onblur" - meaning that when the focus is moved away from the editable notes pieces the information is saved to the annotation entity. The onblur feature is actually pretty nifty, as some CRM systems require you to save the note by clicking on a "Save" button. Extra clicks? No thanks!

In Notes, lets consider a scenario where the user needs to enter a few lines of canned text each time. A very common case is a set of instructions for the CSR on what information to capture from the customer. Right now, one option is to have a document with the text, and copy and paste the right sections to the Note each time. Does not sound very appetizing, does it? Here is an alternate approach that might be useful!

Business Case:
User needs to be able to add standard text to the notes section. The setup should be configurable, enabling the admin to add new canned text that the user can search for.

Design:
We will create a custom entity to hold the details of the note text. Then create a relationship to the entity that requires the standard text. On selecting the standard text name from the lookup, the note section gets populated.

Implementation Details:
1. Create a custom entity called "Notes Text" with 2 fields

  • Name - Defines the identifier for the standard text
  • Notes Text - Multi line text field that will contain the actual text to be pushed into the note. 














2. In the entity where we want the standard text enabled (in my case, the incident entity), create a new field of type lookup. Relate the "Notes Text" entity to the incident. Add the lookup field to the form, right above the notes section.

















3. Add javascript that triggers on change of the "Standard Text" field. Here is a snippet:

//function to get values from the Notes Text entity - onchange of NotesText field

function getNotesText() {

    //get form type - note will be created only on existing records

    var formType = Xrm.Page.ui.getFormType();

    var lookUpObjectValue = Xrm.Page.getAttribute("new_notestext").getValue();
    if ((lookUpObjectValue != null) && formType != 1) {
        var lookuptextvalue = lookUpObjectValue[0].name;
        var lookupType = lookUpObjectValue[0].type;
        var lookupid = lookUpObjectValue[0].id;
        //alert(lookupType);
            var serverUrl = Xrm.Page.context.getServerUrl();

            //The XRM OData end-point
            var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";


            var odataSetName = "new_notestextSet";

            var odataSelect = serverUrl + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + lookupid + "')";

        //alert(odataSelect);

            $.ajax({
                type: "GET",
                contentType: "application/json; charset=utf-8",
                datatype: "json",
                url: odataSelect,
                beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
                success: function (data, textStatus, XmlHttpRequest) {

                    var result_note = data.d;

                    //alert(result_note.new_TextValue);

                    var noteText = result_note.new_TextValue;
                    if (noteText != null) {
                        
                        //create the note
                        var regardingCase = new Object();
                        regardingCase.LogicalName = "incident";
                        regardingCase.Id = Xrm.Page.data.entity.getId();

                        var noteObj = new Object();
                        noteObj.ObjectId = regardingCase;
                        noteObj.ObjectTypeCode = "incident";
                        noteObj.NoteText = noteText;
                        noteObj.Subject = lookuptextvalue;

                        //parse into JSON
                        var noteJson = window.JSON.stringify(noteObj);

                        var odataCreate = serverUrl + ODATA_ENDPOINT + "/AnnotationSet";

                        //send request to create note
                        $.ajax({
                            type: "POST",
                            contentType: "application/json; charset=utf-8",
                            datatype: "json",
                            url: odataCreate,
                            data: noteJson,
                            beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
                            success: function (data, textStatus, XmlHttpRequest) {
                                //refresh the notes tab
                                document.getElementById("notescontrol").contentWindow.location.reload(true);

                                //set note text lookup to null
                                Xrm.Page.getAttribute("new_notestext").setValue(null);

                            },
                            error: function (XmlHttpRequest, textStatus, errorThrown) { alert('OData create Failed: ' + errorThrown); }
                        });

                        //end create note

                    }

                },
                error: function (XmlHttpRequest, textStatus, errorThrown) { alert('OData Select Failed: ' + odataSelect); }
            });

    }

    else if ((lookUpObjectValue != null) && formType == 1) {
        alert("Please Save the Incident before selecting the Notes Text");

        //set note text lookup to null
        Xrm.Page.getAttribute("new_notestext").setValue(null);
    }
}


Let me walk through the code a bit here. If the lookup Notes Text value is not null, I do an odata call to get the corresponding multi line text value. Then I create a new annotation record and attach it to the current incident. Also I clear the value of the lookup, in case the user wants to use the same text twice.

Since a note creation requires it to be attached to an existing record, if the formtype is 1 (new record), the user is shown an alert message asking him/her to save the record first.

It is also important to refresh the Notes section once the note has been successfully created.

This is what the Notes section looks like after the note has been added
















Limitations:

  1. The record needs to exist for the note to be attached to it.
  2. The user cannot "preview" the note (unless they open up the notes record)

Hope this helps!

6 comments:

  1. Hi Mani,

    Nice post,Thanks for sharing this information .



    Dynamics CRM Developers

    ReplyDelete
  2. hey mani,
    I have similar requirement of showing the notes text added by the previous user in the notes sections. But somehow i couldn't make this work for me. i used your code and i see the error: unable to get value of the property 'name' :object is null or undefined. i have added the Jquery and json library also to this.
    Any help would be greatly appreciated.

    ReplyDelete
    Replies
    1. Gary, I am not sure I understand the requirement- the post does not address the visibility of the notes text added by another user.

      Still, if you have issues with the JS, i would suggest a couple of things:
      1. Make sure the user creating the note has the right security privilege
      2. Put a "debugger" statement in the JS and step through the code using IE developer tools.

      Hope this helps!

      Delete
  3. Is there a way that we could do that. Showing the user , date time stamp under the edited notes in notes section.

    Thanks,
    Gary

    ReplyDelete
  4. Hi Mani,

    Nice article and thanks for the share.
    I have below requirement,

    After user attached document to the Note, need to prompt a alert saying "Please create Task ...etc".
    Is it possible to catch the attach event ?

    Thanks

    ReplyDelete