function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Matt Cooper 7Matt Cooper 7 

Visualforce Search Page - Dependent Picklists Issue

Hi, I'm working on building a custom search visualforce page and I've run into a problem.  I have added 2 picklists (one controlling and one dependent) as filtering fields.  However, when I go to the VF page and try to filter, the query returns nothing if Geography is left blank. For some reason, the Sub-Geography field is querying as "__" instead of blank.  I'm guessing that this is caused by the field being faded out when no Geography is selected, but not sure why it is not just outputting as nothing or void.  Also, if I do select a Geography and Sub-Geography then select another Geography the Sub-Geography value stays the same as the older selection.  Does anyone have any ideas on 1) how I can set the Sub-Geography value as blank if no Geography is selected and 2) how to reset the Sub-Geography value to blank when Geography value is changed?

Controller:
 
public with sharing class CorpGovSearchController {

    
  public Apttus__APTS_Agreement__c agmt1 {get;set;}
    
  // the soql without the order and limit
  private String soql {get;set;}
  // the collection of agreements to display
  public List<Apttus__APTS_Agreement__c> agmts {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 CorpGovSearchController() {
    soql = 'select Name, Apttus__Agreement_Category__c, NikeSF_Sub_Geography__c, NikeSF_Geography__c, ID from Apttus__APTS_Agreement__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 {
      agmts = 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 agmtCategory = Apexpages.currentPage().getParameters().get('agmtCategory');
    String subgeography = Apexpages.currentPage().getParameters().get('subgeography');
    String geography = Apexpages.currentPage().getParameters().get('geography');
    String ID = Apexpages.currentPage().getParameters().get('ID');

    soql = 'select Name, Apttus__Agreement_Category__c, NikeSF_Sub_Geography__c, NikeSF_Geography__c, ID from Apttus__APTS_Agreement__c where name != null';
    if (!Name.equals(''))
	soql += ' and Name LIKE \''+String.escapeSingleQuotes(Name)+'%\'';
    if (!agmtCategory.equals(''))
      soql += ' and agmtCategory LIKE \''+String.escapeSingleQuotes(agmtCategory)+'%\'';
    if (!geography.equals(''))
      soql += ' and NikeSF_Geography__c LIKE \'' + ''+geography+'\'';
    if (!subgeography.equals(''))
      soql += ' and NikeSF_Sub_Geography__c LIKE \''+subgeography+'\'';  
    

    // run the query again
    runQuery();

    return null;
  }

  // use apex describe to build the picklist values
  public List<String> geographies {
    get {
      if (geographies == null) {

        geographies = new List<String>();
        Schema.DescribeFieldResult field = Apttus__APTS_Agreement__c.NikeSF_Geography__c.getDescribe();

        for (Schema.PicklistEntry f : field.getPicklistValues())
          geographies.add(f.getLabel());

      }
      return geographies;          
    }
    set;
  }

      public List<String> subgeographies {
    get {
      if (subgeographies == null) {

        subgeographies = new List<String>();
        Schema.DescribeFieldResult field = Apttus__APTS_Agreement__c.NikeSF_Sub_Geography__c.getDescribe();

        for (Schema.PicklistEntry g : field.getPicklistValues())
          subgeographies.add(g.getLabel());

      }
      return subgeographies;          
    }
    set;
  }
}

Visualforce Page:
 
<apex:page controller="CorpGovSearchController" sidebar="false">

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

  <apex:pageBlock title="Agreement Search" mode="edit">

  <table width="100%" border="0">
  <tr>  
    <td width="200" valign="top">

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

      <script type="text/javascript">
      function doSearch() {
        searchServer(
          document.getElementById("Name").value,
          document.getElementById("agmtCategory").value,
          document.getElementById("{!$Component.geography}").value,
          document.getElementById("{!$Component.subgeography}").value          
          );
      }

      </script> 
	  
      <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
          <apex:param name="Name" value="" />
          <apex:param name="agmtCategory" value="" />
          <apex:param name="geography" value="" />
          <apex:param name="subgeography" value="" />
      </apex:actionFunction>
          

          
      <table cellpadding="2" cellspacing="2">
      <tr>
        <td style="font-weight:bold;">Agreement Name<br/>
        <input type="text" id="Name" onkeyup="doSearch();"/>
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Agreement Category<br/>
        <input type="text" id="agmtCategory" onkeyup="doSearch();"/>
        </td>
      </tr>

      <tr>
        <td style="font-weight:bold;">Geography<br/>
          <apex:inputfield id ="geography" value="{!agmt1.NikeSF_Geography__c}"  onchange="doSearch();"/>  
        </td>
      </tr>
          
      <tr>
        <td style="font-weight:bold;">Sub-Geography<br/>
          <apex:inputfield id ="subgeography" value="{!agmt1.NikeSF_Sub_Geography__c}"  onchange="doSearch();"/>  
        </td>
      </tr>

      </table>

      </apex:pageBlock>

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

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

        <apex:pageBlockTable value="{!agmts}" var="agmt">

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Agreement Name" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Name" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputLink value="/{!agmt.id}">{!agmt.Name}</apex:outputLink>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Agreement Category" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Apttus__Agreement_Category__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!agmt.Apttus__Agreement_Category__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Geographies" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="NikeSF_Geography__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!agmt.NikeSF_Geography__c}"/>
            </apex:column>
            
            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Sub-Geography" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="NikeSF_Sub_Geography__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!agmt.NikeSF_Sub_Geography__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>


Thanks!
Matt Cooper 7Matt Cooper 7
So, after some tinkering, I believe I have been able to solve my issue. I added an if statement to my javascript to look at the current value of Geography, current value of Sub-Geography, and the old value of Geography. If the conditions are met then it sets the Sub-Geography value to blank. Here is the code:
 
var oldG;
      function doSearch() {
        
        if(document.getElementById("{!$Component.geography}").value=='' || document.getElementById("{!$Component.subgeography}").value=='__' || document.getElementById("{!$Component.geography}").value!=oldG){
          document.getElementById("{!$Component.subgeography}").value='';
          oldG = document.getElementById("{!$Component.geography}").value;
          searchServer(
          	document.getElementById("Name").value,
          	document.getElementById("agmtCategory").value,
          	document.getElementById("{!$Component.geography}").value,
          	document.getElementById("{!$Component.subgeography}").value          
          	);
        }
        else{
            oldG = document.getElementById("{!$Component.geography}").value;
            searchServer(
          	document.getElementById("Name").value,
          	document.getElementById("agmtCategory").value,
          	document.getElementById("{!$Component.geography}").value,
          	document.getElementById("{!$Component.subgeography}").value          
          	);
        }    
      }