Monday, August 31, 2015

Javascript AS a Visualforce page

There are several reasons a developer may want or need to have a their Javascript inside a Visualforce page.  Before explaining what those reasons may be, let just look at how you go about it.

Step 1 - Create your Javascript Page

The source below comes from a page I named "TomTestJS.page"

<apex:page showHeader="false" sidebar="false" standardStylesheets="false" 
    contentType="text/javascript">
 console.log('We are here!');
 document.write('This is the Javascript');
</apex:page>

Step 2 - Include your Javascript inside another page

Use <apex:includeScript value="{!$Page.TomTestJS" /> if the Javascript needs to be loaded at the top of the page and <script src="{!$Page.TomTestJS" /> if it needs to be loaded later, perhaps after some content has been rendered to the DOM.

The page below renders:

This is the page.
This is Javascript.

<apex:page showHeader="false" sidebar="false" standardStylesheets="false">

<p>This is the page.</p>

<script src="{!$Page.TomTestJS}" />

</apex:page>

The page above included the Javascript below some page content, that's why the document.write() output appeared below the HTML output.

If we instead did it the more traditional way using <apex:includeScript /> at the top of the page, the output renders:

This is the Javascript.
This is the page.

<apex:page showHeader="false" sidebar="false" standardStylesheets="false">
<apex:includeScript value="{!$Page.TomTestJS}" />
<p>This is the page.</p>

</apex:page>

I can think of a few reasons why programmers may want to do this.  Coincidentally, there the reasons I've wanted to do this.
  1. It's easier to track the source code in a repository if the files exist as independent entities and not part of a zip file.
  2. It's easier to see when a specific Javasript was last modified
  3. It allows the Visualforce preprocessor to resolve merge fields in the Javascript before being loaded into the browser (for assets that may exist in a static resource or as another page.
  4. It allows what would normally live inside <script /> tags inside a Visualforce page to exist independently, change independently, etc.
There are other reasons, too.  Today I had to port some Javascript and HTML from a media team into a sandbox and the team had taken liberties with their templates and other references that required "fixing" to work inside Salesforce.  Moving one of these Javascript files into a page and letting the preprocessor take care of a merge field to resolve the location of a static resource worked like a charm.
Follow @TomGagne