Dynamic Account Search
I had a business requierment that was involving coding a controller in combination wiht a Visualforce page.
The idea was to enable users to dynamically search for accounts. Looking for some ideas I found a really nice example from Jeff Douglas, you can find it here. So I took this structure and build my own page. The most interesting part of this code is the fact that you don’t event need to click a “search” button to start retriving results. As nice as that can be there are other things that I really like about this code. The simplicity and efficiency of this code are really outstanding, that is why I want to share this with you, all credit goes to Jeff of course … I’m just a messenger.
This is the controller:
[code lang="php"]
//AccountSearch controller
public with sharing class AccountSearch {
private String soql {get;set;}
public List<Account> accounts {get;set;}
public String sortDir
{
get {
if (sortDir == null)
{
sortDir = 'asc';
}
return sortDir;
}
set;
}
public String sortField
{
get {
if (sortField == null)
{
sortField = 'name';
}
return sortField;
}
set;
}
public String debugSoql {
get { return soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20'; }
set;
}
public AccountSearch()
{
soql = 'select name, industry, shippingCountry from account where name != null';
runQuery();
}
public void toggleSort()
{
sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
runQuery();
}
public void runQuery()
{
try {
accounts = Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20');
if(accounts.isEmpty())
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Sorry, there are no results on your search criteria.'));
} catch (Exception e) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Something went wrong with your search!'));
}
}
public PageReference runSearch()
{
String name = Apexpages.currentPage().getParameters().get('name');
String industry = Apexpages.currentPage().getParameters().get('industry');
String shippingCountry =Apexpages.currentPage().getParameters().get('shippingCountry');
soql = 'select name, industry, shippingCountry from account where name != null';
if (!name.equals(''))
soql += ' and name LIKE \''+String.escapeSingleQuotes(name)+'%\'';
if (!industry.equals(''))
soql += ' and name LIKE \''+String.escapeSingleQuotes(industry)+'%\'';
if (!shippingCountry.equals(''))
soql += ' and shippingCountry LIKE \''+String.escapeSingleQuotes(shippingCountry)+'%\'';
runQuery();
return null;
}
}
[/code]
I did some changes to fix a few issues I had with this controller and now works like a charm. I like the way Jeff used properties to get the SOQL query sorted, real nice touch.
Here you can find the Visualforce page for this controller:
[code lang="java"]
//AccountSearch visualforce
<apex:page controller="AccountSearch" sidebar="false" showHeader="false">
<apex:form >
<apex:pageMessages id="errors" />
<apex:pageBlock title="Account Search" mode="edit">
<table width="100%" border="0">
<tr>
<td width="200" valign="top">
<apex:pageBlock title="" mode="edit" id="criteria">
<script type="text/javascript">
function doSearch() {
searchServer(
document.getElementById("name").value,
document.getElementById("industry").value,
document.getElementById("shippingCountry").value);
}
</script>
<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
<apex:param name="name" value="" />
<apex:param name="industry" value="" />
<apex:param name="shippingCountry" value="" />
</apex:actionFunction>
<table cellpadding="2" cellspacing="2">
<tr>
<td style="font-weight:bold;">Name<br/>
<input type="text" id="name" onkeyup="doSearch();"/>
</td>
</tr>
<tr>
<td style="font-weight:bold;">Industry<br/>
<input type="text" id="industry" onkeyup="doSearch();"/>
</td>
</tr>
<tr>
<td style="font-weight:bold;">Shipping Country<br/>
<input type="text" id="shippingCountry" onkeyup="doSearch();"/>
</td>
</tr>
</table>
</apex:pageBlock>
</td>
<td valign="top">
<apex:pageBlock mode="edit" id="results">
<apex:pageBlockTable value="{!accounts}" var="account">
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Name" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="name" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!account.name}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="Industry" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="Industry" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!account.industry}"/>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink value="ShippingCountry" action="{!toggleSort}" rerender="results,debug">
<apex:param name="sortField" value="shippingCountry" assignTo="{!sortField}"/>
</apex:commandLink>
</apex:facet>
<apex:outputField value="{!account.shippingCountry}"/>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</td>
</tr>
</table>
<apex:pageBlock title="Extra Information" id="debug">
<apex:outputText value="Please refer to this information if you can't find your account" />
</apex:pageBlock>
</apex:pageBlock>
</apex:form>
</apex:page>
[/code]
Real nice and simple…