Contents[Hide]

How jQuery works.

Find Something, Attach Event, Do Something

$j(".account").click(function() {
    alert("Goodbye");
    $j(this).hide();
});

Including jQuery to VS page

1. Download libraries

For developement purposes I advise to use full jQuery + UI package from http://jqueryui.com/download, later you can decide which function are not used and download smaller package or just jQuery without UI from http://jquery.com/download/

2. Create Static Resource

Upload ZIP file to static resources (salesforce is able to read zip content). Go to  Setup -> Develop -> Static Resources click "New" button and fill the Name "jQueryUI" and chose the downloaded ZIP file as shown on image below.

3. Include in VS Page

<apex:includeScript value="{!URLFOR($Resource.jQueryUI, '/js/jquery-1.7.2.min.js')}" />
<apex:includeScript value="{!URLFOR($Resource.jQueryUI, '/js/jquery-ui-1.8.22.custom.min.js')}" />
<apex:stylesheet value="{!URLFOR($Resource.jQueryUI, '/css/ui-lightness/jquery-ui-1.8.22.custom.css')}" />

Where:
jQueryUI - name given to static resource in previous step
js/jquery-1.7.2.min.js - path inside ZIP file to script library

Later you can updated this ZIP to contain additional newer versions of scripts.

4. Avoid conflicts with other scripts.

$j = jQuery.noConflict();

5. Run scripts when document is loaded.

If you need to run functions after page load place then iside function which checks if document is ready. This event will fire when DOM elements are ready, but before assets like images download.

$j(document).ready(function() {  
    myFynction();
}

myFunction(param1, param2){
   // Function content
}

6. Getting it together - slider example

<apex:page standardController="Opportunity" >
<head>
    <!-- Include jQuery libraries from Static Resource "jQueryUI" -->
        <apex:includeScript value="{!URLFOR($Resource.jQueryUI, '/js/jquery-1.7.2.min.js')}" />
        <apex:includeScript value="{!URLFOR($Resource.jQueryUI, '/js/jquery-ui-1.8.22.custom.min.js')}" />
        <apex:stylesheet value="{!URLFOR($Resource.jQueryUI, '/css/ui-lightness/jquery-ui-1.8.22.custom.css')}" />

    <script type="text/javascript">     
        var $j = jQuery.noConflict(); // Create $j to avoid conflicts with other JS libraries
        
        /* Functions executed when document is loaded */
        $j(document).ready(function() {
            changeDivToSlider();
        
        });
        
        /* Functions executed on deamand */
        function changeDivToSlider(){
            $j("#ProbabilitySlider").slider({
                min: 0,
                max: 100,
                slide: function(event, ui) {
                    $j("#ProbabilitySlider").next().val(ui.value);
                },
                step: 10,
                value: {!IF(ISNULL(Opportunity.Amount),0,Opportunity.Amount)} // Read value from field when record is edited
            });    
        }
        
    </script>
    
    <!-- Additional styles definitions -->
    <style>
        <!-- Selectors: #idName .className http://www.w3.org/TR/css3-selectors/ -->
        #ProbabilitySlider {
            width: 120px;
            background: white;
            margin-bottom: 8px;      
        }
    </style>
</head>    
<body>
    <apex:form id="OpportunityEdit">
        <apex:pageBlock title="Chose Probability" id="ProbabilityEdit">
            <apex:pageMessages id="errorMsg" escape="FALSE" />
            
            <apex:pageBlockButtons location="top" >
                 <apex:commandButton value="Save" id="Save" action="{!Save}" />
                 <apex:commandButton value="Cancel" action="{!Cancel}" id="Cancel"/>
            </apex:pageBlockButtons>
            
            <apex:pageBlockSection columns="2" id="FieldsSection" >
             
                <!-- Group tags into one item (cell) of pageBlockSection -->
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Probability" />
                    <apex:outputPanel >
                    
                        <div id="ProbabilitySlider"></div>
                        <apex:inputField id="ProbabilityField" value="{!Opportunity.Amount}"/> <!-- Any text field -->        
                        
                    </apex:outputPanel>
                </apex:pageBlockSectionItem>
                
            </apex:pageBlockSection>          
        </apex:pageBlock>
    </apex:form>
</body>
</apex:page>

 

Fixing, ReRender breaks jQuery functionality

If we modify example above to do ajax save which reRender the page instead of redirecting to other page then we hit a problem that scrollbar disapears after save.

<apex:commandButton value="Save" id="Save" action="{!doAjaxSave}" reRender="FieldsSection" />

If reRender breaks your functionality use additional parameter oncomplete="functionName" to call that functionality again.

<apex:commandButton value="Save" id="Save" action="{!doAjaxSave}" reRender="FieldsSection" oncomplete="changeDivToSlider()"/>

Notice that by copy paste this code you will get an error:
Error: action="{!doAjaxSave}": Unknown method 'OpportunityStandardController.doAjaxSave()'
unless you create a controller which handle that action or simply, for testing purposes, just remove action="{!doAjaxSave}"

Find element by partial Id

When you define input field (or any other eleemnt) with specific Id you will not get the same id on page, Salesforce adds some prefix based on DOM location of element.

Example input field in VF Page code:

 <apex:inputField value="{!DA_Document__c.name}" id="name" required="true"/>

how it is shown on rendered page:

<input id="j_id0:form1:j_id4:j_id5:j_id8:name" maxlength="80" name="j_id0:form1:j_id4:j_id5:j_id8:docname" size="20" type="text">

Because of that simple

$j("#name").val()

will not work, instead you must use partial id selector like this

$j('[id*="name"]').val()

it will find all elements where id ends with "name", so be carefull with id names as it may happen that id "firstname" will be also selected as it ends with "name".

Running controller method by Javascript

<!-- Function which invokes action from controller-->
<apex:actionFunction name="updateRecord" action="{!doUpdate}" status="updateStatus"/>

<!-- Optional Status message -->
<apex:actionStatus id="updateStatus">
    <apex:facet name="start"> Updating.... </apex:facet>
</apex:actionStatus>

<!-- Script which invokes action -->
<script>
    updateRecord();
</script>

 

This article is based on:
Developing Applications with jQuery video 
Developing Applications with jQuery (#1) video
Developing Applications with jQuery (#2) video
Developing Apps with jQuery
Using jQuery in a Visualforce Page
jQuery selectors and Visualforce Component Ids
Using JavaScript with Force.com

   
© Paweł Woźniak