+ Start a Discussion
justynjustyn 

Custom search page development

Hi

 

I have utilised the excellent demo from Jeff Douglas at http://blog.jeffdouglas.com/2010/07/13/building-a-dynamic-search-page-in-visualforce/ for building a custom dynamic search page in visual force. There is a great demo app there.

 

I have amended the code so that it works from my custom object. The page works fine, but I have an extra function that I would like but am not sure how to develop. 

 

In the search results on my VF page I want to be able to click on the name of each custom objects record so that it opens the record in the normal layout for the custom object. The custom object has a master detail relationship to Contacts and the field for this relationship has the link automatically displayed. Can anyone enlighten me as to the peice of code I need to allow the Name field to be clickable?

 

The code I have in the VF page for this field is:

 

 

<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="{!counselling_practice.name}"/>
            </apex:column>

 

 

Many thanks in advance

 

Justyn

 

Best Answer chosen by Admin (Salesforce Developers) 
justynjustyn

Bingo! Words cannot express my delight. I now just need to move on to Apex tests so that I can move it over to my production system.

 

many thanks

 

Justyn

All Answers

Jake GmerekJake Gmerek

Hello, 

 

Without seeing all the code it is hard to know for sure, but looking at the demo app that you linked to above, you should be able to make your changes with two edits.

 

1st - in the SOQL query that is built in the constructor of the controller you need to add ID as one of the fields being queryed.  This is so that you can build the URL for the Link.

 

2nd - Change your code block that you showed above to the following:

 

 

<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:outputlink value = "/{!counselling_practice.id}">
                   <apex:outputField value="!counselling_practice.name}"/>
                </ apex:outputlink>
            </apex:column>	

 Notice all we did was wrap your outputfield in an output link and used the id from step one as the value, but do not forget the leading slash.

 

Hope this helps.

 

justynjustyn

Hi

 

Thanks for the helpful tip. I followed the two steps, but must have made an error on the first one as I got an error saying value for outputField is not a dynamic binding! I don't know if you are able to but I have copied below working copies of the code for the controller and VF Page. It will be interesting to see the changes.

 

Kind regards

 

Justyn

 

CONTROLLER

 

public with sharing class ReferralSearchController {
 
  // the soql without the order and limit
  private String soql {get;set;}
  // the collection of contacts to display
  public List<Counselling_Practice__c> counselling_practices {get;set;}
 
  // the current sort direction. defaults to asc
  public String sortDir {
    get  { if (sortDir == null) {  sortDir = 'asc'; } return sortDir;  }
    set;
  }
 
  // the current field to sort by. defaults to last name
  public String sortField {
    get  { if (sortField == null) {sortField = 'name'; } return sortField;  }
    set;
  }
 
  // format the soql for display on the visualforce page
  public String debugSoql {
    get { return soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20'; }
    set;
  }
 
  // init the controller and display some sample data when the page loads
  public ReferralSearchController() {
    soql = 'select name, member__c, Counselling_Service__c, fee_amount__c, Referral_County__c, Practice_Area_Town__c, Practice_City_County__c, for_whom__c, gender__c from counselling_practice__c where name != null and currently_active__c = True';
    runQuery();
  }
 
  // toggles the sorting of query from asc<-->desc
  public void toggleSort() {
    // simply toggle the direction
    sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
    // run the query again
    runQuery();
  }
 
  // runs the actual query
  public void runQuery() {
 
    try {
      counselling_practices = Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20');
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
    }
 
  }
 
  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
 
    String name = Apexpages.currentPage().getParameters().get('name');
    String member = Apexpages.currentPage().getParameters().get('member');
    String Counselling_Service = Apexpages.currentPage().getParameters().get('Counselling_Service');
    String fee_amount = Apexpages.currentPage().getParameters().get('fee_amount');
    String Referral_County = Apexpages.currentPage().getParameters().get('Referral_County');
    String Practice_Area_Town = Apexpages.currentPage().getParameters().get('Practice_Area_Town');
    String Practice_City_County = Apexpages.currentPage().getParameters().get('Practice_City_County');
    String for_whom = Apexpages.currentPage().getParameters().get('for_whom');
    String gender = Apexpages.currentPage().getParameters().get('gender');
 
    soql = 'select name, member__c, Counselling_Service__c, fee_amount__c, Referral_County__c, Practice_Area_Town__c, Practice_City_County__c, for_whom__c, gender__c from counselling_practice__c where name != null';
    if (!name.equals(''))
      soql += ' and name LIKE \''+String.escapeSingleQuotes(name)+'%\'';
    if (!member.equals(''))
      soql += ' and member__c LIKE \''+String.escapeSingleQuotes(member)+'%\'';
     if (!Counselling_Service.equals(''))
      soql += ' and Counselling_Service__c includes (\''+Counselling_Service+'\')';
    if (!fee_amount.equals(''))
      soql += ' and fee_amount__c LIKE \''+String.escapeSingleQuotes(fee_amount)+'%\'';  
    if (!Referral_County.equals(''))
      soql += ' and Referral_County__c = \''+Referral_County+'\'';
    if (!Practice_Area_Town.equals(''))
      soql += ' and Practice_Area_Town__c LIKE \''+String.escapeSingleQuotes(Practice_Area_Town)+'%\'';
      if (!Practice_City_County.equals(''))
      soql += ' and Practice_City_County__c LIKE \''+String.escapeSingleQuotes(Practice_City_County)+'%\'';
    if (!for_whom.equals(''))
      soql += ' and for_whom__c includes (\''+for_whom+'\')';
    if (!gender.equals(''))
      soql += ' and gender__c LIKE \''+String.escapeSingleQuotes(gender)+'%\'';
      
 
    // run the query again
    runQuery();
 
    return null;
  }
 
  // use apex describe to build the picklist values
  public List<String> Counselling_Service{
    get {
      if (Counselling_Service== null) {
 
        Counselling_Service = new List<String>();
        Schema.DescribeFieldResult field = counselling_practice__c.Counselling_Service__c.getDescribe();
 
        for (Schema.PicklistEntry f : field.getPicklistValues())
          Counselling_Service.add(f.getLabel());
 
      }
      return Counselling_Service;          
    }
    set;
  }
  public List<String> Referral_County{
    get {
      if (Referral_County== null) {
 
        Referral_County = new List<String>();
        Schema.DescribeFieldResult field = counselling_practice__c.Referral_County__c.getDescribe();
 
        for (Schema.PicklistEntry f : field.getPicklistValues())
          Referral_County.add(f.getLabel());
 
      }
      return Referral_County;          
    }
    set;
  }
  public List<String> for_whom{
    get {
      if (for_whom== null) {
 
        for_whom = new List<String>();
        Schema.DescribeFieldResult field = counselling_practice__c.for_whom__c.getDescribe();
 
        for (Schema.PicklistEntry f : field.getPicklistValues())
          for_whom.add(f.getLabel());
 
      }
      return for_whom;          
    }
    set;
  }
 
}
justynjustyn

 

VISUALFORCE PAGE:

 

<apex:page controller="ReferralSearchController" sidebar="false">

 

  <apex:form >

  <apex:pageMessages id="errors" />

 

  <apex:pageBlock title="Find Me A Counsellor / Psychotherapist!" mode="edit">

 

  <table width="100%" border="0">

  <tr>  

    <td width="200" valign="top">

 

      <apex:pageBlock title="Parameters" mode="edit" id="criteria">

 

      <script type="text/javascript">

      function doSearch() {

        searchServer(

          document.getElementById("name").value,

          document.getElementById("member").value,

          document.getElementById("Counselling_Service").options[document.getElementById("Counselling_Service").selectedIndex].value,

          document.getElementById("fee_amount").value,

          document.getElementById("Referral_County").options[document.getElementById("Referral_County").selectedIndex].value,

          document.getElementById("Practice_Area_Town").value,

          document.getElementById("Practice_City_County").value,

          document.getElementById("for_whom").options[document.getElementById("for_whom").selectedIndex].value,

          document.getElementById("gender").value

          );

      }

      </script> 

 

      <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">

          <apex:param name="name" value="" />

          <apex:param name="member" value="" />

          <apex:param name="Counselling_Service" value="" />

          <apex:param name="fee_amount" value="" />

          <apex:param name="Referral_County" value="" />

          <apex:param name="Practice_Area_Town" value="" />

          <apex:param name="Practice_City_County" value="" />

          <apex:param name="for_whom" value="" />

          <apex:param name="gender" 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;">Member<br/>

        <input type="text" id="member" onkeyup="doSearch();"/>

        </td>

      </tr>

      <tr>

        <td style="font-weight:bold;">Counselling_Service<br/>

          <select id="Counselling_Service" onchange="doSearch();">

            <option value=""></option>

            <apex:repeat value="{!Counselling_Service}" var="Counselling_Service">

              <option value="{!Counselling_Service}">{!Counselling_Service}</option>

            </apex:repeat>

          </select>

        </td>

      </tr>

      <tr>

        <td style="font-weight:bold;">Fee Amount<br/>

        <input type="text" id="fee_amount" onkeyup="doSearch();"/>

        </td>

      </tr>

      <tr>

        <td style="font-weight:bold;">Referral County<br/>

          <select id="Referral_County" onchange="doSearch();">

            <option value=""></option>

            <apex:repeat value="{!Referral_County}" var="Referral_County">

              <option value="{!Referral_County}">{!Referral_County}</option>

            </apex:repeat>

          </select>

        </td>

      </tr>

      <tr>

        <td style="font-weight:bold;">Practice Area/Town<br/>

        <input type="text" id="Practice_Area_Town" onkeyup="doSearch();"/>

        </td>

      </tr>

      <tr>

        <td style="font-weight:bold;">Practice City/County<br/>

        <input type="text" id="Practice_City_County" onkeyup="doSearch();"/>

        </td>

      </tr>

      <tr>

        <td style="font-weight:bold;">For Whom<br/>

          <select id="for_whom" onchange="doSearch();">

            <option value=""></option>

            <apex:repeat value="{!for_whom}" var="for_whom">

              <option value="{!for_whom}">{!for_whom}</option>

            </apex:repeat>

          </select>

        </td>

      </tr>

      <tr>

        <td style="font-weight:bold;">Gender<br/>

        <input type="text" id="gender" onkeyup="doSearch();"/>

        </td>

      </tr>

      </table>

 

      </apex:pageBlock>

 

    </td>

    <td valign="top">

 

    <apex:pageBlock mode="edit" id="results">

 

        <apex:pageBlockTable value="{!counselling_practices}" var="counselling_practice">

 

            <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="{!counselling_practice.name}"/>

            </apex:column>

 

            <apex:column >

                <apex:facet name="header">

                    <apex:commandLink value="Member" action="{!toggleSort}" rerender="results,debug">

                        <apex:param name="sortField" value="member" assignTo="{!sortField}"/>

                    </apex:commandLink>

                </apex:facet>

                <apex:outputField value="{!counselling_practice.Member__c}"/>

            </apex:column>

            <apex:column >

                <apex:facet name="header">

                    <apex:commandLink value="Counselling_Service" action="{!toggleSort}" rerender="results,debug">

                        <apex:param name="sortField" value="Counselling_Service" assignTo="{!sortField}"/>

                    </apex:commandLink>

                </apex:facet>

                <apex:outputField value="{!counselling_practice.Counselling_Service__c}"/>

            </apex:column>

            <apex:column >

                <apex:facet name="header">

                    <apex:commandLink value="Fee Amount" action="{!toggleSort}" rerender="results,debug">

                        <apex:param name="sortField" value="fee_amount" assignTo="{!sortField}"/>

                    </apex:commandLink>

                </apex:facet>

                <apex:outputField value="{!counselling_practice.Fee_Amount__c}"/>

            </apex:column>

 

            <apex:column >

                <apex:facet name="header">

                    <apex:commandLink value="Referral County" action="{!toggleSort}" rerender="results,debug">

                        <apex:param name="sortField" value="Referral_County" assignTo="{!sortField}"/>

                    </apex:commandLink>

                </apex:facet>

                <apex:outputField value="{!counselling_practice.Referral_County__c}"/>

            </apex:column>

            <apex:column >

                <apex:facet name="header">

                    <apex:commandLink value="Practice Area/Town" action="{!toggleSort}" rerender="results,debug">

                        <apex:param name="sortField" value="Practice_Area_Town" assignTo="{!sortField}"/>

                    </apex:commandLink>

                </apex:facet>

                <apex:outputField value="{!counselling_practice.Practice_Area_Town__c}"/>

            </apex:column>

            <apex:column >

                <apex:facet name="header">

                    <apex:commandLink value="Practice City/County" action="{!toggleSort}" rerender="results,debug">

                        <apex:param name="sortField" value="Practice_City_County" assignTo="{!sortField}"/>

                    </apex:commandLink>

                </apex:facet>

                <apex:outputField value="{!counselling_practice.Practice_City_County__c}"/>

            </apex:column>

            <apex:column >

                <apex:facet name="header">

                    <apex:commandLink value="For Whom" action="{!toggleSort}" rerender="results,debug">

                        <apex:param name="sortField" value="for_whom" assignTo="{!sortField}"/>

                    </apex:commandLink>

                </apex:facet>

                <apex:outputField value="{!counselling_practice.For_Whom__c}"/>

            </apex:column>

            <apex:column >

                <apex:facet name="header">

                    <apex:commandLink value="Gender" action="{!toggleSort}" rerender="results,debug">

                        <apex:param name="sortField" value="gender" assignTo="{!sortField}"/>

                    </apex:commandLink>

                </apex:facet>

                <apex:outputField value="{!counselling_practice.Gender__c}"/>

            </apex:column>

        </apex:pageBlockTable>

 

    </apex:pageBlock>

 

    </td>

  </tr>

  </table>

 

  <apex:pageBlock title="Debug - SOQL" id="debug">

      <apex:outputText value="{!debugSoql}" />           

  </apex:pageBlock>    

 

  </apex:pageBlock>

 

  </apex:form>

 

</apex:page>

Jake GmerekJake Gmerek

Taking a look at it, the method I described should work.  Just for clarity I made a quick test page and controller that shows what I am taking about.

//Page

<apex:page Controller="Accounttest">
  
      Account Name:<apex:outputLink value="/{!testACC.id}">
          <apex:outputfield value="{!testACC.name}" />
      </apex:outputlink>
      
</apex:page>

//controller

public class Accounttest {
    public Account testACC {get;set;}
    
    public Accounttest(){
        
        testACC = [select id, name from Account where id =: ApexPages.currentPage().getParameters().get('id') LIMIT 1];
        
    }

   }

 Would you make the changes, and if you get the same error, will you post the sections of the code that you modified so that I can take a look at that?

 

justynjustyn

Hi Jake

 

I am definitely out of my league here. I have added the ID to the two soql listed in the search controller (original listed earlier):

 

 

// init the controller and display some sample data when the page loads
  public ReferralSearchController() {
    soql = 'select name, ID, member__c, Counselling_Service__c, Therapeutic_Approach__c, fee_amount__c, Referral_County__c, Practice_Area_Town__c, Practice_City_County__c, for_whom__c, gender__c from counselling_practice__c where name!= null and currently_active__c = True';
    runQuery();
  }

 

 

and also added in your sample code to the VF Page:

 

 

<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:outputlink value="/{!counselling_practice.id}">

                   <apex:outputField value="!counselling_practice.name}"/>

                </apex:outputlink>

            </apex:column>

 

 

As the original code is fairly complex it is beyond me to work out what to do which is a real shame and the code is so close to what I want to achieve. If the code for the VF page is correct, then the error I get is down to the controller code. I do know that the above soql is error free when using Force.com explorer.

 

Kind regards

 

Justyn

 

 

 

Jake GmerekJake Gmerek

Justyn, your code is missing a { on the name field:

 

<apex:outputField value="!counselling_practice.name}"/>

 

should be:

<apex:outputField value="!{counselling_practice.name}"/>

 

Sometimes those errors can be the hardest to find.  Try that and let me know if it works.

justynjustyn

Bingo! Words cannot express my delight. I now just need to move on to Apex tests so that I can move it over to my production system.

 

many thanks

 

Justyn

This was selected as the best answer
Jake GmerekJake Gmerek

No problem

SayasoniSayasoni

Were you successfull in creating the Apex Test case for this controller?

justynjustyn

Hi

 

I've not been able to do the Apex Test controllers as it is definitely out of my league without some training. A real shame and I am having to see if I can find a developer to aid.

 

Justyn

SayasoniSayasoni

I have managed to come up with a test method with 72% code coverage. Would like help in increasing the coverage.

 

Apex Controller:

public with sharing class CandidateSearchController {

    public String source { get; set; }
 
  // the soql without the order and limit
  private String soql {get;set;}
  // the collection of contacts to display
  public List<Candidates__c> candidates {get;set;}
 
  // the current sort direction. defaults to asc
  public String sortDir {
    get  { if (sortDir == null) {  sortDir = 'asc'; } return sortDir;  }
    set;
  }
 
  // the current field to sort by. defaults to last name
  public String sortField {
    get  { if (sortField == null) {sortField = 'Name'; } return sortField;  }
    set;
  }
 
  // format the soql for display on the visualforce page
  public String debugSoql {
    get { return soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20'; }
    set;
  }
 
  // init the controller and display some sample data when the page loads
  public CandidateSearchController() {
    soql = 'Select Id,First_Name__c, Name, Main_Email__c,Candidate_Source__c from Candidates__c where Name != null';
    runQuery();
  }
 
  // toggles the sorting of query from asc<-->desc
  public void toggleSort() {
    // simply toggle the direction
    sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
    // run the query again
    runQuery();
  }
 
  // runs the actual query
  public void runQuery() {
 
    try {
      candidates = Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20');
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
    }
 
  }
 
  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
 
    String firstName = Apexpages.currentPage().getParameters().get('firstName');
    String lastName = Apexpages.currentPage().getParameters().get('lastName');
    String email = Apexpages.currentPage().getParameters().get('email');
    String source = Apexpages.currentPage().getParameters().get('source');
 
    soql = 'select Id,First_Name__c, Name, Main_Email__c,Candidate_Source__c from Candidates__c where Name != null';
    if (!firstName.equals(''))
      soql += ' and First_Name__c LIKE \''+String.escapeSingleQuotes(firstName)+'%\'';
    if (!lastName.equals(''))
      soql += ' and Name LIKE \''+String.escapeSingleQuotes(lastName)+'%\'';
    if (!email.equals(''))
      soql += ' and Main_Email__c LIKE \''+String.escapeSingleQuotes(email)+'%\''; 
    if (!source.equals(''))
      soql += ' and Candidate_Source__c LIKE \''+source+'\''; 
         
    // run the query again
    runQuery();
 
    return null;
  }
 
  // use apex describe to build the picklist values
  public List<String> sources {
    get {
      if (sources == null) {
 
        sources = new List<String>();
        Schema.DescribeFieldResult field = Candidates__c.Candidate_Source__c.getDescribe();
 
        for (Schema.PicklistEntry f : field.getPicklistValues())
          sources.add(f.getLabel());
 
      }
      return sources;          
    }
    set;
  }
 }



Test Method:

@isTest
private class SearchCandidateTest {
    
     static testMethod void testCandidateSearch() {
     
      //instantiate a page     
     PageReference pg = Page.SearchCandidate;
        Test.setCurrentPage(pg);
        pg.getParameters().put('firstName', 'test first name');
        pg.getParameters().put('lastName', 'test last name');
        pg.getParameters().put('email', 'test@testmail.com');
        pg.getParameters().put('source', 'test candidate source');
     
     // instantiate the controller
        CandidateSearchController controller=new CandidateSearchController();

        System.assert(controller.runSearch() == null);
      }
 }



justynjustyn

Wow. That is very quick, and very helpful. If anyone can push the coverage to over 75% I would be much indebted.

 

Justyn

Jake GmerekJake Gmerek

Can one of you indicate which lines are not being covered by the test currently?

SayasoniSayasoni

The Red ones are not being covered.

 

Apex Controller:

public with sharing class CandidateSearchController {

    public String source { get; set; }
 
  // the soql without the order and limit
  private String soql {get;set;}
  // the collection of contacts to display
  public List<Candidates__c> candidates {get;set;}
 
  // the current sort direction. defaults to asc
  public String sortDir {
    get  { if (sortDir == null) {  sortDir = 'asc'; } return sortDir;  }
    set;
  }
 
  // the current field to sort by. defaults to last name
  public String sortField {
    get  { if (sortField == null) {sortField = 'Name'; } return sortField;  }
    set;
  }
 
  // format the soql for display on the visualforce page
  public String debugSoql {
    get { return soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20'; }
    set;
  }
 
  // init the controller and display some sample data when the page loads
  public CandidateSearchController() {
    soql = 'Select Id,First_Name__c, Name, Main_Email__c,Candidate_Source__c from Candidates__c where Name != null';
    runQuery();
  }
 
  // toggles the sorting of query from asc<-->desc
  public void toggleSort() {
    // simply toggle the direction
    sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
    // run the query again
    runQuery();
  }
 
  // runs the actual query
  public void runQuery() {
 
    try {
      candidates = Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20');
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
    }
 
  }
 
  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
 
    String firstName = Apexpages.currentPage().getParameters().get('firstName');
    String lastName = Apexpages.currentPage().getParameters().get('lastName');
    String email = Apexpages.currentPage().getParameters().get('email');
    String source = Apexpages.currentPage().getParameters().get('source');
 
    soql = 'select Id,First_Name__c, Name, Main_Email__c,Candidate_Source__c from Candidates__c where Name != null';
    if (!firstName.equals(''))
      soql += ' and First_Name__c LIKE \''+String.escapeSingleQuotes(firstName)+'%\'';
    if (!lastName.equals(''))
      soql += ' and Name LIKE \''+String.escapeSingleQuotes(lastName)+'%\'';
    if (!email.equals(''))
      soql += ' and Main_Email__c LIKE \''+String.escapeSingleQuotes(email)+'%\''; 
    if (!source.equals(''))
      soql += ' and Candidate_Source__c LIKE \''+source+'\''; 
         
    // run the query again
    runQuery();
 
    return null;
  }
 
  // use apex describe to build the picklist values
  public List<String> sources {
    get {
      if (sources == null) {
 
        sources = new List<String>();
        Schema.DescribeFieldResult field = Candidates__c.Candidate_Source__c.getDescribe();
 
        for (Schema.PicklistEntry f : field.getPicklistValues())
          sources.add(f.getLabel());
 
      }
      return sources;          
    }
    set;
  }
 }



 

 

Jake GmerekJake Gmerek
@isTest
private class SearchCandidateTest {
    
     static testMethod void testCandidateSearch() {

      /*Also to be sure that this class works correctly we should create and
       *insert some records for the object that we are running the query on
       *(Canditates__c in the above example) and then after we call runSearch()
       *check the candidates list and ensure that the first record would be the 
       *first record that is returned.  For example to check the sort by firstname,
       *we would create a candidate with the first name 'aaaaaaa'.  This would
       *ensure that the record we created would be returned first and we can check
       *to ensure that we get the proper record back. We would have to call runSearch()
       *directly after we do "pg.getParameters().put('firstName', 'test first name');" 
       *so that it would sort by first name, then we would have to unset the firstname
       *parameter and repeat the process for the next parameter and so on.  But I will 
       *leave that to you
       */
     
      //instantiate a page     
     PageReference pg = Page.SearchCandidate;
        Test.setCurrentPage(pg);
        pg.getParameters().put('firstName', 'test first name');
        pg.getParameters().put('lastName', 'test last name');
        pg.getParameters().put('email', 'test@testmail.com');
        pg.getParameters().put('source', 'test candidate source');
     
     // instantiate the controller
        CandidateSearchController controller=new CandidateSearchController();

        System.assert(controller.runSearch() == null);

	String testDebugSoql = controller.debugSoql;
	System.assert(check to see if it retruned the soql string);

	controller.toggleSort();
	System.assertequals (controller.sortDir, 'desc');

	List<String> testSources = new List<String>();
	testSources = controller.sources;
	System.assertequals (testSources[0], 'First Picklist Value');

	//to test the catch clause we need to make the query fail
        //I think that this will do it but I am not sure
	controller.sortField = 'Some invalid sort field';
	controller.runQuery();
	
      }
 }

 This should give you good code coverage, but please notice my note for proper testing.  It is also possible that without creating some records as mentioned that the test will fail when deployed to production in a clean (no data) environment since there will be no records to query.

SayasoniSayasoni

Thanks Jake, this has been really helpful.Raised the coverage to 88%

justynjustyn

Hi Jake

 

It's great that someone is helpful us work out our testing! I've taken the code you suggested and applied to my situation but get the following error:

 

Error: Compile Error: expecting a right parentheses, found 'to' at line 34 column 24

 

The relevant line of the code is:

 

   System.assert(check to see if it returned the soql string);

 

Any helpful thoughts?

 

Justyn

Jake GmerekJake Gmerek

 System.assert(check to see if it returned the soql string);

 

Sorry, the "check to see if it returned the soql string" was in the nature of a comment.  You can actually comment that line out to test your code, because essentially there is two parts to testing, code coverage and ensuring your code is doing what it is actually supposed to do.  Sales force requires the first, the second is just best practice for the user to ensure that your program does what you want it to do.  After you test it, you will probably want to add something back in, but it is not required.

justynjustyn

Hi Jake

 

The test controller is up to 40% which is good progress. I've copied below the debug log if it can be of help. I will also copy the full test controller code.The original controller code is in first couple of entries to this discussion. If you can help that would be great.

 

Justyn

 

08:41:28.869 (869253000)|FATAL_ERROR|System.NullPointerException: Attempt to de-reference a null object

22.0 APEX_CODE,FINE;APEX_PROFILING,FINE;DB,INFO;VALIDATION,INFO;WORKFLOW,FINEST
08:41:28.451 (451713000)|EXECUTION_STARTED
08:41:28.451 (451823000)|CODE_UNIT_STARTED|[EXTERNAL]|01pT0000000AFsZ|ReferralSearchControllerTest.ReferralSearchControllerTest
08:41:28.451 (451922000)|METHOD_ENTRY|[2]|01pT0000000AFsZ|ReferralSearchControllerTest.ReferralSearchControllerTest()
08:41:28.451 (451994000)|METHOD_EXIT|[2]|ReferralSearchControllerTest
08:41:28.452 (452188000)|METHOD_ENTRY|[1]|Test.Test()
08:41:28.452 (452255000)|METHOD_EXIT|[1]|Test
08:41:28.454 (454662000)|METHOD_ENTRY|[1]|01pT0000000A9jv|ReferralSearchController.ReferralSearchController()
08:41:28.455 (455773000)|METHOD_EXIT|[1]|ReferralSearchController
08:41:28.455 (455856000)|CONSTRUCTOR_ENTRY|[37]|01pT0000000A9jv|<init>()
08:41:28.456 (456226000)|METHOD_ENTRY|[29]|01pT0000000A9jv|ReferralSearchController.runQuery()
08:41:28.484 (484108000)|SOQL_EXECUTE_BEGIN|[44]|Aggregations:0|select name, ID, member__c, Counselling_Service__c, Therapeutic_Approach__c, fee_amount__c, Referral_County__c, Practice_Area_Town__c, Practice_City_County__c, for_whom__c, gender__c, donations__c, negotiable__c, free_service__c from counselling_practice__c where name != null and currently_active__c = True order by name asc limit 20
08:41:28.862 (862631000)|SOQL_EXECUTE_END|[44]|Rows:5
08:41:28.863 (863065000)|METHOD_EXIT|[29]|01pT0000000A9jv|ReferralSearchController.runQuery()
08:41:28.863 (863302000)|CONSTRUCTOR_EXIT|[37]|01pT0000000A9jv|<init>()
08:41:28.863 (863566000)|METHOD_ENTRY|[39]|01pT0000000A9jv|ReferralSearchController.runSearch()
08:41:28.868 (868745000)|EXCEPTION_THROWN|[72]|System.NullPointerException: Attempt to de-reference a null object
08:41:28.868 (868936000)|METHOD_EXIT|[39]|01pT0000000A9jv|ReferralSearchController.runSearch()

 

Controller

 

 }

@isTest
private class ReferralSearchControllerTest {
    
     static testMethod void ReferralSearchControllerTest() {

      /*Also to be sure that this class works correctly we should create and
       *insert some records for the object that we are running the query on
       *(Counselling_Practice__c in the above example) and then after we call runSearch()
       *check the counselling list list and ensure that the first record would be the 
       *first record that is returned.  For example to check the sort by firstname,
       *we would create a candidate with the first name 'aaaaaaa'.  This would
       *ensure that the record we created would be returned first and we can check
       *to ensure that we get the proper record back. We would have to call runSearch()
       *directly after we do "pg.getParameters().put('firstName', 'test first name');" 
       *so that it would sort by first name, then we would have to unset the firstname
       *parameter and repeat the process for the next parameter and so on.  But I will 
       *leave that to you
       */
     
      //instantiate a page     
     PageReference pg = Page.ReferralSearch;
        Test.setCurrentPage(pg);
        pg.getParameters().put('Name', 'test first name');
        pg.getParameters().put('Counselling_Service', 'test Addiction');
        pg.getParameters().put('Therapeutic_Approach', 'test C.B.T.');
        pg.getParameters().put('Referral_County', 'test Wicklow');
        pg.getParameters().put('Practice_Area_Town', 'test Bray');
        pg.getParameters().put('Practice_City_County', 'test Shankhill');
        pg.getParameters().put('for_whom', 'test Couples');
        pg.getParameters().put('gender', 'test male');
        pg.getParameters().put('donations', 'test Yes');
        pg.getParameters().put('negotiable', 'test No');
        pg.getParameters().put('fee_amount', 'test 70');
        pg.getParameters().put('free_service', 'test Yes');
     
     // instantiate the controller
        ReferralSearchController controller=new ReferralSearchController();

        System.assert(controller.runSearch() == null);

    String testDebugSoql = controller.debugSoql;
  //  System.assert(check to see if it returned the soql string);

    controller.toggleSort();
    System.assertequals (controller.sortDir, 'desc');

    List<String> testCounselling_Service = new List<String>();
    testCounselling_Service = controller.Counselling_Service;
    System.assertequals (testCounselling_Service[0], 'First Picklist Value');

    List<String> testTherapeutic_Approach = new List<String>();
    testTherapeutic_Approach = controller.Therapeutic_Approach;
    System.assertequals (testTherapeutic_Approach[0], 'First Picklist Value');
    
    List<String> testReferral_County = new List<String>();
    testReferral_County = controller.Referral_County;
    System.assertequals (testReferral_County[0], 'First Picklist Value');
    
    List<String> testfor_whom = new List<String>();
    testfor_whom = controller.for_whom;
    System.assertequals (testfor_whom[0], 'First Picklist Value');
    
    //to test the catch clause we need to make the query fail
        //I think that this will do it but I am not sure
    controller.sortField = 'Some invalid sort field';
    controller.runQuery();
    
      }

justynjustyn

The test result detail from the Apex test is below. I assume the main issue are erroros on lines 72 & 39 :



Apex Test Result Detail

 
Time Started29/06/2011 16:31
ClassReferralSearchControllerTest
Method NameReferralSearchControllerTest
Pass/FailFail
Error MessageSystem.NullPointerException: Attempt to de-reference a null object
Stack TraceClass.ReferralSearchController.runSearch: line 72, column 10
Class.ReferralSearchControllerTest.ReferralSearchControllerTest: line 39, column 23
External entry point
Jake GmerekJake Gmerek

Justyn, which line in referral search controller is line 72?  I know approx. where it is, but I want to make sure I am looking at the right one.

justynjustyn

Hi

 

I've copied the relevant lines below:

 

Class.ReferralSearchController.runSearch: line 72, column 10

72          if (!member.equals(''))

73          soql += ' and member__c LIKE \''+String.escapeSingleQuotes(member)+'%\'';

 

 

Class.ReferralSearchControllerTest.ReferralSearchControllerTest: line 39, column 23

39         System.assert(controller.runSearch() == null);

 

 

Kind regards

 

Justyn

Jake GmerekJake Gmerek

Hey Justyn,

 

It looks like your test code is not initializing the member variable to anything.  Normally when the runSearch function is called, all of your variables are being initialized to "" by your VF page, but since there is no VF page to do that you have to explicitly do that in the test code.

 

 pg.getParameters().put('Member', 'Test Member');

 

That should take care of this error at least.

justynjustyn

Up to 80% coverage with that little change! I've just tried to deploy it to the Production setting but it says I only have 70% coverage. Do you think we can easily tweek extra?

 

Justyn

Jake GmerekJake Gmerek

Show me what is not covered still, you may have a problem though.  Salesforce requires that to deploy any code, ALL of your code must total 75% coverage, so it is possible that we could get this code to 100% and still not get your entire org to 75%, but it depends on the amount of other code you have.  Anyway, that was just a heads up, if you show me what is still not being covered, I will do my best to help you.

justynjustyn

Hi

 

I had a sudden thought that I should also deploy the ReferralSearchControllerTest as well as my ReferralSearchController and ReferralSearch Visualforce page? When validating this in Production it fails for this reason:

 



ReferralSearchControllerTest.ReferralSearchControllerTest()Class505Failure Message: "System.AssertException: Assertion Failed: Expected: Abuse, Actual: First Picklist Value", Failure Stack Trace: "Class.ReferralSearchControllerTest.ReferralSearchControllerTest: line 50, column 5 External entry point"

 

Line 50 in the Test Controller is:

 

System.assertequals (testCounselling_Service[0], 'First Picklist Value');

 

Should it say First Picklist Value, or be the actual value?

 

I can't get a revised coverage value until I've done this bit. Feels like we are so close to pushing it over the line!

 

Justyn

Jake GmerekJake Gmerek

It should be the actual value.

justynjustyn

We have 100% code coverage. I've just successfully deployed it to our Production setting. Thank you ever so much!

 

Justyn

Jake GmerekJake Gmerek

No problem, glad to help!!

Arish_KhanArish_Khan

Hi Jake,


 

I am trying to implement the same type of custom dynamic search for a Custom Object Candidates which contains a particular Canidate record. But the same type of code is not working for me.

 

Please check my VF Page code and Controller below and correct me if there is something wrong i am following.

 

 

------------------------------------------------------------------------------------------------

Apex Controller

------------------------------------------------------------------------------------------------

 

public with sharing class CandidateSearchController {

 

 // the soql without the order and limit
  private String soql {get;set;}

 

 // the collection of Candidates to display
  public List<Candidate__c> candidates {get;set;}

 

  public String firstName{get;set;}
  public String lastName{get;set;}
  public String emailid {get;set;}
 
  // the current sort direction. defaults to asc
  public String sortDir {
    get  { if (sortDir == null) {  sortDir = 'asc'; } return sortDir;  }
    set;
  }
 
  // the current field to sort by. defaults to last name
  public String sortField {
    get  { if (sortField == null) {sortField = 'Last_Name__c'; } return sortField;  }
    set;
  }

  // format the soql for display on the visualforce page
  public String debugSoql {
    get { return soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20'; }
    set;
  }

  // init the controller and display some sample data when the page loads
  public CandidateSearchController() {
    soql = 'Select Id, Last_Name__c, First_Name__c, Email__c From Candidate__c';
    runQuery();
  }

  // toggles the sorting of query from asc<-->desc
  public void toggleSort() {
    // simply toggle the direction
    sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
    // run the query again
    runQuery();
  }

  // runs the actual query
  public void runQuery() {

    try {
      candidates = Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20');
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
    }

  }

  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {

    firstName = Apexpages.currentPage().getParameters().get('firstName');
    lastName = Apexpages.currentPage().getParameters().get('lastName');
    emailid = Apexpages.currentPage().getParameters().get('emailid');
   
    soql = 'Select Id, Last_Name__c, First_Name__c, Email__c From Candidate__c';
    if (!firstName.equals(''))
    system.debug('First Name of the candidate is: **************'+firstName);
      soql += 'and First_Name__c LIKE \''+String.escapeSingleQuotes(firstName)+'%\'';
    if (!lastName.equals(''))
      soql += 'and Last_Name__c LIKE \''+String.escapeSingleQuotes(lastName)+'%\'';
    if (!emailid.equals(''))
      soql += 'and Email__c LIKE  \''+String.escapeSingleQuotes(emailid)+'%\'';

    // run the query again
    runQuery();

    return null;
  }


}

 

 

-------------------------------------------------------------------------------------

VisualForce Page

-------------------------------------------------------------------------------------

 

 

 <apex:page controller="CandidateSearchController" sidebar="false">
  <apex:form >
  <apex:pageMessages id="errors" />
 
<apex:pageBlock title="Find Me A Candidate!" >
<table width="100%" border="0">
<tr>
<td width="200" valign="top">

      <apex:pageBlock title="Parameters" mode="edit" id="criteria">
     
        <script type="text/javascript">
          function doSearch() {
            searchServer(
              document.getElementById("firstName").value,
              document.getElementById("lastName").value,
              document.getElementById("emailid").value
              );
          }
        </script>
     
        <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
          <apex:param name="firstName" value="" />
          <apex:param name="lastName"  value="" />
          <apex:param name="emailid"   value="" />
        </apex:actionFunction>
     
<table cellpadding="2" cellspacing="2">
    <tr>
        <td style="font-weight:bold;">First Name<br/>
        <apex:inputText id="firstName" value="{!firstName}" >
            <apex:actionsupport event="onkeyup" onbeforedomupdate="doSearch();"/>
        </apex:inputText>
        </td>
    </tr>
  
   <tr>
        <td style="font-weight:bold;">Last Name<br/>
        <apex:inputText id="lastName" value="{!lastName}" >
            <apex:actionsupport event="onkeyup" onbeforedomupdate="doSearch();"/>
        </apex:inputText>
        </td>
    </tr>
  
   <tr>
        <td style="font-weight:bold;">Email<br/>
        <apex:inputText id="emailid" value="{!emailid}" >
            <apex:actionsupport event="onkeyup" onbeforedomupdate="doSearch();"/>
        </apex:inputText>
        </td>
    </tr>
   
</table>

</apex:pageBlock>
</td>
<td valign="top">

    <apex:pageBlock id="results">

        <apex:pageBlockTable value="{!candidates}" var="contact">

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="First Name" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="{!firstName}" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputlink value="/{!contact.Id}">
                <apex:outputField value="{!contact.First_Name__c}"/>
                </apex:outputlink>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Last Name" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="{!lastName}" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputlink value="/{!contact.Id}">
                    <apex:outputField value="{!contact.Last_Name__c}"/>
                </apex:outputlink>
            </apex:column>
           
            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Email" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="{!emailid}" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputlink value="/{!contact.Id}">
                <apex:outputField value="{!contact.Email__c}"/>
                </apex:outputlink>
            </apex:column>
           
</apex:pageBlockTable>
</apex:pageBlock>

</td>

</tr>
</table>



  <apex:pageBlock title="Debug - SOQL" id="debug">
      <apex:outputText value="{!debugSoql}"/>
  </apex:pageBlock>   

  </apex:pageBlock>

  </apex:form>

</apex:page>

SayasoniSayasoni

Are you getting any errors and if so what type of error?

Arish_KhanArish_Khan

Hi Sayasoni,

 

No I am not getting Error. It just the search is not working. I am not sure of any specific reason for this issue.

When I am entering any thing in the input boxes its not returning the output instead its displaying the same thing as before.

Jake GmerekJake Gmerek

Hello, does the sample data display when the page loads?

 

I have a feeling that your problem is in the <apex:actionSupport> tag.  In the Documentataion it states that if the action attribute is not set then the page will simply refresh.  If that is strictly followed then your JavaScript is never getting called because there is no DOM update.  I would probably try this:

 

 <input type="text" id="firstName" onkeyup="doSearch();"/>

 

and see if it works.  You also should not need the value attribute on the input tag since that is used for displaying a default value and you are not rerendering that section so the value will never be displayed, however the entered seach criteria should never go away as well.  I believe that you should be able to use the <apex:inputText> tag as well as it does support the onkeyup event.

 

Let me know if this does not work and I will give you some more debugging device.

 

 

Arish_KhanArish_Khan

Hi Jake,

 

I have fixed issue. Actually the problem was in Apex Controller into the query.

 

anyways Many thanks for your valuable time.

 

---

Regards

Arish

Jake GmerekJake Gmerek

So it actually is registering that as a DOM update?  That is good to know!

 

Jake

Arish_KhanArish_Khan

Jake,

 

No it was not actually doing the Dom Update. I do have changed the input text code to

 

<input type="text" id="firstName" onkeyup="doSearch();"/>

 

Later I noticed that in the query there was a bug i made changes into that and its work great.

 

thanks

Arish

Jake GmerekJake Gmerek

Cool, thanks for letting me know, I am glad you got it working!!

justynjustyn

Hi Jake

 

I don't know if you are able to help with another query I have on my search page. The system has been invaluable to us, and I am now looking to make additional tweeks.

 

The code displays the members name and be default is is a click through to the Contact record. What I want is for it to just display the name and not be clickable.

 

The relevant section of the visualforce page is:

 

 <apex:column >               

<apex:facet name="header">                   

<apex:commandLink value="Member" action="{!toggleSort}" rerender="results,debug">                       

<apex:param name="sortField" value="member" assignTo="{!sortField}"/>                   

</apex:commandLink>               

</apex:facet>               

<apex:outputField value="{!counselling_practice.Member__c}"/>           

</apex:column>

 

No worries if its not something you can help with.

 

Regards

 

Justyn

 

justynjustyn

Any advice on the controller and visualforce page code to use for checkboxes? I have everything else working perfectly apart from these particular field types.


Thanks


Justyn

Jake GmerekJake Gmerek

I have never actually had the need to do that before.  I have read where people have used images, basically if the cell is true display an image of a checked box if not display an unchecked box.  I am fairly busy for the next couple of days, but if you can not get it, I can get something mocked up for you later in the week.

justynjustyn

Hi Jake

 

My problem is more with getting the filter box to work. It happily displays a tick or not in the result section, but my empty field box for typing in the value for searching on does not like True, or False. The debug message says:

 

select name, ID, member__c, Counselling_Service__c, Therapeutic_Approach__c, fee_amount__c, Interests_Skills__c, Language__c, Referral_County__c, Practice_Area_Town__c, Practice_City_County__c, for_whom__c, gender__c, donations__c, negotiable__c, free_service__c from counselling_practice__c where name != null and currently_active__c = True and donations__c LIKE 'true%' order by Current_Year_Referrals__c asc limit 20

Jake GmerekJake Gmerek

I am not 100% sure what you are asking, I think you copied and pasted the wrong thing as that is not a debug message.  So you are saying that there is a problem when you type true or false into the search field?

justynjustyn

Hi

 

You are right in that it isn't a debug message as such, but it is a something that is shown on the demo () to aid sorting problems. The problem is with the true or false in the search field. The relevant section from the search controller is:

 

 if (!donations.equals(''))      soql += ' and donations__c LIKE \''+String.escapeSingleQuotes(donations)+'%\'';

 

I'm assuming that this must be incorrect in some way?

 

Regards

 

Justyn

Jake GmerekJake Gmerek

I see now, I know what debug message that you are talking about. Is donations__c a boolean field(checkbox) or a text field?  True and False are Literal Constants but you are passing it as a string (i.e. 'true%') so if donations__c is a boolean it is not matching to the string, I would think.  You could try this to check my conjecture:

 

soql += ' and donations__c = donations';

 

If donations__c is a string than that change will not work.

 

Another suggestion that I have is that you could download the force.com explorer from here:

 

http://wiki.developerforce.com/index.php/ForceExplorer

 

This will let you run a test query against the db if you copy and paste that debug code that you gave me above.  You can manually tweak it till you get the result that you need and then if you post the valid soql query here, I can help you create some Apex to generate it.

 

Let me know if this helps!

justynjustyn

HI Jake

 

Very helpful. You are correct in that the donations__c field is a checkbox. The code you mentioned presents the following message when I type true into the donations field search box :

 

select name, ID, member__c, Counselling_Service__c, Therapeutic_Approach__c, fee_amount__c, Interests_Skills__c, Language__c, Referral_County__c, Practice_Area_Town__c, Practice_City_County__c, for_whom__c, gender__c, donations__c, negotiable__c, free_service__c from counselling_practice__c where name != null and currently_active__c = True and donations__c = donations order by Current_Year_Referrals__c asc limit 20

 

Obviously the info is incorrect. If it replace it with True in Force Exlorer it presents the correct info:

 

select name, ID, member__c, Counselling_Service__c, Therapeutic_Approach__c, fee_amount__c, Interests_Skills__c, Language__c, Referral_County__c, Practice_Area_Town__c, Practice_City_County__c, for_whom__c, gender__c, donations__c, negotiable__c, free_service__c from counselling_practice__c where name != null and currently_active__c = True and donations__c = true order by Current_Year_Referrals__c asc limit 20

 

Is there an appropriate piece of code that work? On the one hand the ideal would be to have the search criteria on my visualforce page being a tick box rather than typing in True or False, and for it to then filter correctly. For now I'd be happy for the True ro False to work.

 

Thanks.

 

Justyn

Jake GmerekJake Gmerek

Sorry, I was still half asleep when I wrote that.

 

Try this:

 

soql += ' and donations__c = ' + donations;

 

That should make the two queries match.

justynjustyn

Hi Jake 

 

That is perfect. Thanks. 

 

You don't know the steps to make the data from the custom object publicly viewable on the visualforce page? I have the page added to my site.

 

No worries if not you have been really helpful already.

 

Regards

 

Justyn

Jake GmerekJake Gmerek

I wrote a long drawn out answer on this then noticed the emphasis on publically and had to change tracks completely.  :)

 

What you need to do is set up Force.com sites.  It is on the setup page under Develop->Sites.  Basically it will walk you through setting up a public facing URL, then you create a site and just add your VF page to it.  I have not done it in awhile but from what I remember it is pretty straight forward.  Let me know if you have questions.

 

Jake

justynjustyn

Hi Jake

 

Thanks. I'd done that previously put the actual information for my custom object isn't displaying. The filters all seem to work in that there are no error messages, but the rows of info aren't displaying. I've also atted Counselling PRactice as Read in the Guest User License profile. 

 

A strange one. I will have to search abit more.

 

Regards

 

Justyn

CharlieLangCharlieLang

Hi All,

 

I am trying to do this on an account object, i have most of it working but i am trying to turn a multiselect picklist into a string.

 

How do i go about this? do i need to create a formula field in the object and use that or is there a simpler way

 

this is the code (the bit is at the bottom - it is the Buy & Sell currencies field)

 

 // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
    String Name = Apexpages.currentPage().getParameters().get('Name');
    String AccountNumber = Apexpages.currentPage().getParameters().get('AccountNumber');
   String TEXT(Buy_Currencies__c) = Apexpages.currentPage().getParameters().get('Buy_Curr');
   String TEXT(Sell_Currencies__c) = Apexpages.currentPage().getParameters().get('Sell_curr');
    
    soql = 'select Name, AccountNumber from account where account.name != null';
    if ( (null!= Name) && (!''.equals(Name)) )
      soql += ' and Name LIKE \''+String.escapeSingleQuotes(Name)+'%\'';
    if ( (null!= AccountNumber) && (!''.equals(AccountNumber)) )
      soql += ' and AccountNumber LIKE \''+String.escapeSingleQuotes(AccountNumber)+'%\'';
    
        if ( (null!= Buy_Currencies__c) && (!''.equals(Buy_Currencies__c)) )
      soql += ' and Buy_Curr LIKE \''+String.escapeSingleQuotes(Buy_Curr)+'%\'';
      
       if ( (null!= Sell_Currencies__c) && (!''.equals(Sell_Currencies__c)) )
      soql += ' and Sell_curr LIKE \''+String.escapeSingleQuotes(Sell_curr)+'%\'';

    // run the query again
    runQuery();

    return null;
  }

  

}

 and i'm getting this error

 

Error: ContactSearchController Compile Error: expecting a semi-colon, found '(' at line 57 column 14

 

Any help would be absoloutely amazing!!

Jake GmerekJake Gmerek

First thing, lets fix your error.

 

String TEXT(Buy_Currencies__c) = Apexpages.currentPage().getParameters().get('Buy_Curr');

 

That is the line in question and I am not sure what you are trying to do.  The Keyword String is declaring a new variable, the compiler is looking for an identifier next and finds TEXT so assumes that that is the identifier.  Now it is looking for either an assignment operator (=) or the end of line character (;), but instead finds open parentheses.  That is why it is throwing an error.  I am not sure how to fix it, because I am not quite sure what you are trying to do with TEXT(Buy_Currencies__c) I have never seen a construction like that nor could I find reference to it in the Apex reference guide.

 

Anyway, I hope that helped, let me know what you are trying to do and I will try to help you get this resolved.

CharlieLangCharlieLang

I used the TEXT(xxxx) because thats what i've used in formulas to pull a string from a multi select picklist.

CharlieLangCharlieLang

Thanks. I've got that bit sorted.

 

Can anyone spot why the dynamic search part is not actually working (all the data is displaying ok on the page, just when you press the keys it is not performing the search.

 

Thanks for ANY help in advance

 

Apex Class

 

public with sharing class ContactSearchController {

  // the soql without the order and limit
  private String soql {get;set;}
  // the collection of contacts to display
  public List <Account> accounts {get;set;}

  // the current sort direction. defaults to asc
  public String sortDir {
    get  { if (sortDir == null) {  sortDir = 'asc'; } return sortDir;  }
    set;
  }

  // the current field to sort by. defaults to last name
  public String sortField {
    get  { if (sortField == null) {sortField = 'Name'; } return sortField;  }
    set;
  }

  // format the soql for display on the visualforce page
  public String debugSoql {
    get { return soql + ' order by ' + sortField + ' ' + sortDir + ' limit 60'; }
    set;
  }

  // init the controller and display some sample data when the page loads
  public ContactSearchController() {
    soql = 'select Name, AccountNumber, fl_buy__c, fl_sell__c  from account where account.name != null';
    runQuery();
  }

  // toggles the sorting of query from asc<-->desc
  public void toggleSort() {
    // simply toggle the direction
    sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
    // run the query again
    runQuery();
  }

  // runs the actual query
  public void runQuery() {

    try {
      accounts = Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 60');
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
    }

  }

   // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
    String aName = Apexpages.currentPage().getParameters().get('Name');
    String abuy = Apexpages.currentPage().getParameters().get('fl_buy__c');
    String asell = Apexpages.currentPage().getParameters().get('fl_sell__c');
    
    soql = 'select Name, AccountNumber from account where account.name != null';
    if ( (null!= aName) && (!''.equals(aName)) )
      soql += ' and Name LIKE \''+String.escapeSingleQuotes(aName)+'%\'';
    if ( (null!= abuy) && (!''.equals(abuy)) )
      soql += ' and fl_buy__c CONTAINS \''+String.escapeSingleQuotes(abuy)+'%\'';
    if ( (null!= asell) && (!''.equals(asell)) )
      soql += ' and fl_sell__c CONTAINS \''+String.escapeSingleQuotes(asell)+'%\'';
    
    // run the query again
    runQuery();

    return null;
  } 
}

 VF PAGE

 

<apex:page controller="ContactSearchController" sidebar="false">

  <apex:form >
  <apex:pageMessages id="errors" />
<br/>
  <apex:pageBlock title="Find Me An Account!" mode="edit">
<table width="100%" border="0">
    <tr>
        <td width="200" valign="top">

              <apex:pageBlock title="Search" mode="edit" id="criteria">

              <script type="text/javascript">
                  function doSearch() {
                        searchServer(
                              document.getElementById("Name").value,
                              document.getElementById("AccountNumber").value,
                               document.getElementById("fl_buy__c").value,
                               document.getElementById("fl_sell__c").value,
             
                        );
                  }
              </script> 

          <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results">
              <apex:param name="Name" value="" />
              <apex:param name="AccountNumber" value="" />
              <apex:param name="fl_buy__c" value="" />
              <apex:param name="fl_sell__c" value="" />
      
       
          </apex:actionFunction>
<table cellpadding="2" cellspacing="2">

    <tr>
        <td style="font-weight:bold;">Account Name<br/>
            <input type="text" id="Name" onkeyup="doSearch();"/>
        </td>
    </tr>
    
    <tr>
        <td style="font-weight:bold;">Buy Currency<br/>
            <input type="text" id="abuy" onkeyup="doSearch();"/>
        </td>
    </tr>
    
    <tr>
        <td style="font-weight:bold;">Sell Currency<br/>
            <input type="text" id="asell" onkeyup="doSearch();"/>
        </td>
    </tr>

    
 
    <tr>

    </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="Account Name" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Name" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputLink value="/{!account.id}">{!account.Name}</apex:outputLink>
            </apex:column>

         <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Buy Currency" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="fl_buy__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputLink value="/{!account.id}">{!account.fl_buy__c}</apex:outputLink>
            </apex:column>
            
         <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Sell Currency" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="fl_sell__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputLink value="/{!account.id}">{!account.fl_sell__c}</apex:outputLink>
            </apex:column>

           

        </apex:pageBlockTable>

    </apex:pageBlock>
</td>
</tr>
</table>
 
  </apex:pageBlock>

  </apex:form>

</apex:page>

THANK YOU to anyone that can help!!!! 

Jake GmerekJake Gmerek

Debugging this one could be kind of hard.  The first thing I would check is that the query is being formed correctly.  The easiest way to do that should be to put something like:

 

<apex:outputText value = "{!soql}" />

 

on your VF page.

 

You can then take and run that query in Force.com explorer (http://wiki.developerforce.com/page/ForceExplorer) and see if you are actually getting results.  That will tell you if your problem is in forming the query, or in displaying the results.

CharlieLangCharlieLang

To be honest i need a little more help than that, i've stripped the SQL statement out so it's only looking for one of the fields, and adjusted the VF page appropriately but still not getting any results.

 

I have used this code a couple of times in the past everything looks to be fine to me i just need a bit of help from someone that would be able to have a look at the code - just when typing in the fields the search is not happening

 

I tried adding the VF bit to the page that jake suggested but i am getting an error

mihir17_inmihir17_in

I have two custom objects: rentrequests and items.

In rentrequest i have the item name , date required and which city as fields.

How can i use search code to search items ie using two objects?

Arun KArun K

HI,

I have a pageblocktable where I am able to search the records by name .

When I am trying to tranfer record. I could able to select the desired record.But problem comes when I try to search and try to transfer record.Somehow the desired records are not selected.
What could be the reason and how to avoid this..

 

 

Arun KArun K
Hi Jake,

I have a problem in using this search functionality.
So basically I have a pagelcoktable where I have search and transfer accounts functionality.

When I try to search and try to transfer accounts. It is getting the initial values in table

Can u help me in this regard about Why Iam getting such result.
Ali MeyerAli Meyer
@CharlieLang or @ArishKhan--

Did either of you figure out why the code wasn't working? I have the same situation: it compiles fine, but when you type into the dynamic search boxes, nothing happens. I don't think the controller is calling the runSearch method properly but I'm not sure where it gets held up. Do either of you remember the solution you came up with?

Thank you!!