+ Start a Discussion
mgodseymgodsey 

Dynamic Search/VF page not re-rendering

I am trying to use Jeff Douglas' post about dynamic searching and use picklists to search, but I can't get the page to re-render after I have made a selection in the picklist. I've looked through various other posts about this and haven't been able to find anything that works for me. Does anyone see what is going wrong? I think it has to do with doSearch() function not actually being called when changing a picklist value.

Any feedback is much appreciated, thank you!!

Here is my controller class:
public with sharing class quoteLineItemEntryExtensionOption4 {
   
    public Quote theQuote {get;set;}
    public Pricebook2 theBook {get;set;}
   
    private Boolean forcePricebookSelection = false;
    //the soql without the order and limit
    private String soql {get;set;}
   
    //the collection of products to display
    public List<priceBookEntry> availableProducts {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 Quote name
    public String sortField {
        get{
            if (sortField == null){
                sortField = 'Quote';
            }
            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 quoteLineItemEntryExtensionOption4(ApexPages.StandardController controller){
   
        //get information about the Quote being worked on
        theQuote = database.query('select Id, Pricebook2Id,Pricebook2.Name,CurrencyISOCode from Quote where Id = \'' + controller.getRecord().Id + '\' limit 1');
       
        //Check if the Opp has a pricebook associated yet
        if(theQuote.Pricebook2Id == null){
            Pricebook2[] activepbs = [select ID, Name FROM Pricebook2 WHERE isActive = true limit 2];
            if(activepbs.size() == 2){
                forcePriceBookSelection = true;
                theBook = new Pricebook2();
            } else {
                theBook = activepbs[0];
            }
        }
        else{
            theBook = theQuote.Pricebook2;       
        }
        //this soql just shows the initial results when page is loaded
        soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Product2.CreativeFamily__c != null and Pricebook2Id = \'' + theBook.Id + '\'';
        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 {
            availableProducts = Database.query(soql  /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/);
        } catch (Exception e) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops! There are no results for this search'));
        }
    }
   
    // runs the search with parameters passed via Javascript
    public PageReference runSearch() { 

        String creativeFamily = Apexpages.currentPage().getParameters().get('creativeFamily');
        String creativeTypes = Apexpages.currentPage().getParameters().get('creativeTypes');
        String pricingModel = Apexpages.currentPage().getParameters().get('pricingModel');
        String targetingOptions = Apexpages.currentPage().getParameters().get('targetingOptions');

        soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Pricebook2Id = \'' + theBook.Id + '\'';
        if (!creativeFamily.equals(''))
            soql += ' and Product2.CreativeFamily__c LIKE (\''+creativeFamily+'\')';
        if (!creativeTypes.equals(''))
            soql += ' and Product2.CreativeType__c LIKE (\''+creativeTypes+'\')';
        if (!pricingModel.equals(''))
            soql += ' and Product2.pricingModel__c LIKE (\''+pricingModel+'\')'; 
        if (!targetingOptions.equals(''))
            soql += ' and Product2.TargetingOptions__c LIKE (\''+targetingOptions+'\')';

        // run the query again
        System.debug('[MF] running the query from runSearch method' + soql);
        runQuery();

        return null;
    }
   
    //use apex describe to build the picklist values for Creative Family
    public List<String> creativeFamily{
        get{
            if(creativeFamily == null){
                creativeFamily = new List<String>();
                Schema.DescribeFieldResult field = Product2.CreativeFamily__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    creativeFamily.add(f.getLabel());
                }               
            }
            return creativeFamily;
        }
        set;
    }
   
    //use apex describe to build the picklist values for Creative Type
    public List<String> creativeType{
        get{
            if(creativeType == null){
                creativeType = new List<String>();
                Schema.DescribeFieldResult field = Product2.creativeType__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    creativeType.add(f.getLabel());
                }               
            }
            return creativeType;
        }
        set;
    }
   
    //use apex describe to build the picklist values for Pricing Model
    public List<String> pricingModel{
        get{
            if(pricingModel == null){
                pricingModel = new List<String>();
                Schema.DescribeFieldResult field = Product2.pricingModel__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    pricingModel.add(f.getLabel());
                }               
            }
            return pricingModel;
        }
        set;
    }
   
    //use apex describe to build the picklist values
    public List<String> targetingOptions{
        get{
            if(targetingOptions == null){
                targetingOptions = new List<String>();
                Schema.DescribeFieldResult field = Product2.TargetingOptions__c.getDescribe();
               
                for(Schema.PicklistEntry f : field.getPickListValues()){
                    targetingOptions.add(f.getLabel());
                }
            }
            return targetingOptions;
        }
        set;
    }

}

Here is my VF page:
<apex:page standardController="Quote" extensions="quoteLineItemEntryExtensionOption4" sidebar="false">

  <apex:form >
  <apex:pageMessages id="errors" />

  <apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" 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("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex.]value,
          document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex.]value,
          document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex.]value,
          document.getElementById("targetingOptions").options[document.getElementById("targetingOptions").selectedIndex].value
          );
      }
      </script>

      <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
          <apex:param name="creativeFamily" value="" />
          <apex:param name="creativeTypes" value="" />
          <apex:param name="pricingModel" value="" />
          <apex:param name="targetingOptions" value="" />
      </apex:actionFunction>

      <table cellpadding="2" cellspacing="2">
      <tr>
        <td style="font-weight:bold;">Creative Family<br/>
          <select id ="creativeFamily" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!creativeFamily}" var="cFamily">
              <option value="{!cFamily}">{!cFamily}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Creative Type<br/>
          <select id ="creativeType" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!creativeType}" var="cType">
              <option value="{!cType}">{!cType}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Pricing Model<br/>
          <select id ="Pricing Model" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!pricingModel}" var="pm">
              <option value="{!pm}">{!pm}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Targeting Options<br/>
          <select id="targetingOptions" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!targetingOptions}" var="targeting">
              <option value="{!targeting}">{!targeting}</option>
            </apex:repeat>
          </select>
        </td>
      </tr>
      </table>

      </apex:pageBlock>

    </td>
    <td valign="top">

    <apex:pageBlock title="Available Products To Add" mode="edit" id="results">

        <apex:pageBlockTable value="{!availableProducts}" var="product">
            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Product Name" action="{!toggleSort}" reRender="results,debug">
                        <apex:param name="sortfield" value="Product2.Name" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.Name}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Creative Family" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.creativeFamily__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.CreativeFamily__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Creative Type" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.creativeType__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.CreativeType__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Pricing Model" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.pricingModel__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.PricingModel__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Targeting Options" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.targetingOptions" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.TargetingOptions__c}"/>
            </apex:column>

        </apex:pageBlockTable>

    </apex:pageBlock>

    </td>
  </tr>
  </table>
 
  <apex:pageBlock title="Selected Products">
 
  </apex:pageBlock>


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

  </apex:pageBlock>

  </apex:form>

</apex:page>
Damien Phillippi033905702927186443Damien Phillippi033905702927186443
1) Are you hitting your debugs?
2) You aren't using any Wildcards in your LIKE
3) Try binding your variables directly to the controller instead of passing them in through URL parameters
4) Use <apex:selectList> instead of your <options> tags
5) You might want to practice your Salesforce development a little bit on some simpler work before you try something like this.  You seem to be overcomplicating a lot of what you are doing which is probably adding to your confusion.  (Try using more Salesforce specific components on your page.  They will make your life much easier if you learn to use them over standard HTML ones.)

Sorry I can't help you any more than this right now, but I think you need to work on your 3-5 before I can help much more.
mgodseymgodsey
Thank you for your feedback! While I have some experience with Apex, Visualforce, VF Controllers & JavaScript are entirely new territory for me. I do wish I could start on something easier, but when your manager assigns you something, sometimes you just have to figure out a way :)
I was able to get the code above to work with a few minor changes (some capitalization issues, decimal points in the wrong spot, etc). However, I would definitely still be interested in making it simpler.

This is the blog post that I used as a reference: http://blog.jeffdouglas.com/2010/07/13/building-a-dynamic-search-page-in-visualforce/

I've changed the picklist fields to use the apex:inputField tag, and the doSearch() function is being called when a picklist value changes. However, my second alert comes back null. If this way won't work, how would I go about binding these variables directly to the controller? I know I would have to create properties for each with get and set methods, but how do I access the selected picklist value from the page? Would it still be possible to do without creating some sort of command button to get the process started?

<apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">


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

  <tr>

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

      <!-------This is the Search by picklist section-------------------------->

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



      <script type="text/javascript">

      function doSearch() {

        alert('doSearch function');

        alert(document.getElementById("creativeFamily")); //THIS COME BACK NULL

            searchServer(

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

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

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

            document.getElementById("targetingOption").options[document.getElementById("targetingOption").selectedIndex].value

        );

      
      }

      </script>

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

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

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

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

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

      </apex:actionFunction>


     <apex:pageBlockSection columns="1">

         <apex:inputField value="{!Quote.TestInventoryType__c}" id="creativeFamily" onchange="doSearch();"/>