[SalesForce] Boolean value not setting in wrapper class

I am having an issue with a wrapper class I have created to set a boolean value from a checkbox on a table located on a visualforce page. I have based my work off a widely cited example here: https://developer.salesforce.com/page/Wrapper_Class

Everything seems to work except for the fact that all the values in the """""" list have selected = false and so no emails are added to the list.

My code:

Controller:

public class CustomButtonController{

    public List<sSupplier> SupplierList {get;set;}
    public string CustomText {get;set;}
    public string CustomSubject {get;set;}    
    public String Project {get;set;}


    public class sSupplier{
        public Supplier_Bidding__c Supp {get; set;}
        public Boolean selected {get; set;}

        //This is the contructor method. When we create a new cContact object we pass a Contact that is set to the con property. We also set the selected value to false
        public sSupplier(Supplier_Bidding__c s) {
            Supp= s;
            selected = false;

        }
    }


    public List<sSupplier> getSuppliers(){

        Project = ApexPages.currentPage().getParameters().get('Project'); 
        List<String> ProjectID = new List<String>{Project};  
        List<Proc_Contract__c> CurrentContract = New List<Proc_Contract__c>();
        CurrentContract = [SELECT ID, Name FROM Proc_Contract__c WHERE ID in :ProjectID];

        if(SupplierList == null){

            SupplierList = new List<sSupplier>();
            for(Supplier_Bidding__c s: [SELECT ID, Existing_Supplier_Record__c, Existing_Supplier_Record__r.Name, Name, Primary_Portal_Contact__r.Name, Main_Contact__c, Email__c, Primary_Portal_Contact__r.Email FROM Supplier_Bidding__c WHERE Project__c IN :CurrentContract AND (Primary_Portal_Contact__r.Email <> null OR Email__c <> null) ]){


            SupplierList .add(new sSupplier(s));

            }


        }

        return SupplierList;

    }


    public pagereference processSelected() {

        //Project = ApexPages.currentPage().getParameters().get('Project'); 
        //List<String> ProjectID = new List<String>{Project}; 
        //String userName = UserInfo.getUserName();
        //User activeUser = [Select ID, Email From User where Username = : userName limit 1]; 
        List<Supplier_Bidding__c>  selectedSuppliers = new List<Supplier_Bidding__c>();
        List<String> Emails = new List<String>();

        for(sSupplier sSupp: getSuppliers()){

            if(sSupp.selected == true){
                selectedSuppliers.add(sSupp.supp);
                    }
                }

                for(Supplier_Bidding__c Supp: selectedSuppliers){

                    Emails.add(Supp.Email__c);

                }


                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); 

                 mail.setToAddresses(Emails);
                 mail.setplaintextbody(CustomText);
                 //mail.setsubject(CustomSubject);


                 Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

        SupplierList = null;
         return null;

        }
}

My visualforce page:

<apex:page controller="CustomButtonController" >


    <apex:form >
        <apex:pageBlock >


            <apex:pageBlockTable value="{!Suppliers}" var="s" id="table">
                <apex:column >

                    <apex:inputCheckbox value="{!s.selected}"/>
                </apex:column>

                <apex:column value="{!s.Supp.Name}" />
                <apex:column value="{!s.Supp.Primary_Portal_Contact__r.Name}" />
                <apex:column value="{!s.Supp.Main_Contact__c}" />
                <apex:column value="{!s.Supp.Email__c}" />

            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>

    <apex:form >
        <apex:pageBlock >
        <apex:outputtext value="Enter Email Subject Here:" /><br/>
        <apex:inputTextarea id="CustomSubject" value="{!CustomSubject}" style="width: 700px; height: 20px"/> <br/>
        <apex:outputtext value="Enter Main Email Body Here:" /><br/>
        <apex:inputTextarea id="CustomText" value="{!CustomText}" style="width: 700px; height: 200px"/> 
        </apex:pageBlock> 

        <apex:commandButton ID="Send" action="{!processSelected}"  value="Send To Selected Suppliers"/>



    </apex:form>

The issue is in the "ProcessSelected" method during the if statement within the loop through the list of suppliers bidding inside the wrapper class.

I am wondering if the issue is to do with the page re rendering attributes that are causing the check boxes to lose their value before they can be passed back to the controller?

Best Answer

I think the problem will be on the following line:

for(sSupplier sSupp:getSuppliers()){

This is because in your getSuppliers method, you're recalling the query and rebuilding the rows returned thus selected will always be false.

To resolve this, I think you just need to iterate over the list you've already got, in your case: SupplierList.

for(sSupplier sSupp : SupplierList){

When you call processSelected() on your Visualforce page, the new values (i.e. the checkbox) will be posted and thus you can loop over them and process your action based on selected values.

Edit

I've noticed another problem too in that you've got your <apex:commandButton /> outside of the <apex:form /> which your Supplier data is. So, when you're clicking the following button:

<apex:commandButton ID="Send" action="{!processSelected}"  value="Send To Selected Suppliers"/>

It's posting a completely different form.

In addition to my first solution, try adding your <apex:commandButton /> to the "top" <apex:form />. If you debug your selectedSuppliers List you should, then, see the values you've selected. In order to use both forms in the same callout, you'll need to merge them.

Related Topic