Custom Editors Setup

Prerequisites

  • To set up the Custom Editors feature, you need the following permissions:

    • Minimum permissions for the FieldFX modules you are using

    • System permissions:

      • Customize Application

      • Manage Profiles and Permission Sets

      • View Setup and Configuration

Basics

An Edit page displays when you edit a record in FieldFX Back Office

To make editing records easier, you can replace regular Edit pages with Custom Editors.

How it Works

Custom Editors are Visualforce pages that give you the ability to: * Limit the records that display available in lookups * Define the fields that display in lookups * Define the fields analyzed for keyword searches in lookups

There are five Custom Editors included in the FieldFX Base Package:

Name Object Description

CrewPlanningEditor

Crew Planning

Changes how lookups work when you add/edit a crew planning record.

EquipmentPlanningEditor

Equipment Planning

Changes how lookups work when you add/edit an equipment planning record.

JobEditor

Job

Changes how lookups work when you add or edit a job.

PriceBookRuleActionEditor

Rule Action

Changes how lookups work when you add or edit a rule action.

PriceBookRuleEditor

Rule

Changes how lookups work when you add or edit a rule.

You can also define your own Custom Editors for any FieldFX object.

Setting Up the Custom Editors Feature

  1. Access FieldFX Back Office

  2. Switch to Salesforce Classic

  3. Add an SFDCToolingAPI remote site setting:

    1. From Setup, enter "remote" in the Quick Find box, then select Remote Site Settings

    2. Click New Remote Site

    3. In Remote Site Name, enter "SFDCToolingAPI"

    4. In Remote Site URL, enter the domain in which your org runs

      To get the URL for your domain, copy the first part of the URL from the address bar in your browser, such as: https://na43.salesforce.com

      The Remote Site URL field is case-sensitive so make sure the URL you enter uses the correct capitalization.

    5. Click Active

    6. Click Save

  4. Grant permissions:

    1. From Setup, enter "permission" in the Quick Find box, then select Permission Sets

    2. Open a permission set

    3. Under Apps, click Object Settings

    4. Click CustomFieldInfo

    5. Click Edit

    6. Under Object Permissions, select Read

    7. Under Field Permissions, select Read for every field

    8. Click Save

    9. At the top of the page, click the arrow next to CustomFieldInfo and select CustomObjectInfo

    10. Click Edit

    11. Under Object Permissions, select Read

    12. Under Field Permissions, select Read for every field

    13. Click Save

    14. Repeat steps a to m for other perimission sets as needed

  5. Run scripts:

    1. Open a new tab in your browser

    2. Access Workbench

    3. Select Utilities | Apex Execute

    4. Enter the following script:

      System.debug(FX5.FXWorkerLauncher.DoWork('FX5.CustomObjectInfoHandler', null));
    5. Click Execute.

    6. Delete the script entered in step 5.d and replace it with the following script:

      System.debug(FX5.FXWorkerLauncher.DoWork('FX5.CustomFieldInfoHandler', null));
    7. Click Execute

  6. Complete the following:

CrewPlanningEditor

Basics

Use the CrewPlanningEditor to make adding/editing crew planning records easier.

The CrewPlanningEditor changes how lookups work on the Crew Planning tab as follows.

How It Works

Crew Member Lookup

Setting Value Impact

Lookup Filter

{!FXNamespace}Available_for_Field_Work__c=true AND ({!FXNamespace}Office__c=NULL OR {!FXNamespace}Office__c='{!CurrentUserContactOffice}')

Limits the list of contacts to show only those who:

  1. Have Available for Field Work selected in their Contact record and

  2. Do not have an Office assigned or are assigned to the same Office as the current user.

Fields for Available Records

Id, Name, Office, Available for Field Work, Job Title from Catalog, Email, Business Phone

The listed fields display for contacts in search results.

Fields Analyzed for Keyword Searches

Name, Email, Business Phone

Keyword searches analyze the name, email address, and phone number of contacts.

Sort Order of Available Records

Name

Contacts sort in alphabetical order by name.

Role on Job Lookup

Setting Value Impact

Lookup Filter

{!FXNamespace}Ticket_Item_Record_Type__c='Labor' AND {!FXNamespace}Price_Book__c='@@{!FXNamespace}Job__c.{!FXNamespace}Price_Book__c@@'

Only labor items from the job’s price book display available for selection.

Fields for Available Records

Id, Name, Catalog Item Code, Catalog Description

The listed fields display for price book items in search results.

Fields Analyzed for Keyword Searches

Catalog Description, Catalog Item Code

Keyword searches analyze the description and item code of price book items.

Sort Order of Available Records

Catalog Item Code

Price book items sort numerical order by item code.

Switching to Use the CrewPlanningEditor

  1. Access FieldFX Back Office

  2. Switch to Salesforce Classic

  3. Configure the CrewPlanningEditor:

    1. From Setup, enter "object" in the Quick Find box, then select Objects

    2. Click Crew Planning

    3. Under Buttons, Links, and Actions, click Edit next to Clone

    4. In Override With, select Visualforce Page and then select "CrewPlanningEditor"

    5. Click Save

    6. Under Buttons, Links, and Actions, click Edit next to Edit

    7. In Override With, select Visualforce Page and then select "CrewPlanningEditor"

    8. Click Save

    9. Under Buttons, Links, and Actions, click Edit next to New

    10. In Override With, select Visualforce Page and then select "CrewPlanningEditor"

    11. Click Save

  4. Add a RESTEndPoint remote site setting:

    1. Open the Crew Planning tab

    2. Open a crew planning record

    3. Click Edit

      • If the CrewPlanningEditor displays, proceed to step 5

      • If an error message displays, proceed to step d

    4. Copy the domain listed in the error message

      Example 1. Sample domain name to copy
    5. From Setup, enter "remote" in the Quick Find box, then select Remote Site Settings

    6. Click New Remote Site

    7. In Remote Site Name, enter "RESTEndpoint"

    8. In Remote Site URL, enter the domain you copied in step d

      The Remote Site URL field is case-sensitive so make sure the URL you enter uses the correct capitalization.

    9. Click Active

    10. Click Save

  5. Grant permission to the CrewPlanningEditor:

    1. From Setup, enter "permission" in the Quick Find box, then select Permission Sets

    2. Open a permission set for Visualforce pages

    3. Under Apps, click Visualforce Page Access

    4. Click Edit

    5. Add "FX5.CrewPlanningEditor" to Enabled Visualforce Pages

    6. Click Save

    7. Repeat steps a to f for other permission sets as needed

EquipmentPlanningEditor

Basics

Use the EquipmentPlanningEditor to make adding/editing equipment planning records easier.

The EquipmentPlanningEditor changes how lookups work on the Equipment Planning tab as follows.

How It Works

Equipment Lookup

Setting Value Impact

Lookup Filter

{!FXNamespace}Out_of_Service__c=false AND ({!FXNamespace}Office__c=null OR {!FXNamespace}Office__c='{!FXUserInfo.Contact.Office__c}')

Only equipment that doesn’t have Out of Service selected and is linked to the job’s Office displays available for selection.

Fields for Available Records

Id, Name, Serial Number, Unit Number, Office, In Service Date

The listed fields display for equipment in search results.

Fields Analyzed for Keyword Searches

Name, Serial Number, Unit Number

Keyword searches analyze the name, serial number, and unit number of equipment.

Sort Order of Available Records

Name

Equipment sorts in alphabetical order by name.

Price Book Item Lookup

Setting Value Impact

Lookup Filter

{!FXNamespace}Ticket_Item_Record_Type__c='Equipment' AND {!FXNamespace}Price_Book__c='@@{!FXNamespace}Job__c.{!FXNamespace}Price_Book__c@@'

Only equipment items from the job’s price book display available for selection.

Fields for Available Records

Id, Name, Catalog Item Code, Catalog Description

The listed fields display for price book items in search results.

Fields Analyzed for Keyword Searches

Catalog Description, Catalog Item Code

Keyword searches analyze the description and item code of price book items.

Sort Order of Available Records

Catalog Item Code

Price book items sort in numerical order by item code.

Switching ot Use the EquipmentPlanningEditor

  1. Access FieldFX Back Office

  2. Switch to Salesforce Classic

  3. Configure the EquipmentPlanningEditor:

    1. From Setup, enter "object" in the Quick Find box, then select Objects

    2. Click Equipment Planning

    3. Under Buttons, Links, and Actions, click Edit next to Clone

    4. In Override With, select Visualforce Page and then select "EquipmentPlanningEditor"

    5. Click Save

    6. Under Buttons, Links, and Actions, click Edit next to Edit

    7. In Override With, select Visualforce Page and then select "EquipmentPlanningEditor"

    8. Click Save

    9. Under Buttons, Links, and Actions, click Edit next to New

    10. In Override With, select Visualforce Page and then select "EquipmentPlanningEditor"

    11. Click Save

  4. Add a RESTEndPoint remote site setting:

    1. Open the Equipment Planning tab

    2. Open an equipment planning record

    3. Click Edit

      • If the EquipmentPlanningEditor displays, proceed to step 5

      • If an error message displays, proceed to step d

    4. Copy the domain listed in the error message.

      Example 2. Sample domain to copy
    5. From Setup, enter "remote" in the Quick Find box, then select Remote Site Settings

    6. Click New Remote Site

    7. In Remote Site Name, enter "RESTEndpoint"

    8. In Remote Site URL, enter the domain you copied in step d

      The Remote Site URL field is case-sensitive so make sure the URL you enter uses the correct capitalization.

    9. Click Active

    10. Click Save

  5. Grant permission to the EquipmentPlanningEditor:

    1. From Setup, enter "permission" in the Quick Find box, then select Permission Sets

    2. Open a permission set for Visualforce pages

    3. Under Apps, click Visualforce Page Access

    4. Click Edit

    5. Add "FX5.EquipmentPlanningEditor" to Enabled Visualforce Pages

    6. Click Save

    7. Repeat steps a to f for other permission sets as needed

JobEditor

Basics

Use the JobEditor to make adding/editing jobs easier.

The JobEditor changes how lookups work on the Jobs tab as follows.

How It Works

Customer Lookup

Setting Value Impact

Lookup Filter

"RecordType.DeveloperName!='Office'"

Only accounts that aren’t offices display available for selection.

Fields for Available Records

Id, Name, Sync to Mobile, Account Type

The listed fields display for customers in search results.

Fields Analyzed for Keyword Searches

Name

Keyword searches analyze the names of customers.

Sort Order of Available Records

Name

Customers sort in alphabetical order by name.

Office Lookup

Setting Value Impact

Lookup Filter

"RecordType.DeveloperName='Office'"

Only office accounts display available for selection.

Fields for Available Records

Id, Name, Sync to Mobile, Account Type

The listed fields display for offices in search results.

Fields Analyzed for Keyword Searches

Name

Keyword searches analyze the names of offices.

Sort Order of Available Records

Name

Offices sort in alphabetical order by name.

Price Book Lookup

Setting Value Impact

Lookup Filter

{!FXNamespace}Is_Active\__c=true AND ({!FXNamespace}Account__c=NULL OR {!FXNamespace}Account__c='@@this.{!FXNamespace}CustomerAccount__c@@') AND ({!FXNamespace}Office__c=NULL OR {!FXNamespace}Office__c='@@this.{!FXNamespace}Office__c@@') AND ({!FXNamespace}Segment__c=NULL OR {!FXNamespace}Segment__c='@@this.{!FXNamespace}Segment__c@@')

Only active price books linked to the job’s customer, office, or segment display available for selection.

Fields for Available Records

Name,{!FXNamespace}Account__r.Name,{!FXNamespace}Office__r.Name,{!FXNamespace}Segment__c

The listed fields display for price books in search results.

Fields Analyzed for Keyword Searches

Name,{!FXNamespace}Account__r.Name,{!FXNamespace}Office__r.Name,{!FXNamespace}Segment__c

Keyword searches analyze the name, customer, office, and segment of price books.

Sort Order of Available Records

Name

Price books sort in alphabetical order by name.

Switching to Use the JobEditor

  1. Access FieldFX Back Office

  2. Switch to Salesforce Classic

  3. Configure the JobEditor:

    1. From Setup, enter "object" in the Quick Find box, then select Objects

    2. Click Job

    3. Under Buttons, Links, and Actions, click Edit next to Clone

    4. In Override With, select Visualforce Page and then select "JobEditor"

    5. Click Save

    6. Under Buttons, Links, and Actions, click Edit next to Edit

    7. In Override With, select Visualforce Page and then select "JobEditor"

    8. Click Save

    9. Under Buttons, Links, and Actions, click Edit next to New

    10. In Override With, select Visualforce Page and then select "JobEditor"

    11. Click Save

  4. Add a RESTEndPoint remote site setting:

    1. Open the Jobs tab

    2. Open a job

    3. Click Edit

      • If the JobEditor displays, proceed to step 5

      • If an error message displays, proceed to step d

    4. Copy the domain listed in the error message

      Example 3. Sample domain to copy
    5. From Setup, enter "remote" in the Quick Find box, then select Remote Site Settings

    6. Click New Remote Site

    7. In Remote Site Name, enter "RESTEndpoint"

    8. In Remote Site URL, enter the domain you copied in step d

      The Remote Site URL field is case-sensitive so make sure the URL you enter uses the correct capitalization.

    9. Click Active

    10. Click Save

  5. Grant permission to the JobEditor:

    1. From Setup, enter "permission" in the Quick Find box, then select Permission Sets

    2. Open a permission set for Visualforce pages

    3. Under Apps, click Visualforce Page Access

    4. Click Edit

    5. Add "FX5.JobEditor" to Enabled Visualforce Pages

    6. Click Save

    7. Repeat steps a to f for other permission sets as needed

PriceBookRuleActionEditor

Basics

Use the PriceBookRuleActionEditor to make adding/editing rule actions easier.

The PriceBookRuleActionEditor changes how lookups work on the Rule Actions tab as follows.

How It Works

Price Book Item Lookup

Setting Value Impact

Lookup Filter

{!FXNamespace}Price_Book__c='@@{!FXNamespace}Price_Book_Rule__c.{!FXNamespace}Price_Book__c@@'

Only items from the rule’s price book display available for selection.

Fields for Available Records

Id, Name, Catalog Item Code, Catalog Description

The listed fields display for price book items in search results.

Fields Analyzed for Keyword Searches

Catalog Description, Catalog Item Code

Keyword searches analyze the description and item code of price book items.

Sort Order of Available Records

Catalog Item Code

Price book items sort in numerical order by item code.

Switching to Use the PriceBookRuleActionEditor

  1. Access FieldFX Back Office

  2. Switch to Salesforce Classic

  3. Configure the PriceBookRuleActionEditor:

    1. From Setup, enter "object" in the Quick Find box, then select Objects

    2. Click Rule Action

    3. Under Buttons, Links, and Actions, click Edit next to Clone

    4. In Override With, select Visualforce Page and then select "PriceBookRuleActionEditor"

    5. Click Save

    6. Under Buttons, Links, and Actions, click Edit next to Edit

    7. In Override With, select Visualforce Page and then select "PriceBookRuleActionEditor"

    8. Click Save

    9. Under Buttons, Links, and Actions, click Edit next to New

    10. In Override With, select Visualforce Page and then select "PriceBookRuleActionEditor"

    11. Click Save

  4. Add a RESTEndPoint remote site setting:

    1. Open the Jobs tab

    2. Open a job

    3. Click Edit

      • If the PriceBookRuleActionEditor displays, proceed to step 5

      • If an error message displays, proceed to step d

    4. Copy the domain listed in the error message

      Example 4. Sample domain to copy
    5. From Setup, enter "remote" in the Quick Find box, then select Remote Site Settings

    6. Click New Remote Site

    7. In Remote Site Name, enter "RESTEndpoint"

    8. In Remote Site URL, enter the domain you copied in step d

      The *Remote Site URL field is case-sensitive. Make sure the URL you enter uses the correct capitalization.

    9. Click Active

    10. Click Save

  5. Grant permission to the PriceBookRuleActionEditor:

    1. From Setup, enter "permission" in the Quick Find box, then select Permission Sets

    2. Open a permission set for Visualforce pages

    3. Under Apps, click Visualforce Page Access

    4. Click Edit

    5. Add "FX5.PriceBookRuleActionEditor" to Enabled Visualforce Pages

    6. Click Save

    7. Repeat steps a to f for additional permission sets as needed

PriceBookRuleEditor

Basics

Use the PriceBookRuleEditor to make adding/editing rules easier.

The PriceBookRuleEditor changes how lookups work on the Rules tab as follows.

How It Works

Price Book Item Lookup

Setting Value Impact

Lookup Filter

({!FXNamespace}Price_Book\__c='@@this.{!FXNamespace}Price_Book__c@@' OR {!FXNamespace}Price_Book\__r.Name='@@this.{!FXNamespace}Price_Book__c@@')

Only items from the rule’s price book display available for selection.

Fields for Available Records

Id, Name, Catalog Item Code, Catalog Description

The listed fields display for price book items in search results.

Fields Analyzed for Keyword Searches

Catalog Description, Catalog Item Code

Keyword searches analyze the description and item code of price book items.

Sort Order of Available Records

Catalog Item Code

Price book items sort in numerical order by item code.

Switching to the PriceBookRuleEditor

  1. Access FieldFX Back Office

  2. Switch to Salesforce Classic

  3. Configure the PriceBookRuleEditor:

    1. From Setup, enter "object" in the Quick Find box, then select Objects

    2. Click Rule

    3. Under Buttons, Links, and Actions, click Edit next to Clone

    4. In Override With, select Visualforce Page and then select "PriceBookRuleEditor"

    5. Click Save

    6. Under Buttons, Links, and Actions, click Edit next to Edit

    7. In Override With, select Visualforce Page and then select "PriceBookRuleEditor"

    8. Click Save

    9. Under Buttons, Links, and Actions, click Edit next to New

    10. In Override With, select Visualforce Page and then select "PriceBookRuleEditor"

    11. Click Save

  4. Add a RESTEndPoint remote site setting:

    1. Open the Jobs tab

    2. Open a job

    3. Click Edit

      • If the PriceBookRuleEditor displays, proceed to step 5

      • If an error message displays, proceed to step d

    4. Copy the domain listed in the error message

      Example 5. Sample domain to copy
    5. From Setup, enter "remote" in the Quick Find box, then select Remote Site Settings

    6. Click New Remote Site

    7. In Remote Site Name, enter "RESTEndpoint"

    8. In Remote Site URL, enter the domain you copied in step d

      The *Remote Site URL field is case-sensitive. Make sure the URL you enter uses the correct capitalization.

    9. Click Active

    10. Click Save

  5. Grant permission to the PriceBookRuleEditor:

    1. From Setup, enter "permission" in the Quick Find box, then select Permission Sets

    2. Open a permission set for Visualforce pages

    3. Under Apps, click Visualforce Page Access

    4. Click Edit

    5. Add "FX5.PriceBookRuleEditor" to Enabled Visualforce Pages

    6. Click Save

    7. Repeat steps a to f for other permission sets

Defining Your Own Custom Editors

  • You can define your own Custom Editors.

  • Custom Editors involve creating a VisualForce page to use in place of the standard Salesforce edit page.

  • The steps for creating a Custom Editor for Quotes are detailed in the example below.

  • Use the Quote example below as a model for creating your own Custom Editors.

To ensure the VisualForce page for custom editors renders fields in the same order as they appear in the FieldFX Back Office page layout, you must set the Custom FX Setting CustomEditorRenderPlaceHolder__c to TRUE and include the following code in the VisualForce page:

<apex:repeat value="{!LayoutSections}" var="s">
  <apex:pageBlockSection columns="{!s.columns}" title="{!s.heading}">
  <apex:repeat value="{!s.fields}" var="f">
    <apex:inputField value="{!EntityObj[f.fieldName]}" styleClass="fxdatafield {!f.fieldName}" required="{!f.required}" html-data-fieldname="{!f.fieldName}" rendered="{!AND(f.type =='Field', OR(AND(IsInsert, f.editableForNew), AND(NOT(IsInsert),f.editableForUpdate)))}" />
    <apex:outputField value="{!EntityObj[f.fieldName]}" styleClass="fxdatafield {!f.fieldName}" html-data-fieldname="{!f.fieldName}" rendered="{!AND(f.type=='Field', OR(AND(IsInsert, NOT(f.editableForNew)), AND(NOT(IsInsert), NOT(f.editableForUpdate))))}" />
  <apex:outputText styleClass="dataCol empty" value="" rendered="{!NOT(f.type=='Field')}" />
</apex:repeat>

Example: Defining a Custom Editor for Quotes

Description

In this example, we will show you how to define a Custom Editor for quotes.

Feature Impact

Once we set up this Custom Editor, lookups on the Quotes tab work as follows.

Customer Lookup
Setting Value Impact

Lookup Filter

"RecordType.DeveloperName='Customer' AND {!FXNamespace}IsArchived__c=false"

Only customer accounts that aren’t marked archived display available for selection.

Fields for Available Records

Id, Name

The listed fields display for customers in search results.

Fields Analyzed for Keyword Searches

Name

Keyword searches analyze the names of customers.

Sort Order of Available Records

Name

Customers sort in alphabetical order by name.

Office Lookup
Setting Value Impact

Lookup Filter

"RecordType.DeveloperName='Office' AND {!FXNamespace}IsArchived__c=false"

Only office accounts that aren’t marked archived display available for selection.

Fields for Available Records

Id, Name

The listed fields display for offices in search results.

Fields Analyzed for Keyword Searches

Name

Keyword searches analyze the names of offices.

Sort Order of Available Records

Name

Offices sort in alphabetical order by name.

Price Book Lookup
Setting Value Impact

Lookup Filter

{!FXNamespace}Is_Active__c=true AND ({!FXNamespace}Account__c=NULL OR {!FXNamespace}Account__c='@@this.{!FXNamespace}CustomerAccount__c@@') AND ({!FXNamespace}Office__c=NULL OR {!FXNamespace}Office__c='@@this.{!FXNamespace}Office__c@@') AND ({!FXNamespace}Segment__c=NULL OR {!FXNamespace}Segment__c='@@this.{!FXNamespace}Segment__c@@')

Only active price books linked to the job’s customer, office, or segment display available for selection.

Fields for Available Records

Name,{!FXNamespace}Account__r.Name,{!FXNamespace}Office__r.Name,{!FXNamespace}Segment__c

The listed fields display for price books in search results.

Fields Analyzed for Keyword Searches

Name,{!FXNamespace}Account__r.Name,{!FXNamespace}Office__r.Name,{!FXNamespace}Segment__c

Keyword searches analyze the name, customer, office, and segment of price books.

Sort Order of Available Records

Name

Price books sort in alphabetical order by name.

Setup Instructions

  1. Access FieldFX Back Office

  2. Switch to Salesforce Classic

  3. Create a new FXEditorSearcher Visualforce page:

    1. From Setup, enter "pages" in the Quick Find box, then select Visualforce Pages

    2. Click New

    3. In Label, enter "FXEditorSearcher"

    4. Copy the following code:

      <apex:page controller="FX5.FXEditorSearchController" title="{!SearcherTitle}" showHeader="false" sideBar="false" id="pg" lightningstylesheets="true">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <apex:sectionHeader title="{!SearcherTitle}" rendered="true"/>
        <apex:form >
          <apex:outputpanel id="page" layout="block" style="margin:5px;padding:5px;padding-top:2px;">
            <apex:actionregion >
              <apex:outputpanel id="top" layout="block" style="margin:5px;padding:5px;padding-top:2px;">
                <apex:outputlabel value="Keyword" style="font-weight:Bold;padding-right:5px;" for="txtSearch" />
                <apex:inputtext id="txtSearch" value="{!KeywordString}" />
                <span style="padding-left:5px"><apex:commandbutton id="btnGo" onclick="EnableMe('btnGo', false);EnableMe('txtSearch', false)" value="Go" status="searchstatus" action="{!Search}" rerender="searchResults" oncomplete="EnableMe('btnGo', true);EnableMe('txtSearch', true);setsearchfocus();"></apex:commandbutton></span>
                <apex:outputlabel style="padding-left:25px" value="Wildcard '*' search is not supported." />
              </apex:outputpanel>
              <div id="clearresults" style="display: none;">
                <apex:outputpanel id="clearsearch">
                  &#60;
                <apex:commandlink value="Clear Search Results" rerender="searchResults" onclick="j$('[id$=\'txtSearch\']').val('');EnableMe('btnGo', false);EnableMe('txtSearch', false)" status="searchstatus" action="{!Search}" oncomplete="EnableMe('btnGo', true);EnableMe('txtSearch', true);setsearchfocus();" />
                 <br />
                 <br />
                 <br />
                 </apex:outputpanel>
              </div>
              <apex:outputpanel id="pnlSearchResults" style="margin:5px;height:350px;overflow-Y:auto;" layout="block">
                <apex:actionstatus id="searchstatus">
                  <apex:facet name="start">
                    <apex:outputpanel >
                      <apex:image value="/img/loading32.gif" style="height: 15px" />
                    </apex:outputpanel>
                  </apex:facet>
                  <apex:facet name="stop">
                    <apex:pageblock id="searchResults">
                      <apex:pageblocktable value="{!results}" var="a" id="tblResults">
                        <apex:column >
                          <apex:facet name="header">
                            <apex:outputpanel >Name</apex:outputpanel>
                          </apex:facet>
                          <apex:outputlink value="javascript:top.window.opener.lookupPick2('{!FormTag}','{!TextBox}_lkid','{!TextBox}','{!a.Id}', &#39;{!a['Name']}&#39;, false)" rendered="{!NOT(ISNULL(a.Id))}">{!a["Name"]}</apex:outputlink>
                        </apex:column>
                        apex:repeat value="{!DisplayColumns}" var="f">
                         <apex:column >
                           <apex:facet name="header">
                             <apex:outputpanel >{!f.Label}</apex:outputpanel>
                           </apex:facet>
                           <apex:outputlabel value="{!a[f.FieldPath]}" rendered="{!NOT(ISNULL(a[f.FieldPath]))}" />
                         </apex:column>
                        /apex:repeat>
                      </apex:pageblocktable>
                    </apex:pageblock>
                  </apex:facet>
                </apex:actionstatus>
              </apex:outputpanel>
            </apex:actionregion>
          </apex:outputpanel>
        </apex:form>
      
        <script type="text/javascript">
          var j$ = jQuery.noConflict();
            j$(document).ready(function() {
              j$("[id$='txtSearch']:first").focus();
              var defaultsearch = getUrlParameter('lksrch');
              if (defaultsearch != undefined) {
                if (j$("[id$='txtSearch']").val() != defaultsearch) {
                  j$("[id$='txtSearch']").val(defaultsearch);
                  j$("[id$='btnGo']").trigger("click");
                }
              }
            });
          j$("[id$='txtSearch']").keydown(function(e) {
            if (e.keyCode == 13) {
              e.preventDefault();
              j$("[id$='btnGo']").trigger("click");
            }
          });
         function getUrlParameter(sParam) {
           var sPageURL = decodeURIComponent(window.location.search.substring(1)),
           sURLVariables = sPageURL.split('&'),
           sParameterName, i;
           for (i = 0; i < sURLVariables.length; i++) {
             sParameterName = sURLVariables[i].split('=');
             if (sParameterName[0] === sParam) {
               return sParameterName[1] === undefined ? true : sParameterName[1];
             }
           }
         };
         function EnableMe(objid, enabled) {
           if (objid != undefined && enabled != undefined) {
             if (enabled == false) {
               j$('input[id$=' + objid + ']').attr('disabled', 'disabled');
               j$('input[id$=' + objid + ']').addClass('btnDisabled');
               j$("#clearresults").hide();
             } else {
               j$('input[id$=' + objid + ']').removeAttr('disabled', 'disabled');
               j$('input[id$=' + objid + ']').removeClass('btnDisabled');
             }
           }
          }
         function setsearchfocus() {
           j$('input[id$=txtSearch]').focus();
           if (j$("[id$='txtSearch']").val() != '') {
             j$("#clearresults").show();
           } else {
             j$("#clearresults").hide();
           }
         }
        </script>
      </apex:page>
    5. Replace the code on the Visualforce Markup tab by pasting over it with the code you copied

    6. Click the Version Settings tab

    7. Click -- Select to Add Installed Package -- and select "FieldFX Base Package"

    8. Click Save

  4. Add the FXQuoteEditor:

    1. From Setup, enter "pages" in the Quick Find box, then select Visualforce Pages

    2. Click New

    3. In Label, enter "FXQuoteEditor"

    4. Copy the following code:

      <apex:page standardcontroller="FX5__Quote__c" extensions="FX5.FXEditorController,FX5.UtilityGetInstanceUrl" sidebar="false" tabstyle="FX5__Quote__c" lightningstylesheets="true">
        <apex:sectionheader title="Edit {!EntityTypeDisplayLabel}" rendered="{!NOT(IsInsert)}" />
          <apex:sectionheader title="New {!EntityTypeDisplayLabel}" rendered="{!IsInsert}" />
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
            <apex:includescript value="https://code.jquery.com/jquery-2.2.4.min.js" />
            <script src="https://cdn.fieldfx.com/{!$Api.Session_ID}/{!FXNamespaceWithoutUnderscores + '__'}/customeditor/LATEST/main.js?sitePrefix={!$Site.Prefix}&siteDomain={!$Site.Domain}&instanceUrl={!instanceUrl}" type="text/javascript"></script>
            <apex:form id="editorForm">
               <apex:pagemessages />
               <apex:pageblock mode="edit" id="pbMain">
                  <apex:pageblockbuttons >
                    <apex:commandbutton action="{!save}" value="Save" id="cmdSave" />
                    <apex:commandbutton action="{!saveAndNew}" value="Save & New" id="cmdSaveAndNew" />
                    <apex:commandbutton action="{!doCancel}" value="Cancel" immediate="true" />
                  </apex:pageblockbuttons>
                  <apex:repeat value="{!LayoutSections}" var="s">
                    <apex:pageblocksection columns="{!s.columns}" title="{!s.heading}" collapsible="false">
                      <apex:repeat value="{!s.fields}" var="f">
                        <apex:inputfield value="{!EntityObj[f.fieldName]}" styleclass="fxdatafield {!f.fieldName}" required="{!f.required}" html-data-fieldname="{!f.fieldName}" />
                      </apex:repeat>
                    </apex:pageblocksection>
                  </apex:repeat>
                </apex:pageblock>
               <apex:inputhidden value="{!LayoutJsonString}" />
            </apex:form>
            <script type="text/javascript">
               var customSearch = '{!FXNamespace}CustomerAccount__c,{!FXNamespace}Office__c,{!FXNamespace}Price_Book__c';
               var searchAttrs = `{
                "{!FXNamespace}CustomerAccount__c" : {
                    "QueryFilter" : "RecordType.DeveloperName='Customer' AND {!FXNamespace}IsArchived__c=false",
                    "QueryFields" : "Id,Name",
                    "KeywordSearchFields" : "Name",
                    "OrderBy" : "Name"
                },
                "{!FXNamespace}Office__c" : {
                   "QueryFilter" : "RecordType.DeveloperName='Office' AND {!FXNamespace}IsArchived__c=false",
                   "QueryFields" : "Id,Name",
                   "KeywordSearchFields" : "Name",
                   "OrderBy" : "Name"
                },
                "{!FXNamespace}Price_Book__c" : {
                  "QueryFilter" : "{!FXNamespace}Is_Active__c=true AND ({!FXNamespace}Account__c='@@this.{!FXNamespace}CustomerAccount__c@@' OR {!FXNamespace}Global_Price_Book__c=true)",
                  "QueryFields" : "Name,{!FXNamespace}Account__r.Name,{!FXNamespace}Office__r.Name,{!FXNamespace}Segment__c",
                  "KeywordSearchFields" : "Name,{!FXNamespace}Account__r.Name,{!FXNamespace}Office__r.Name,{!FXNamespace}Segment__c",
                  "OrderBy" : "Name"
                }
               }`;
              function openLookup(baseURL, width, modified, searchParam) {
                var j$ = jQuery.noConflict();
                var originalbaseURL = baseURL;
                var originalwidth = width;
                var originalmodified = modified;
                var originalsearchParam = searchParam;
                var entityType = '{!EntityType}';
                var entityId = '{!EntityId}';
                var originatorId = '{!ReturnUrlObjectId}';
                var lookupType = getParameterByName('lktp', baseURL);
                var lookupCustomFieldId = getParameterByName('lknm', baseURL);
                var ctrl = j$('[Id$="' + lookupCustomFieldId + '"]')[0];
                var lookupCustomField = j$(ctrl).data('fieldname');
                if (modified == '1') baseURL = baseURL + searchParam;
                var pIndex = baseURL.indexOf('?');
                var params = baseURL.substring(pIndex);
                var isCustomLookup = customSearch.indexOf(lookupCustomField) !== -1;
                console.log('isCustomLookup for ' + lookupCustomField + ' : ' + isCustomLookup);
                if (isCustomLookup == true) {
                    var urlArr = baseURL.split("&");
                    var txtId = '';
                    if (urlArr.length > 2) {
                      urlArr = urlArr[1].split('=');
                      txtId = urlArr[1];
                    }
                    params = params.replace('&lknm=' + encodeURIComponent(lookupCustomFieldId), '&lknm=' + lookupCustomField);
                    console.log('params: ' + params);
                    var jsonSubjectEntity = getContextEntity();
                    // Following is the url of Custom Lookup page. You need to change that accordingly
                    baseURL = "/apex/FXEditorSearcher" + params;
                    baseURL += "&txt=" + txtId;
                    baseURL += "&subjectType={!EntityType}&subjectId={!EntityId}&originatorId={!ReturnUrlObjectId}";
                    baseURL += "&subjectEntity=" + escapeUTF(jsonSubjectEntity);
                    // Following is the id of apex:form control "myForm". You need to change that accordingly
                    baseURL = baseURL + "&frm=" + escapeUTF("{!$Component.editorForm}");
                    if (modified == '1') {
                    baseURL = baseURL + "&lksearch=" + searchParam;
                  }
                  baseURL = baseURL + "&searchAttrs=" + searchAttrs;
                  openPopup(baseURL, "lookup", 350, 480, "width=" + width + ",height=480,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no", true);
                } else {
                    if (modified == '1') originalbaseURL = originalbaseURL + originalsearchParam;
                    openPopup(originalbaseURL, "lookup", 350, 480, "width=" + originalwidth + ",height=480,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no", true);
                }
              }
            </script>
      </apex:page>
    5. Replace the code on the Visualforce Markup tab by pasting over it with the code you copied

    6. Click the Version Settings tab

    7. Click -- Select to Add Installed Package -- and select "FieldFX Base Package"

    8. Click Save

  5. Configure the FXQuoteEditor:

    1. From Setup, enter "object" in the Quick Find box, then select Objects

    2. Click Quote

    3. Under Buttons, Links, and Actions, click Edit next to Clone

    4. In Override With, select Visualforce Page and then select "FXQuoteEditor"

    5. Click Save

    6. Under Buttons, Links, and Actions, click Edit next to Edit

    7. In Override With, select Visualforce Page and then select "FXQuoteEditor"

    8. Click Save

    9. Under Buttons, Links, and Actions, click Edit next to New

    10. In Override With, select Visualforce Page and then select "FXQuoteEditor"

    11. Click Save

  6. Add a RESTEndPoint remote site setting:

    1. Open the Quote tab

    2. Open a quote

    3. Click Edit

      • If the FXQuoteEditor displays, proceed to step 7

      • If an error message displays, proceed to step d

    4. Copy the domain listed in the error message.

      Example 6. Sample domain to copy
    5. From Setup, enter "remote" in the Quick Find box, then select Remote Site Settings

    6. Click New Remote Site

    7. In Remote Site Name, enter "RESTEndpoint"

    8. In Remote Site URL, enter the domain you copied in Step d

      The Remote Site URL field is case-sensitive. Make sure the URL you enter uses the correct capitalization.

    9. Click Active

    10. Click Save

  7. Grant permission to use the new Visualforce pages you added:

    1. From Setup, enter "permission" in the Quick Find box, then select Permission Sets

    2. Open a permission set for Visualforce pages

    3. Under Apps, click Visualforce Page Access

    4. Click Edit

    5. Add "FXEditorSearcher" and "FXQuoteEditor" to Enabled Visualforce Pages

    6. Click Save

    7. Repeat steps a to f for other permission sets as needed