function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SoloSolo 

VF Inline Injection ("snippets") with preloader image solution

Hello All,

 

Just want to share my experinse in creating VF Inline Injection ("snippets") with preloader image

 

Overview

Using standard (native) SFDC page layouts is the most efficient and recommended way by Salesforce (SF) to present an object’s information. But in some cases where a page layout requires advanced VF logic and features, VF injection (inline embedding) need to be used.

To do VF injection, a custom VF page with controller extension has to be created for each VF injection.  VF page must use the standard controller (e.g. Account controller in case if VF injection is used on Account page), then this VF page can be embedded to page layout.

 

Implementation Details (example)

Create the Visualforce page and Controlles

You have to create the Visualforce page and controller extension. Our Visualforce page must use the standard object controller it will be assigned. After saving it will show up on the list of available Visualforce pages on the object’s page layout(s).

 

Code example

Visual page start:

<apex:page standardcontroller="Account" extensions="EXTENTION" cache="true"> <apex:outputPanel id="errMsg"> <apex:pageMessages /> </apex:outputPanel> ... your VF page code here ...

 

Design Considerations and implementation tips

 

  • VF page injections do not influence parent page performance.   They work and load in individual HTML iframe.
  • Apply general CSS styles for common elements in <style> section in the top of the VS page.
  • Do not apply inconsistent with parent and general for SF pages styles.  For example <center><font color="#000000">Industry Team Type</font></center>.  In native SF's interface, all fields in related objects aligned to the left by default.
  • Do not apply code like - <td width="16.66%" - in most cases default width works properly.
  • Keep the code structured and easy to read (use Tab to align the code lines by sections).
  • Interface use-ability is a priority #1.  Keep UI easy to understand and work with.  Move allAJAXworking areas (to add or edit records) to the top of the VF page and set all field and buttons in one row (to avoid horizontal scrolling).
  • In case the VF page has dependent fields (with dynamic pickup values changed by AJAX request), always use re-render action listener and re-rendering action status string (for example "Updating picklist values...") that will appear on the top of the page in good visible area.
  • Use the same action status string style appearance to indicate "Requesting...", "Saving..." and "Updating..." AJAXactions.
  • The height of the iframe with embedded VF page will be constant – so apply the height that would cover average list of record.  Other records will be available for review by vertical scrolling.

 

Useful VF upgrade to show user “loading” picture while VF is loading

On the VF page:

<!-- workaround to show user “loading” picture while VF is loading --> <apex:form > <!-- start of VF performance workaround --> <apex:actionFunction name="ajaxSetClientLoaded" action="{!setClientLoaded}" immediate="true" rerender="DeferredLoad"/> <script type="text/javascript">var cached_onload = window.onload; window.onload = function() { ajaxSetClientLoaded(); if (cached_onload != null) cached_onload(); }</script> <!-- opening VF performance workaround panels --> <apex:outputPanel id="DeferredLoad"> <apex:outputPanel rendered="{!NOT(clientLoaded)}"><div align="center"><img src="{!$Resource.Loading}" /></div></apex:outputPanel> <apex:outputPanel rendered="{!clientLoaded}"> <!-- end of VF performance workaround --> ... your VF page code here ... <!-- closing VF performance workaround panels --> </apex:outputPanel> </apex:outputPanel> </apex:form> </apex:page> 

 on the controller:

 

<apex:page standardcontroller="Account" extensions="IB_CCP_AccountIndustryCoverageController" boolean clientLoaded = false; public boolean getClientLoaded() { return clientLoaded; } public PageReference setClientLoaded() { clientLoaded = true; return null; } 

 

Note: $Resource.Loading is a “loading” image in GIF format saved in Static Resources

 

Regards,