Thursday, November 16, 2017

Using Ajax and JavaScript in a Visualforce Page

Using Ajax in a Page

Some Visualforce components are Ajax aware and allow you to add Ajax behaviors to a page without having to write any JavaScript. The following topics provide examples:

Implementing Partial Page Updates with Command Links and Buttons

One of the most widely used Ajax behaviors is a partial page update, in which only a specific portion of a page is updated following some user action, rather than a reload of the entire page.
The simplest way to implement a partial page update is to use the reRender attribute on an <apex:commandLink> or <apex:commandButton> tag to identify a component that should be refreshed. When a user clicks the button or link, only the identified component and all of its child components are refreshed.
For example, consider the contact list example shown in Getting and Setting Query String Parameters on a Single Page. In that example, when a user clicks the name of a contact in the list to view the details for that contact, the entire page is refreshed as a result of this action. With just two modifications to that markup, we can change the behavior of the page so that only the area below the list refreshes:
  1. First, create or identify the portion of the page that should be rerendered. To do this, wrap the <apex:detail> tag in an <apex:outputPanel> tag, and give the output panel an id parameter. The value of id is the name that we can use elsewhere in the page to refer to this area. It must be unique in the page.
  2. Next, indicate the point of invocation (the command link) that we want to use to perform a partial page update of the area that we just defined. To do this, add a reRender attribute to the <apex:commandLink> tag, and give it the same value that was assigned to the output panel's id.
The final markup looks like this:
<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are displaying contacts from the {!account.name} account. 
        Click a contact's name to view his or her details.
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:form>
            <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" 
                               border="1">
                  <apex:column>
                      <apex:commandLink rerender="detail"> 
                          {!contact.Name}
                          <apex:param name="cid" value="{!contact.id}"/>
                      </apex:commandLink>
                  </apex:column>
            </apex:dataTable>
        </apex:form>
    </apex:pageBlock>
    <apex:outputPanel id="detail"> 
        <apex:detail subject="{!$CurrentPage.parameters.cid}" relatedList="false" 
                        title="false"/>
    </apex:outputPanel> 
</apex:page>
After saving the page, click any contact and notice how the detail component displays without a complete page refresh.
Note: You cannot use the reRender attribute to update content in a table.

Providing Status for Asynchronous Operations

Ajax behaviors, such as partial page updates, are asynchronous events that occur in the background while a page user continues to work. For good usability, designers often add a status element to alert the user of any background activity currently in progress.
Visualforce supports status updates with the <apex:actionStatus> tag. This tag allows you to display text at the beginning or end of a background event with the startText or stopText attributes, or, for more advanced developers, allows you to display an image or other component.
For this example, we'll add status text to the contact list page that we have been developing. After a user clicks the name of a contact, the detail area displays the text, “Requesting...” while the detail area is rendered.
To implement the message, wrap <apex:actionStatus> around the <apex:detail> component, since that is the component being updated asynchronously. In between the two tags, add an <apex:facet> tag named “stop”.
facet consists of content in an area of a Visualforce component that provides contextual information about the data that is presented in the component. For example, <apex:dataTable> supports facets for the header, footer, and caption of a table, while <apex:column> only supports facets for the header and footer of the column. The <apex:facet> component allows you to override the default facet on a Visualforce component with your own content. Facets only allow a single child within the start and close tags.
Note: Not all components support facets. Those that do are listed in the Standard Component Reference.

In the following example, <apex:actionStatus> supports a facet named “stop” that contains the component that should be displayed as soon as the action completes—in this case, the detail area:

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are displaying contacts from the {!account.name} account. 
        Click a contact's name to view his or her details.
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:form>
            <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" 
                               border="1">
                  <apex:column>
                      <apex:commandLink rerender="detail">
                          {!contact.Name}
                          <apex:param name="cid" value="{!contact.id}"/>
                      </apex:commandLink>
                  </apex:column>
            </apex:dataTable>
        </apex:form>
    </apex:pageBlock>
    <apex:outputPanel id="detail">
        <apex:actionStatus startText="Requesting...">
            <apex:facet name="stop"> 
                <apex:detail subject="{!$CurrentPage.parameters.cid}" 
                             relatedList="false" title="false"/>
            </apex:facet>
        </apex:actionStatus> 
    </apex:outputPanel>
</apex:page>

Remember when you visit this page, to include an ID as part of the URL. For example,

https://***Salesforce_instance***/apex/ajaxAsyncStatus?id=001x000xxx3Jsxb

Applying Ajax Behavior to Events on Any Component

Using command links and buttons to implement a partial page update is relatively simple, but suppose you want to have the same page update occur just by hovering the mouse over a contact's name?
To do this with the contact list example, remove the <apex:commandLink> tag from the data table and wrap the contact name in an <apex:outputPanel> tag instead. Within this output panel, add an <apex:actionSupport> element as a sibling of the contact's name:
  • The <apex:outputPanel> tag defines the area over in which we want the specialized behavior.
  • The <apex:actionSupport> tag defines the partial page update behavior that was implemented previously by the command link.
    • The event attribute specifies the DOM event that should trigger the update. Whereas <apex:commandLink> only executes during the “onclick” event, <apex:actionSupport> can execute on any valid event such as “onclick”, “ondblclick”, or, for this example, “onmouseover”.
    • The reRender attribute specifies which part of the page should refresh.
    • The <apex:param> tag sets the value of the cid query string parameter when the specified event occurs.
The reRender attribute isn’t required. If you don’t set it, the page does not refresh upon the specified event, but ≤apex:param> still sets the name and value of cid.
The resulting markup looks like this:
<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are displaying contacts from the {!account.name} account. 
        Mouse over a contact's name to view his or her details.
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:form>
            <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" 
                               border="1">
                  <apex:column>
                      <apex:outputPanel>
                          <apex:actionSupport event="onmouseover" rerender="detail"> 
                              <apex:param name="cid" value="{!contact.id}"/>
                          </apex:actionSupport> 
                          {!contact.Name}
                      </apex:outputPanel> 
                  </apex:column>
            </apex:dataTable>
        </apex:form>
    </apex:pageBlock>
    <apex:outputPanel id="detail">
        <apex:actionStatus startText="Requesting...">
            <apex:facet name="stop">
                <apex:detail subject="{!$CurrentPage.parameters.cid}" relatedList="false" 
                                title="false"/>
            </apex:facet>
        </apex:actionStatus>
    </apex:outputPanel>
</apex:page>
After saving the page, move the mouse over any contact and notice that the detail area refreshes appropriately without clicking on it.

Using JavaScript in Visualforce Pages

Using JavaScript in Visualforce pages gives you access to a wide range of existing JavaScript functionality, such as JavaScript libraries, and other ways to customize the functionality of your pages. Action tags, such as<apex:actionFunction> and <apex:actionSupport>, support Ajax requests.
Note: By including JavaScript in a page, you are introducing the possibility of cross-browser and maintenance issues that you do not have when using Visualforce. Before writing any JavaScript, you should be sure that there is not an existing Visualforce component that can solve your problem.
The best method for including JavaScript in a Visualforce page is placing the JavaScript in a static resource, then calling it from there. For example,
<apex:includeScript value="{!$Resource.MyJavascriptFile}"/>
You can then use the functions defined within that JavaScript file within your page using <script> tags.
When using JavaScript within an expression, you need to escape quotes using a backslash (\). For example,
onclick="{!IF(false, 'javascript_call(\"js_string_parameter\")', 'else case')}"

No comments:

Post a Comment

Lightning Inter-Component Communication Patterns

Lightning Inter-Component Communication Patterns If you’re comfortable with how a Lightning Component works and want to build producti...