Saturday, 4 June 2011

Execute Custom Search when Opening Page

This week's post is another generated from posts on the Salesforce discussion boards.

The scenario that was troubling the poster was as follows:

  • They had written a custom search page
  • When the results of the search were displayed, the user could click on a result and be taken to another page to edit the record
  • Once the change was made, the user should be returned to the search page
  • The search page should display the previous list of results - i.e. retain the query that was executed
It was the final bullet point that was causing the problem - how to retain the query through the call to the edit page and back again.

In this example, I'm using the standard Salesforce edit page.

The controller code is shown below:

public class RetUrlSearchController 
{
 public String nameQuery {get; set;}
 public List<Account> accounts {get; set;}
 
 public PageReference executeSearch()
 {
  String queryStr='%' + nameQuery + '%';
  accounts=[select id, Name, BillingStreet 
            from Account 
            where name like :queryStr];
           
  return null;
 }
 
 public RetUrlSearchController()
 {
  // if query appears in URL, execute it
  String urlQuery=ApexPages.currentPage().getParameters().get('query');
  
  if ( (null!=urlQuery) && (0!=urlQuery.length()) )
  {
   nameQuery=urlQuery;
   executeSearch();
  }
 }
}

The important part of the controller is the constructor - this looks for a query string supplied in the URL and if one is found, executes the search and populates the results.

Next up the page:

<apex:page controller="RetUrlSearchController">
  <apex:form >
    <apex:pageBlock >
      <apex:pageBlockSection title="Criteria">
      <apex:outputLabel value="Enter Name Snippet"/>
      <apex:inputText value="{!nameQuery}"/>
      <apex:commandButton action="{!executeSearch}" value="Search"/>
   </apex:pageBlockSection>
   
   <apex:pageBlockTable value="{!accounts}" var="acc">
      <apex:column headerValue="Name">
         <apex:outputLink value="/{!acc.id}/e?retURL={!URLENCODE('/apex/RetUrlSearchPage?query='+nameQuery)}">{!acc.Name}</apex:outputLink>
      </apex:column>
      <apex:column value="{!acc.BillingStreet}"/>
   </apex:pageBlockTable>
 </apex:pageBlock>
  </apex:form>
</apex:page>

Notice how the link to the edit page is constructed:

<apex:outputLink value="/{!acc.id}/e?retURL={!URLENCODE('/apex/RetUrlSearchPage?query='+nameQuery)}">{!acc.Name}</apex:outputLink>

This sets the retURL parameter which will be used by Salesforce to determine which page to return the user to after their editing is complete.    As well as the page, I've also added the query that the user last entered.  Thus when the browser is returned to the RetUrlSearchPage, the constructor shown earlier will pull the query from the URL, execute the search and the page displayed to the user will be that of their last search.

Here are screenshots showing the page flow.  First up is the search page with a query executed - note there are no parameters in the URL:


I then click on the Name link and am taken to the standard edit page but with the retURL parameter set in the URL:



Note that I've edited the Billing Street value.  I then click Save, which takes me back to the search page and executes the search:


Looking at the URL shows that the query parameter is set, the search is therefore automatically executed and the edited version of the BrightGen account appears.

9 comments:

  1. it works great.
    Nice!
    Luong

    ReplyDelete
  2. Hi,

    Can u particularly brief this line of code :-

    {!acc.Name}


    I have a urgent requirement for this and this above code can work for me , but I am not able to understand this line of code.


    Thanks & Regards,
    Arun

    ReplyDelete
    Replies
    1. That is simply merge field that gets replaced with the name of the account. Its basically the same as: , which would actually be the better way to write it.

      Delete
  3. HI what about the test class for the above page

    ReplyDelete
    Replies
    1. There isn't one I'm afraid - you'll need to write it yourself.

      Delete
  4. I have second parameter Date, how can I pass date to URL param. Is there a way to retain results without running the query?

    ReplyDelete
  5. Loving the blog and this has worked like a charm! Thanks

    ReplyDelete
    Replies
    1. how we can search using more then one fields?

      Delete
  6. how we can search using more then one fields?

    ReplyDelete