Few days back I read about jquery templates, that’s an awesome jquery plugin(soon going to be part of jquery min).
jQuery templates contain markup with binding expressions ('Template tags'). Templates are applied to data objects or arrays, and rendered into the HTML DOMThis templating engine supports powerful tag lib in-built that supports conditions and iterations. For more details check this post. If you are coming from J2EE background you can treat this jquery template feature very similar to Apache Velocity and free marker templates.
Using jquery templates & Javascript Remoting together !
This mashup is important from force.com development point of view because- Remoting allows you to perform almost any apex logic via Javascript.
- Using remoting one can by pass all the hassle of view state, and performance issues because of that on complex visualforce screens.
- Mashing up these two can result in very light weight, super fast and complex visualforce screens with lesser and more human readable code
- We search for accounts for a user inputted account name using Remoting.
- Display the search results in Salesforce pageBlockStyle table without re-rendering and form submission. All using jquery templates, the lines of code required to do so is really trivial and the markup is very straight forward to understand.
Code Snippet
This code snippet is pretty similar to what you must have already seen in visualforce remoting docs. I only enhanced it for jqueryTemplate support to render a table easily. I am assuming you are already comfortable with basic Apex, HTML, jquery and visualforce. Only suggested reading is jqueryTemplates, please have a quick look at this page before diving into the code below, for easy understanding.Apex Controller – testremotingcontroller.cls
public global with sharing class testremotingcontroller {
@RemoteAction
global static Account[] searchAccounts(String accountName) {
// support * search like salesforce lookups
accountName = accountName.replaceAll('[*]', '%');
return [select id, name, phone, type, numberofemployees from
Account where name like :accountName ];
}
}Visualforce Page – testremoting.page
<apex:page controller="testremotingcontroller">
<apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"/>
<apex:includeScript value="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"/>
<apex:sectionHeader title="Javascript Remoting & jQuery Templates !"/>
<apex:pageBlock title="Accounts">
<!-- Section to draw search field for account -->
<apex:pageBlockSection title="Search Accounts" columns="2">
<apex:pageBlockSectionItem >
Account Name :
<input type = "text" id = "accountNameToSearch" />
<button onclick="searchAccounts()">Get Account</button>
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<!-- result section for showing matching accounts -->
<apex:pageBlockSection title="Matching Accounts !" columns="1">
<!--
Created Empty table using the CSS styles of visualforce pageBlockTable
This gives same look and feel
-->
<table cellspacing="0" cellpadding="0" border="0" id="searchResults" class="list ">
<colgroup span="2"></colgroup>
<thead class="rich-table-thead">
<tr class="headerRow ">
<th colspan="1" scope="col" class="headerRow">Id</th>
<th colspan="1" scope="col" class="headerRow"> Name</th>
<th colspan="1" scope="col" class="headerRow"> Phone</th>
<th colspan="1" scope="col" class="headerRow">Type</th>
<th colspan="1" scope="col" class="headerRow"> Number of Employees</th>
</tr>
</thead>
<!-- table body left empty for populating via row template using jquery -->
<tbody />
</table>
</apex:pageBlockSection>
</apex:pageBlock>
<!--
Create a named jquery template
This template represents just a result row, with binding variables for each queried field from account.
-->
<script id="resultTableRowTemplate" type="text/x-jquery-tmpl">
<tr onfocus="if (window.hiOn){hiOn(this);}" onblur="if (window.hiOff){hiOff(this);}" onmouseout="if (window.hiOff){hiOff(this);} " onmouseover="if (window.hiOn){hiOn(this);} " class="dataRow even first">
<td class="dataCell">${Id}</td>
<td class="dataCell">${Name}</td>
<td class="dataCell">${Phone}</td>
<td class="dataCell">${Type}</td>
<td class="dataCell">${NumberOfEmployees}</td>
</tr>
</script>
<script type="text/javascript">
// if you are inside some component
// use jquery nonConflict
// var t$ = jQuery.noConflict();
function searchAccounts() {
var accountName = $('#accountNameToSearch').val();
// clear previous results, if any
$("#searchResults tbody").html('');
// The Spring-11 gift from force.com. Javascript remoting fires here
// Please note "abhinav" if my org wide namespace prefix
// testremotingcontroller is the Apex controller
// searchAccounts is Apex Controller method demarcated with @RemoteAction annotation.
abhinav.testremotingcontroller.searchAccounts( accountName,
function(result, event){
if (event.status && event.result) {
$.each(event.result, function () {
// for each result, apply it to template and append generated markup
// to the results table body.
$("#resultTableRowTemplate" ).tmpl(this).appendTo( "#searchResults tbody" );
}
);
} else {
alert(event.message);
}
}, {escape:true});
}
</script>
</apex:page>Thats it guys, on executing this page and searching for records it comes up beautifully like this
Where I got stuck with javascript remoting !
I was planning to present a more rich demo with ability to inline edit Account's phone on blur i.e you change any Phone displayed on grid, on leaving the cell it will update the Account for that via Remoting. But some how Javascript seems to rollback the Account updates silently.
I posted that as an question on discussion board here. Almost same code as above is in this discussion board question, if anyone of you has any clue, please share !
6 comments:
Hi Abhinav,
Superb post. absolutely loved it. specially jquery template usage..
Keep rocking.. :)
Thanks Mohammad Swaleh,
Glad you liked it, jQuery templates are very promising, one can create really complex screens with super clean/simple code using them.
hi can you please help me in generating a picklist in any column say in type.
Not clear on your question @Avinava
Hi Abhinav,
I am landing to your blog all the time.
I know you have something.
I want to add Select Option values using JQuery and which needs to be bind with Controller.
Any help is really appreciated.
Arpit,
Creating dynamic select options that bind with Apex controller is not possible ! this is because salesforce security doesn't lets you change values of SELECTOPTIONS once they are rendered, its to avoid form injection attacks.
You might need to create a HTML SELECT via a CSV or JSON of values, and bind that JSON or CSV back to controller via apex:inputText tag.
Post a Comment