+ Start a Discussion
MayTheForceBeWithYouMayTheForceBeWithYou 

reRender from selectList OnChange not functioning properly

I have a selectlist value that should be passed as a parameter to my controller (using Javascript) in order to rerender the search results of a dynamic SOQL query. I have looked through several forum posts on this site as well as external web resources but haven't had any luck so I thought I'd post my code and maybe someone will see what I've missed; thanks so much!

 

VF Page:

 

<apex:page standardController="Janela_de_Acesso__c" extensions="JDABP" sidebar="false">
<apex:sectionHeader title="Janela de Acesso"/>
<apex:form >
<div align="center">
<apex:messages styleClass="errorMsg"/>
<apex:commandButton action="{!Save}" value="Save"/>
<apex:commandButton action="{!SaveAndNew}" value="Save & New"/>
<apex:commandButton action="{!Cancel}" value="Cancel"/>
</div>
<apex:pageBlock >
<apex:pageBlockSection title="Informações" columns="2">
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Name}" />
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Status__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Final__c}"/>
</apex:pageBlockSection>
<!--document.getElementById("pesquisa").options[document.getElementById("pesquisa").selectedIndex].value
<script type="text/javascript">
      function doSearch() {
        searchServer(
          document.getElementById('searchBox').value,
          document.getElementById('pesquisa').options[document.getElementById('pesquisa').selectedIndex].value);
      }
</script>-->
 
<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="Available">
    <apex:param name="searchB" value="" />
    <apex:param name="pesq" value="" />
</apex:actionFunction>

<apex:pageBlockSection title="Membros da Janela de Acesso" columns="1" id="Available_BPs">

<apex:panelGrid columns="2" cellpadding="5px">
<apex:pageBlockSectionItem labelStyle="vertical-align: middle" >
<apex:outputLabel value="Pesquisa:" for="SearchList"/>
<apex:selectList title="Pesquisa" size="1" id="pesquisa" onchange="searchServer(
          document.getElementById('searchBox').value,
          this.options[this.selectedIndex].value);">
<apex:selectOptions value="{!items}" id="pesquisa2"/>
</apex:selectList>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem labelStyle="vertical-align: middle">
<apex:outputLabel value="for:" for="SearchBox"/>
<apex:inputText id="SearchBox" onkeyup="searchServer(
          document.getElementById('searchBox').value,
          document.getElementById('pesquisa').options[document.getElementById('pesquisa').selectedIndex].value);"/>
</apex:pageBlockSectionItem>
</apex:panelGrid>
<apex:panelGrid columns="2">
<apex:outputLabel value="Membros Disponíveis" style="font-weight:bold"/>
<apex:outputLabel value="Membros Selecionados" style="font-weight:bold"/>
</apex:panelGrid>
<apex:panelGrid columns="3">
<apex:outputPanel id="Available">
<apex:selectList title="Membros Disponíveis" size="14" id="Available2">
<apex:selectOptions value="{!searchResults}" />
</apex:selectList>
</apex:outputPanel>
<apex:selectList title="Membros Selecionados" size="14" id="Selected"/>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>

</apex:page>

 

Controller:

 

public class JDABP {    
    
    // the soql without the order and limit
    private String soql {get;set;}
    // the collection of contacts to display
    public List<sObject> results {get;set;}
    public String searchObject;
    public Janela_de_Acesso__c j;
    public List<SelectOption> searchResult = new List<SelectOption>();
    public String sObjectDesc = 'Business Plans';

    
    //Constructor to apply fields
    public JDABP(ApexPages.StandardController controller) {
        j = (Janela_de_Acesso__c) controller.getRecord();
        j.Name='|';
        j.Status__c='Ativo';
        j.Data_Inicial__c=System.now();
        j.Data_Final__c=System.today()+30;        
        //j.RecordTypeId = Label.Janela_de_Acesso_BP_RecordType;
        searchObject = 'Business_Plan__c';
        soql = 'select Id, Name from ' + searchObject + ' limit 100';
        runQuery();

    }
    
    public List<SelectOption> getItems() {
        List<SelectOption> options = new List<SelectOption>();
            options.add(new SelectOption('Business Plans','Business Plans'));
            options.add(new SelectOption('Perfis','Perfis'));
            options.add(new SelectOption('Usuários','Usuários'));

        return options;
    }     
    
    public List<SelectOption> getSearchResults() {
        return searchResult;
    }
    
    // runs the actual query
  public void runQuery() {    
    try {
      results = Database.query(soql);
      searchResult.clear(); 
      for (sObject r : results){
          If (sObjectDesc=='Business Plans'){
              Business_Plan__c BPr = (Business_Plan__c) r;
              searchResult.add(new SelectOption(BPr.name,BPr.name));
          }
          Else If (sObjectDesc=='Perfis'){
              Profile Pr = (Profile) r;
              searchResult.add(new SelectOption(Pr.Name,Pr.Name));
          }
          Else {
              User Ur = (User) r;
              searchResult.add(new SelectOption(Ur.Name,Ur.Name));
          }         
      }
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, soql+' '+e.getMessage()));
    }
 
  }
 
  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
 
    String searchText = Apexpages.currentPage().getParameters().get('searchB');
    sObjectDesc = Apexpages.currentPage().getParameters().get('pesq');
    If (sObjectDesc=='Business Plans'){
    searchObject='Business_Plan__c';
    }
    Else If (sObjectDesc=='Perfis'){
    searchObject='Profile';
    }
    Else {
    searchObject='User';
    }
 
    soql = 'select Id, Name from ' + searchObject + ' limit 100';
    if (!searchText.equals(''))
      soql += ' and Name LIKE \''+String.escapeSingleQuotes(searchText)+'%\'';
    
 
    // run the query again
    runQuery();
 
    return null;
  }

        
    //Override Save & New Functionality
    public PageReference SaveAndNew() {
        try{
            insert j;
        } catch (DMLException e) {return null;}
        PageReference pr = new PageReference('/apex/JDABP');
        pr.setRedirect(true);
        return pr;
    }

}

 

Thanks again!

Best Answer chosen by Admin (Salesforce Developers) 
Shashikant SharmaShashikant Sharma

I found two mistakes in your code 

1)You have used a

 

document.getElementById('searchBox').value

 this will give java script error for sure as document.getElementById('searchBox') this will not return a HTML DOM object as salesforce creates a hierarchial id for controls so id of the input text control will be generated using is of the controls above in hierarchy, like pageId,formId, page block Id etc to catch such JS error just change your JS function like this

 

2)In your actionFunction you have passed values to server using apex:param but did not use assignedTo , this will be a problem as assignedTo is necessary in apex:param

 

One more thing

3)I would suggest you to make your actionFunction as immediate="true" as you are passing the values from apex:param so no need to bind all VFP values to controller properties.

 

just make above changes and let me know if any issues

 

 

All Answers

Shashikant SharmaShashikant Sharma

I found two mistakes in your code 

1)You have used a

 

document.getElementById('searchBox').value

 this will give java script error for sure as document.getElementById('searchBox') this will not return a HTML DOM object as salesforce creates a hierarchial id for controls so id of the input text control will be generated using is of the controls above in hierarchy, like pageId,formId, page block Id etc to catch such JS error just change your JS function like this

 

2)In your actionFunction you have passed values to server using apex:param but did not use assignedTo , this will be a problem as assignedTo is necessary in apex:param

 

One more thing

3)I would suggest you to make your actionFunction as immediate="true" as you are passing the values from apex:param so no need to bind all VFP values to controller properties.

 

just make above changes and let me know if any issues

 

 

This was selected as the best answer
MayTheForceBeWithYouMayTheForceBeWithYou

Thanks for the fast reply! I've made the suggested changes but the page is still not fully functioning properly and I'm not quite sure why. It appears that my sObjectDesc variable is still not being updated upon changing my selectList value; however, I can see that the search results are being updated (even though the results are the same upon each refresh).

 

If it helps-my long term goal is to emulate the functionality of the Salesforce page where you add/remove members from a group such as in the page you reach after clicking Setup>Manage Users>Public Groups>Edit (Any Group)

 

 

Thanks for your help, below is my updated code:

 

VFPage:

 

<apex:page standardController="Janela_de_Acesso__c" extensions="JDABP" sidebar="false">
<apex:sectionHeader title="Janela de Acesso"/>
<apex:form >
<div align="center">
<apex:messages styleClass="errorMsg"/>
<apex:commandButton action="{!Save}" value="Save"/>
<apex:commandButton action="{!SaveAndNew}" value="Save & New"/>
<apex:commandButton action="{!Cancel}" value="Cancel"/>
</div>
<apex:pageBlock >
<apex:pageBlockSection title="Informações" columns="2">
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Name}" />
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Status__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Final__c}"/>
</apex:pageBlockSection>
 
<apex:actionFunction immediate="true" name="searchServer" action="{!runSearch}" reRender="Available2,Available3">
    <apex:param assignTo="{!searchText}" name="searchB" value="" />
    <apex:param assignTo="{!sObjectDesc}" name="pesq" value="" />
</apex:actionFunction>

<apex:pageBlockSection title="Membros da Janela de Acesso" columns="1" id="Available_BPs">

<apex:panelGrid columns="2" cellpadding="5px">
<apex:pageBlockSectionItem labelStyle="vertical-align: middle" >
<apex:outputLabel value="Pesquisa:" for="SearchList"/>
<apex:selectList title="Pesquisa" size="1" id="pesquisa" onchange="doSearch();">
<apex:selectOptions value="{!items}" id="pesquisa2"/>
<script type="text/javascript">
      function doSearch() {
        searchServer(
          <!--document.getElementById('{!$Component.SearchBox}').value,-->
          document.getElementById('{!$Component.pesquisa}').options[document.getElementById('{!$Component.pesquisa}').selectedIndex].text);
      }
</script>

</apex:selectList>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem labelStyle="vertical-align: middle">
<apex:outputLabel value="for:" for="SearchBox"/>
<apex:inputText id="SearchBox" onkeyup="doSearch2();">
<script type="text/javascript">
      function doSearch2() {
        searchServer(
          document.getElementById('{!$Component.SearchBox}').value,
          <!--document.getElementById('{!$Component.pesquisa}').options[document.getElementById('{!$Component.pesquisa}').selectedIndex].value);-->
      }
</script>

</apex:inputText>
</apex:pageBlockSectionItem>
</apex:panelGrid>
<apex:panelGrid columns="2">
<apex:outputLabel value="Membros Disponíveis" style="font-weight:bold"/>
<apex:outputLabel value="Membros Selecionados" style="font-weight:bold"/>
</apex:panelGrid>
<apex:panelGrid columns="3">
<apex:outputPanel id="Available">
<apex:selectList title="Membros Disponíveis" size="14" id="Available2">
<apex:selectOptions value="{!searchResults}" id="Available3" />
</apex:selectList>
</apex:outputPanel>
<apex:selectList title="Membros Selecionados" size="14" id="Selected"/>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>

</apex:page>

 Controller:

 

public class JDABP {    
    
    // the soql without the order and limit
    private String soql {get;set;}
    // the collection of contacts to display
    public List<sObject> results {get;set;}
    public String searchObject;
    public Janela_de_Acesso__c j;
    public List<SelectOption> searchResult = new List<SelectOption>();
    public String searchText=Apexpages.currentPage().getParameters().get('searchB');
    public String sObjectDesc=Apexpages.currentPage().getParameters().get('pesq');

    
    //Constructor to apply fields
    public JDABP(ApexPages.StandardController controller) {
        j = (Janela_de_Acesso__c) controller.getRecord();
        j.Name='|';
        j.Status__c='Ativo';
        j.Data_Inicial__c=System.now();
        j.Data_Final__c=System.today()+30;        
        //j.RecordTypeId = Label.Janela_de_Acesso_BP_RecordType;
        searchText = '';
        sObjectDesc = 'Business Plans';
        searchObject = 'Business_Plan__c';
        soql = 'select Id, Name from ' + searchObject + ' limit 100';
        runQuery();

    }
    
    public List<SelectOption> getItems() {
        List<SelectOption> options = new List<SelectOption>();
            options.add(new SelectOption('Business Plans','Business Plans'));
            options.add(new SelectOption('Perfis','Perfis'));
            options.add(new SelectOption('Usuários','Usuários'));

        return options;
    }     
    
    public List<SelectOption> getSearchResults() {
        return searchResult;
    }
    
    // runs the actual query
  public void runQuery() {    
    try {
      results = Database.query(soql);
      searchResult.clear(); 
      for (sObject r : results){
          If (sObjectDesc.contains('Business Plans')){
              Business_Plan__c BPr = (Business_Plan__c) r;
              searchResult.add(new SelectOption(BPr.name,BPr.name));
          }
          Else If (sObjectDesc.contains('Perfis')){
              Profile Pr = (Profile) r;
              searchResult.add(new SelectOption(Pr.Name,Pr.Name));
          }
          Else If (sObjectDesc.contains('Usuários')){
              User Ur = (User) r;
              searchResult.add(new SelectOption(Ur.Name,Ur.Name));
          }
          Else {
              searchResult.add(new SelectOption(sObjectDesc,sObjectDesc));
          }         
      }
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, soql+' '+e.getMessage()));
    }
 
  }
 
/*Method for troubleshooting
  public PageReference runReset() {
      searchResult.clear();
      searchResult.add(new SelectOption(sObjectDesc,sObjectDesc));
      return null;
  } 
*/ 
  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
 
    If (sObjectDesc.contains('Business Plans')){
    searchObject='Business_Plan__c';
    }
    Else If (sObjectDesc.contains('Perfis')){
    searchObject='Profile';
    }
    Else If (sObjectDesc.contains('Usuários')){
    searchObject='User';
    }
 
    soql = 'select Id, Name from ' + searchObject + ' limit 100';
    if (!searchText.equals(''))
      soql += ' and Name LIKE \''+String.escapeSingleQuotes(searchText)+'%\'';
    
 
    // run the query again
    runQuery();
 
    return null;
  }

        
    //Override Save & New Functionality
    public PageReference SaveAndNew() {
        try{
            insert j;
        } catch (DMLException e) {return null;}
        PageReference pr = new PageReference('/apex/JDABP');
        pr.setRedirect(true);
        return pr;
    }

}

 

MayTheForceBeWithYouMayTheForceBeWithYou

Had to play around with a few other components to get the functionality working as I had intended but your edits were spot on and got me to the *final* version of my code (posted below) so thanks a lot Shashikant! Now to populate the second selectList with selected options from the first! :-)

 

VF Page:

<apex:page standardController="Janela_de_Acesso__c" extensions="JDABP" sidebar="false">
<apex:sectionHeader title="Janela de Acesso"/>
<apex:form >
<div align="center">
<apex:messages styleClass="errorMsg"/><!--DELETE-->
<apex:commandButton action="{!Save}" value="Save"/>
<apex:commandButton action="{!SaveAndNew}" value="Save & New"/>
<apex:commandButton action="{!Cancel}" value="Cancel"/>
</div>
<apex:pageBlock >
<apex:pageBlockSection title="Informações" columns="2">
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Name}" />
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Status__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Final__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection title="Membros da Janela de Acesso" columns="1">
<apex:panelGrid columns="2" cellpadding="5px">
<apex:pageBlockSectionItem labelStyle="vertical-align: middle" >
<apex:outputLabel value="Pesquisa:" for="SearchList"/>
<apex:selectList title="Pesquisa" size="1" id="pesquisa" onchange="searchServer(this.options[this.selectedIndex].text);">
<apex:selectOptions value="{!items}"/>
<apex:actionFunction immediate="true" name="searchServer" action="{!runSearch}" reRender="Available">
<apex:param assignTo="{!sObjectDesc}" name="pesq" value="" />
</apex:actionFunction>
</apex:selectList>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem labelStyle="vertical-align: middle">
<apex:outputLabel value="for:" for="SearchBox"/>
<apex:inputText id="SearchBox" onkeyup="searchServer2(this.value);">
<apex:actionFunction immediate="true" name="searchServer2" action="{!runSearch}" reRender="Available">
<apex:param assignTo="{!searchText}" name="searchB" value="" />
</apex:actionFunction>
</apex:inputText>
</apex:pageBlockSectionItem>
</apex:panelGrid>
<apex:panelGrid columns="2">
<apex:outputLabel value="Membros Disponíveis" style="font-weight:bold"/>
<apex:outputLabel value="Membros Selecionados" style="font-weight:bold"/>
</apex:panelGrid>
<apex:panelGrid columns="3">
<apex:selectList title="Membros Disponíveis" multiselect="true" size="14" id="Available">
<apex:selectOptions value="{!searchResults}"/>
</apex:selectList>
<apex:selectList title="Membros Selecionados" multiselect="true" size="14" id="Selected"/>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>

 

Controller:

public class JDABP {    
    
    // the soql without the order and limit
    private String soql {get;set;}
    // the collection of contacts to display
    public List<sObject> results {get;set;}
    public String searchObject;
    public Janela_de_Acesso__c j;
    public List<SelectOption> searchResult = new List<SelectOption>();
    public String searchText {get;set;}
    public String sObjectDesc {get;set;}

    
    //Constructor to apply fields
    public JDABP(ApexPages.StandardController controller) {
        j = (Janela_de_Acesso__c) controller.getRecord();
        j.Status__c='Ativo';
        j.Data_Inicial__c=System.now();
        j.Data_Final__c=System.today()+30;        
        //j.RecordTypeId = Label.Janela_de_Acesso_BP_RecordType;
        searchText = '';
        sObjectDesc = 'Business Plans';
        searchObject = 'Business_Plan__c';
        soql = 'select Id, Name from ' + searchObject + ' order by Name limit 100';
        runQuery();

    }
    
    public List<SelectOption> getItems() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('Business Plans','Business Plans'));
        options.add(new SelectOption('Perfis','Perfis'));
        options.add(new SelectOption('Usuários','Usuários'));
        return options;
    }     
    
    public List<SelectOption> getSearchResults() {
        return searchResult;
    }
    
    // runs the actual query
    public void runQuery() {    
        try {
          results = Database.query(soql);
          searchResult.clear(); 
          for (sObject r : results){
              If (sObjectDesc.contains('Business Plans')){
                  Business_Plan__c BPr = (Business_Plan__c) r;
                  searchResult.add(new SelectOption(BPr.name,BPr.name));
              }
              Else If (sObjectDesc.contains('Perfis')){
                  Profile Pr = (Profile) r;
                  searchResult.add(new SelectOption(Pr.Name,Pr.Name));
              }
              Else If (sObjectDesc.contains('Usuários')){
                  User Ur = (User) r;
                  searchResult.add(new SelectOption(Ur.Name,Ur.Name));
              }
              Else {
                  searchResult.add(new SelectOption(sObjectDesc,sObjectDesc));
              }         
          }
        } catch (Exception e) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, ''));
          }
 
  }

  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
    If (sObjectDesc.contains('Business Plans')){
        searchObject='Business_Plan__c';
    }
    Else If (sObjectDesc.contains('Perfis')){
        searchObject='Profile';
    }
    Else If (sObjectDesc.contains('Usuários')){
        searchObject='User';
    }
    soql = 'select Id, Name from ' + searchObject;
    if (!searchText.equals('')){
      soql += ' where Name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\'';   
    }
    soql += ' order by Name limit 100';  
    // run the query again
    runQuery(); 
    return null;
  }
        
    //Override Save & New Functionality
    public PageReference SaveAndNew() {
        try{
            insert j;
        } catch (DMLException e) {return null;}
        PageReference pr = new PageReference('/apex/JDABP');
        pr.setRedirect(true);
        return pr;
    }

}

 

Thanks again!

Eric WhippleEric Whipple

Immediate="true" strikes again.  My problem wasn't strongly related to this post, but it was that suggestion that reminded me and resolved my problem.  Thanks, Shashikant!