+ Start a Discussion
CRNRCRNR 

rerender="table" not rerendering

We have the following wrapper class:

 

 

public class wrapperClassController {

    //Our collection of the class/wrapper objects cTest__c 
    public List<cProducts> productsList {get; set;}
    
    //This method uses a simple SOQL query to return a List of NRProducts__c
    public List<cProducts> getProducts(){
        if(productsList == null){
            productsList = new List<cProducts>();
        
            for(NRProducts__c c : [select Id, Name, Comments_to_Content_Team__c, Product_Description__c, Feature1__c, Feature2__c, Feature3__c, Feature4__c from NRProducts__c WHERE Feature1__c = null limit 100]){
                /* As each NRProducts__c is processed we create a new cProducts__c object and
                add it to the testProducts */
                productsList.add(new cProducts(c));
            }
        }
        return productsList;
    }
    
    public PageReference processSelected(){
        /*We create a new list of NRProducts__c that will be populated only with NRProducts__c
        if they are selected*/
        List<NRProducts__c> selectedProducts = new List<NRProducts__c>();
        
        /*We will cycle through our list of NRProducts__c and will check to see if the 
        selected property is set to true, if it is we add the NRProducts__c to the 
        selectedNRProducts__c list. */
        for(cProducts cCon : getProducts()){
            if(cCon.selected == true){
                selectedProducts.add(cCon.con);
            }
        }
        
        /* Now we have our list of selected NRProducts__c and can perform any type of 
        logic we want, sending emails, updating a field on the NRProducts__c, etc */

        for(NRProducts__c con : selectedProducts){
            system.debug(con);
update selectedProducts;
        }
        return null;
    }
    
    /* This is our wrapper/container class. A container class is a class, a data 
    structure, or an abstract data type whose instances are collections of other 
    objects. In this example a wrapper class contains both the standard salesforce 
    object NRProducts__c and a Boolean value */
    public class cProducts{
        public NRProducts__c con {get; set;}
        public Boolean selected {get; set;}
        
        /*This is the contructor method. When we create a new cNRProducts__c object we pass a 
        NRProducts__c that is set to the con property. We also set the selected value to false*/
        public cProducts(NRProducts__c c){
            con = c;
            selected = false;
        }
    }
}

 And the following page:

 

 

<apex:page controller="wrapperClassController">
    <apex:form>
        <apex:pageBlock >
            <apex:pageBlockButtons >
                <apex:commandButton value="Process" action="{!processSelected}" rerender="table"/>
            </apex:pageBlockButtons>
            <!-- In our table we are displaying the cAccount records -->
            <apex:pageBlockTable value="{!Products}" var="c" id="table">
                <apex:column >
                    <!-- This is our selected Boolean property in our wrapper class -->
                    <apex:inputCheckbox value="{!c.selected}"/>
                </apex:column>
                <!-- This is how we access the account values within our cAccount container/wrapper -->           
                <apex:column value="{!c.con.Name}" />

                         <apex:column headerValue="Feature1">             
                <apex:inputField value="{!c.con.Feature1__c}" />
                      </apex:column>
                         <apex:column headerValue="Feature2">             
                <apex:inputField value="{!c.con.Feature2__c}" />
                      </apex:column>
                         <apex:column headerValue="Feature3">             
                <apex:inputField value="{!c.con.Feature3__c}" />
                      </apex:column>
                          <apex:column headerValue="Feature4">             
                <apex:inputField value="{!c.con.Feature4__c}" />
                      </apex:column>
                 <apex:column value="{!c.con.Comments_to_Content_Team__c}" />
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

 

Everything works as expected when a field is updated, checkbox is checked, and "Process" button is clicked. Except....the table does not rerended. The result that is expected is that the record with thefield that was updated should no longer be in the list, because the Controller statement is looking for ones with this field == null.

 

Not sure what I am missing?

 

Best Answer chosen by Admin (Salesforce Developers) 
MarkWaddleMarkWaddle

The query is not being re-run because productsList is never null after the first request. I recommend refactoring the code that queries the products and assigns them to the productsList property into a separate method that is called by getProducts() (when productsList is null) and by the processSelected() method (after the update is called).

 

By the way, it is unnecessary to call "update selectedProducts" in a loop. This has the effect of updating all of the selected products multiple times. I recommend getting rid of the for loop there.

 

Regards,
Mark

 

 

    //This method uses a simple SOQL query to return a List of NRProducts__c
    public List<cProducts> getProducts(){
        if(productsList == null){
            refreshProductsList();
        }
        return productsList;
    }

    private void refreshProductsList() {
        productsList = new List<cProducts>();
        
        for(NRProducts__c c : [select Id, Name, Comments_to_Content_Team__c, Product_Description__c, Feature1__c, Feature2__c, Feature3__c, Feature4__c from NRProducts__c WHERE Feature1__c = null limit 100]){
            /* As each NRProducts__c is processed we create a new cProducts__c object and
            add it to the testProducts */
            productsList.add(new cProducts(c));
        }
    }
    
    public PageReference processSelected(){
        /*We create a new list of NRProducts__c that will be populated only with NRProducts__c
        if they are selected*/
        List<NRProducts__c> selectedProducts = new List<NRProducts__c>();
        
        /*We will cycle through our list of NRProducts__c and will check to see if the 
        selected property is set to true, if it is we add the NRProducts__c to the 
        selectedNRProducts__c list. */
        for(cProducts cCon : getProducts()){
            if(cCon.selected == true){
                selectedProducts.add(cCon.con);
            }
        }
        
        /* Now we have our list of selected NRProducts__c and can perform any type of 
        logic we want, sending emails, updating a field on the NRProducts__c, etc */

        update selectedProducts;
        refreshProductsList();

        return null;
    }

All Answers

MarkWaddleMarkWaddle

The query is not being re-run because productsList is never null after the first request. I recommend refactoring the code that queries the products and assigns them to the productsList property into a separate method that is called by getProducts() (when productsList is null) and by the processSelected() method (after the update is called).

 

By the way, it is unnecessary to call "update selectedProducts" in a loop. This has the effect of updating all of the selected products multiple times. I recommend getting rid of the for loop there.

 

Regards,
Mark

 

 

    //This method uses a simple SOQL query to return a List of NRProducts__c
    public List<cProducts> getProducts(){
        if(productsList == null){
            refreshProductsList();
        }
        return productsList;
    }

    private void refreshProductsList() {
        productsList = new List<cProducts>();
        
        for(NRProducts__c c : [select Id, Name, Comments_to_Content_Team__c, Product_Description__c, Feature1__c, Feature2__c, Feature3__c, Feature4__c from NRProducts__c WHERE Feature1__c = null limit 100]){
            /* As each NRProducts__c is processed we create a new cProducts__c object and
            add it to the testProducts */
            productsList.add(new cProducts(c));
        }
    }
    
    public PageReference processSelected(){
        /*We create a new list of NRProducts__c that will be populated only with NRProducts__c
        if they are selected*/
        List<NRProducts__c> selectedProducts = new List<NRProducts__c>();
        
        /*We will cycle through our list of NRProducts__c and will check to see if the 
        selected property is set to true, if it is we add the NRProducts__c to the 
        selectedNRProducts__c list. */
        for(cProducts cCon : getProducts()){
            if(cCon.selected == true){
                selectedProducts.add(cCon.con);
            }
        }
        
        /* Now we have our list of selected NRProducts__c and can perform any type of 
        logic we want, sending emails, updating a field on the NRProducts__c, etc */

        update selectedProducts;
        refreshProductsList();

        return null;
    }
This was selected as the best answer
CRNRCRNR

Mark,


Thank you for your efforts! This worked perfect!

 

Really appreciate your time and efforts!