How to hide a field in a SharePoint EditForm.aspx page, append a replica, add a jQuery autocomplete, and put the selected value in the original field.

If you look at this old post, you can see a technique that I used to hide a form field, and then append read-only data after it. I wanted to use this technique to hide a field in a form, append a replica with a jQuery autocomplete, and based on the selected value from the drop down, put the value in the original filed. I actually wanted a comma separated concatenation of all the selected values (multiple lookups). For example, I wanted to create a form to capture all the people at a meeting, the the attendees field would be hidden and replaced with a input box that can lookup contact GUIDs from a CRM, and once the contact is selected, the GUID is appended to the contents of the original Attendees field.

First up, the code to hide the field I want:

	attendeesRow='<tr id="attendeesRow"> \
		<td nowrap="true" valign="top" width="190px" class="ms-formlabel"><h3 class="ms-standardheader"><nobr>Attendee<nobr></h3></td> \
		<td valign="top" class="ms-formbody" width="400px"> \
		<div id="AddAttendees"><input type="text" id="AddAttendeesSearchTextbox" /> (add an EXISTING CRM Contact)</div><br/> \
		</td></tr>';
	$('nobr:contains("Attendees")').closest('tr').hide();
	$('nobr:contains("Attendees")').closest('tr').before(attendeesRow);

Lines 1-5 is the code for the new replica field
Line 6 hides the existing field
Line 7 prepends the new replicate created in Lines 1-5

Next is the jQuery code to attach an autocomplete to the new text box (AddAttendeesSearchTextbox). I am using a little knockout to organize my code and I use some of the observable arrays to make the page more dynamic.

$('#AddAttendeesSearchTextbox).autocomplete({
	    source: function (request, response) { VM.contactsSearchSourceREST(request, response) },
		delay: 600,
		minLength: 3,
		select: function(event, ui) {
			var selectedObj = ui.item;
			VM.addAttendee(selectedObj.fullname,"","",selectedObj.ParentCustomerIdName,"5",selectedObj.id)
			$(this).val("");
			return false;
		}
	});

And here is the javascript code (part of the view model) that is used for the source of the jQuery AutoComplete (CRM 2011 oData REST endpoint). Just a simple ajax call to CRM 2011.

	self.contactsSearchSourceREST = function (request, response) {
	    var serverUrl = "crm.server.com"
	    var ODATA_ENDPOINT = "/ORGNAME/XRMServices/2011/OrganizationData.svc";
	    var ODATA_EntityCollection = "/ContactSet";
	    var strSelect = "$select=FullName,ParentCustomerId,ContactId"
	    var strFilter = "$filter=substringof('" + request.term + "',FullName) and StateCode/Value eq 0"
	    var URL = serverUrl + ODATA_ENDPOINT + ODATA_EntityCollection + "?" + strFilter + "&" + strSelect
	    //alert(URL);
	    $.ajax({
	        type: "GET",
	        contentType: "application/json",
	        datatype: "json",
	        async: false,
	        url: URL,
	        beforeSend: function (XMLHttpRequest) {
	            XMLHttpRequest.setRequestHeader("Accept", "application/json");
	            XMLHttpRequest.setRequestHeader("Content-Type", "application/json")
	        },
	        success: function (data, textStatus, XmlHttpRequest) {
	            response($.map(data.d.results, function (item) {
	                return {
	                    label: item.FullName + ' (' + item.ParentCustomerId["Name"] + ')',
	                    value: item.FullName + ' (' + item.ParentCustomerId["Name"] + ')',
	                    fullname: item.FullName,
	                    ParentCustomerIdName: item.ParentCustomerId["Name"],
	                    id: item.ContactId
	                }
	            }));
	        },
	        error: function (XMLHttpRequest, textStatus, errorThrown) {
	            alert("failure " + errorThrown);
	            return false;
	        }
	    });
	}

Next is the knockout code (part of the view model) that is used to push the new contact guid into an observable array upon selecting the AutoCompleted contact

    self.Attendees = ko.observableArray();
    self.contact = function(fullname, firstname, lastname,ParentCustomerIdName, activitypartytype, guid) {
	this.fullname = fullname;
	this.firstname = firstname;
	this.lastname = lastname;
	this.ParentCustomerIdName = ParentCustomerIdName;
	this.role = activitypartytype;
	this.guid = guid;
    };
    self.addAttendee = function(fullname, firstname, lastname,ParentCustomerIdName, activitypartytype, guid) {
        self.Attendees.push(new self.contact(fullname, firstname, lastname,ParentCustomerIdName, activitypartytype, guid));
        return
    };

And finally the knockout code to concatenate the GUIDs and put them in the hidden (original) field (Attendees).

    ko.utils.arrayForEach(self.Attendees(), function(contact) {
        total = total + contact.guid + ';'
    	});
    total = total.substring(0, total.length - 1);
    $('input[type=text][title="Attendees"]').val(total)
    return total
	});

Pretty complex, lots of different techniques bing used (knockout, jQuery, ajax). Hope it makes sense.

, , ,

Comments are closed.