When the user enters their information into the pre-chat form and clicks the Start Chat button, I want to:

  • Look them up in Contacts and return the most specific matches I can find based on Email, LastName, FirstName
  • If I get only 1 result and the Email matches, assign that Contact to the new case
  • If I get only 1 result and it's a LastName match, open a Search Results tab and allow the CSR to choose (or not choose) the existing contact
  • If I get more than 1 result, open a Search Results tab and allow the CSR to choose (or not choose) one of the several existing contacts
  • If I get zero results, create a new Contact with the pre-chat information prefilled

How I'm attempting to achieve this:

  • Use JS remoting to call a remote controller class that performs a SOQL search and returns the results as JSON
  • Dynamically add/remove pre-chat form hidden elements to control what the CSR sees

My Apex class is working as intended, returning contacts as granular as possible, based on Email, LastName and FirstName - in that order. It returns a list of contacts along with their Ids and other information, as well as the types of matches. For example, here's the response for a user who matches by LastName and FirstName, but not email:

  "searchType": "LastName,FirstName",
  "results": [
      "Id": "003m0000010xxxxxxx",
      "LastName": "Smith",
      "FirstName": "Daisy",
      "Email": "daisy.smith@fake-daisy-smith-email.com"
      "Id": "003m0000011xxxxxxx",
      "LastName": "Smith",
      "FirstName": "Daisy",
      "Email": "dsmith01@fake-daisy-smith-email.com"

In the case above, I would want the search results tab to open for the CSR so she can decide which Daisy Smith is correct (if either). Here's another example:

  "searchType": "Email",
  "results": [
      "Id": "003m0000012xxxxxxx",
      "LastName": "Fake",
      "FirstName": "Fake",
      "Email": "jane.doe@fake-jane-doe-email.com"

In the example above, since they matched by Email and there's only 1 result, assign this exact Contact to the Case.

I'm attempting to do this with client-side JS that receives the JSON result from the remote controller and appends/replaces pre-chat form values. I've tried several different ways to search, but so far nothing is quite working as intended. I have the following issues:

  1. When there is 1 result that matches Email, an existing contact is not mapped to the new case. Instead a new contact is created with the same Email, LastName and FirstName.
  2. Despite showing the Search Results tab correctly when there is more than 1 Contact found, the new case still makes it own assumptions for the Contact Name field, which I guess might be based on Email.

Can anyone steer me in the right direction?

Here is my Apex pre-chat form:

<apex:page showHeader="false" standardStylesheets="false" sidebar="false" docType="html-5.0" title="Live Chat" controller="RemoteController">
    <div class="livechat-prechat">
      <div class="livechat-prechat-container">
        <div class="row livechat-company-logo-container">
          <div class="col-xs">
            <img src="logo.png" class="livechat-company-logo" alt="Logo" />
            <div class="livechat-text">CHAT</div>
            <div class="livechat-close-btn"></div>
        <div class="row">
          <div class="col-xs-12">
            <div class="livechat-prechat-form-container">
              <form id="livechat-prechat-form" method="post" role="form" novalidate="novalidate" action="DYNAMICALLY_SET" class="livechat-prechat-form form-validation">
                <div class="form-group">
                  <input class="form-control" id="firstName" name="liveagent.prechat:ContactFirstName" type="text" aria-required="true" value="" placeholder=" " required="true" />
                  <label class="float-label" for="firstName">First Name</label>
                <div class="form-group">
                  <input class="form-control" id="lastName" name="liveagent.prechat:ContactLastName" type="text" aria-required="true" value="" placeholder=" " required="true" />
                  <label class="float-label" for="lastName">Last Name</label>
                <div class="form-group">
                  <input class="form-control" id="email" name="liveagent.prechat:ContactEmail" type="email" aria-required="true" value="" placeholder=" " required="true" />
                  <label class="float-label" for="email">Email</label>
                <div class="form-group">
                  <select class="form-control" id="subject" name="liveagent.prechat:CaseReason" aria-required="true" required="true" data-rule-select="true">
                    <option value="None" selected="selected">Reason for Chat</option>
                    <option value="Store Inquiry">Store Inquiry</option>
                    <option value="Return Inquiry">Return Inquiry</option>
                    <option value="General Information or Feedback">General Information or Feedback</option>
                    <option value="Order Inquiry">Order Inquiry</option>
                    <option value="Product Inquiry">Product Inquiry</option>
                <!-- Static values -->
                <input type="hidden" name="liveagent.prechat:CaseStatus" value="New" />
                <input type="hidden" name="liveagent.prechat:CaseOrigin" value="Chat" />

                <!-- Map contact/case fields to form input -->
                <input type="hidden" name="liveagent.prechat.findorcreate.map:Contact" value="FirstName,ContactFirstName;LastName,ContactLastName;Email,ContactEmail" id="contactMap" />
                <input type="hidden" name="liveagent.prechat.findorcreate.map:Case" value="Reason,CaseReason;Origin,CaseOrigin;Status,CaseStatus;Subject,Subject;SuppliedName,FullName;SuppliedEmail,ContactEmail" />
                <!-- If not found, create a contact and a case -->
                <input type="hidden" name="liveagent.prechat.findorcreate.map.doCreate:Contact" value="Email,true;FirstName,true;LastName,true" />
                <input type="hidden" name="liveagent.prechat.findorcreate.map.doCreate:Case" value="Reason,true;Origin,true;Status,true;Subject,true;SuppliedName,true;SuppliedEmail,true" />
                <!-- Save the contact/case to the transcript -->
                <input type="hidden" name="liveagent.prechat.findorcreate.linkToEntity:Contact" value="Case,ContactId" />
                <input type="hidden" name="liveagent.prechat.findorcreate.showOnCreate:Contact" value="true" />
                <input type="hidden" name="liveagent.prechat.findorcreate.showOnCreate:Case" value="true" />
                <input type="hidden" name="liveagent.prechat.findorcreate.saveToTranscript:Contact" value="ContactId" />
                <input type="hidden" name="liveagent.prechat.findorcreate.saveToTranscript:Case" value="CaseId" />
                <button class="livechat-prechat-submit-btn btn btn-block" id="prechat_submit" type="submit">Start Chat</button>
              <div class="livechat-close-btn livechat-close-link">Cancel</div>

    <!-- JS Remoting -->
    <script type="text/javascript">
        function onBeforeSubmit() {
            var email = document.getElementById('email');
            var lastName = document.getElementById('lastName');
            var firstName = document.getElementById('firstName');
            Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.RemoteController.getContacts}', (email && email.value) || '', (lastName && lastName.value) || '', (firstName && firstName.value) || '', function(results, event) {
            }, { buffer: false, escape: true, timeout: 10000 });

The startChat method:

        window.startChat = function (response) {
            var results = response.results;
            var searchType = response.searchType;

            // Creates a mapping to use in inputs - E.g. "Email,true;LastName,true"
            var mapString = searchType.split(',').map(function(type) {
                return type + ',true';

            var fullName = $('#firstName').val() + ' ' + $('#lastName').val();

            // Set dynamic fields
            prechatForm.append('<input type="hidden" name="liveagent.prechat.name" value="' + fullName + '" />');
            prechatForm.append('<input type="hidden" name="liveagent.prechat:FullName" value="' + fullName + '" />');
            prechatForm.append('<input type="hidden" name="liveagent.prechat:Subject" value="Live Chat: ' + $('#subject').val() + '" />');

            switch (results.length) {
                // No contacts found
                case 0:
                    prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="Email,true;LastName,true;FirstName,true" />');
                    prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="Email,true;LastName,true;FirstName,true" />');

                // Exact match found
                case 1:
                    if (~searchType.indexOf('Email')) {
                        // Email matches, so assign this contact
                        prechatForm.append('<input type="hidden" name="liveagent.prechat:ContactId" value="' + results[0].Id + '" />');
                        prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="ContactId,true" />');
                        prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="ContactId,true" />');
                        prechatForm.find('#contactMap').replaceWith('<input type="hidden" name="liveagent.prechat.findorcreate.map:Contact" value="FirstName,ContactFirstName;LastName,ContactLastName;Email,ContactEmail;Id,ContactId" />');
                    } else {
                        // Email does NOT match, so show search results
                        prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="' + mapString + '" />');
                        prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="' + mapString + '" />');                      

                    // Multiple contacts found, so show search results
                    prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.doFind:Contact" value="' + mapString + '" />');
                    prechatForm.append('<input type="hidden" name="liveagent.prechat.findorcreate.map.isExactMatch:Contact" value="' + mapString + '" />');

            // Submit the form and start the chat

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.