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
fundooMentalfundooMental 

Wrapper Class

I was just trying to understand wrapper classes and then happen to see the below code. Understood everything almost but one thing I am not able to understand is; if I select one or two Account records by clicking on the checkbox (and not all account records through the topmost checkbox), then how the value of the Boolean variable "Selected" is becoming True from false for the selected account records?

See the below Visualforce code and controller class:
-----------VF------------------------------
<apex:page controller="wrapperControllerClassExample1" sidebar="false">
    <script type="text/javascript">
        function selectAllCheckboxes(obj,receivedInputID){
            var inputCheckBox = document.getElementsByTagName("input");
            for(var i=0; i<inputCheckBox.length; i++){
                if(inputCheckBox[i].id.indexOf(receivedInputID)!=-1){
                    inputCheckBox[i].checked = obj.checked;
                }
            }
        }
    </script>
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockButtons >
                <apex:commandButton value="Show Selected Accounts" action="{!processSelected}" rerender="table2"/>
            </apex:pageBlockButtons>
 
            <apex:pageblockSection title="All Accounts" collapsible="false" columns="2">
 
                <apex:pageBlockTable value="{!wrapAccountList}" var="accWrap" id="table" title="All Accounts">
                    <apex:column >
                        <apex:facet name="header">
                            <apex:inputCheckbox onclick="selectAllCheckboxes(this,'inputId')"/>
                        </apex:facet>
                        <apex:inputCheckbox value="{!accWrap.selected}" id="inputId"/>
                    </apex:column>
                    <apex:column value="{!accWrap.acc.Name}" />
                    <apex:column value="{!accWrap.acc.BillingState}" />
                    <apex:column value="{!accWrap.acc.Phone}" />
                </apex:pageBlockTable>
 
                <apex:pageBlockTable value="{!selectedAccounts}" var="c" id="table2" title="Selected Accounts">
                    <apex:column value="{!c.Name}" headerValue="Account Name"/>
                    <apex:column value="{!c.BillingState}" headerValue="Billing State"/>
                    <apex:column value="{!c.Phone}" headerValue="Phone"/>
                </apex:pageBlockTable>
 
            </apex:pageblockSection>
        </apex:pageBlock>
    </apex:form>
 
</apex:page>

------------Controller-----------------
public class wrapperControllerClassExample1 {
 
    //Our collection of the class/wrapper objects wrapAccount
    public List<wrapAccount> wrapAccountList {get; set;}
    public List<Account> selectedAccounts{get;set;}
 
    public wrapperControllerClassExample1(){
        if(wrapAccountList == null) {
            wrapAccountList = new List<wrapAccount>();
            for(Account a: [select Id, Name,BillingState, Website, Phone from Account limit 10]) {
                // As each Account is processed we create a new wrapAccount object and add it to the wrapAccountList
                wrapAccountList.add(new wrapAccount(a));
            }
        }
    }
 
    public void processSelected() {
    selectedAccounts = new List<Account>();
 
        for(wrapAccount wrapAccountObj : wrapAccountList) {
            if(wrapAccountObj.selected == true) {
                selectedAccounts.add(wrapAccountObj.acc);
            }
        }
    }
 
    // This is our wrapper/container class. In this example a wrapper class contains both the standard salesforce object Account and a Boolean value
    public class wrapAccount {
        public Account acc {get; set;}
        public Boolean selected {get; set;}
 
        public wrapAccount(Account a) {
            acc = a;
            selected = false;
        }
    }
}

 

Best Answer chosen by fundooMental
Philip NelsonPhilip Nelson
Short answer is that there isn't any code that changes it.

When you click on one of the checkboxes in the browser, you are changing the value of the selected property in the View State (https://developer.salesforce.com/page/An_Introduction_to_Visualforce_View_State) on your browser.

When you call the processSelected action, your browser sends the updated View State back to the controller, now with one or two wrapAccount objects with their selected property set to true.

There's probably some JS loaded with the page that actually manipulates the View State objects, but I haven't heard of anyone accessing/manipulating it.

Does that help?

All Answers

Philip NelsonPhilip Nelson
Hey Gyanendra,

I had a hard time understaing this at first too, so I thought a short video might explain it best: 

http://screencast.com/t/AzAEVvkvkMmC

Hopefully this helps.

Thanks,
Philip
fundooMentalfundooMental

Hi Philip,

That is really amazing of you for recording a video to explain how the code works.Million thanks for the effort.But I am sorry to say this Philip, as I had mentioned in the question, I have understood the whole code like how the list is getting populated and how the warpper class is working BUT the only thing that I have NOT understood is which is my actual question is below:

When I select just one or two accounts through the checkbox (and not ALL ten accounts through the topmost checkbox) then how the value of the boolean variable Selected is changing from ''false" to "true"? .Where in code this is happening?

Philip NelsonPhilip Nelson
Short answer is that there isn't any code that changes it.

When you click on one of the checkboxes in the browser, you are changing the value of the selected property in the View State (https://developer.salesforce.com/page/An_Introduction_to_Visualforce_View_State) on your browser.

When you call the processSelected action, your browser sends the updated View State back to the controller, now with one or two wrapAccount objects with their selected property set to true.

There's probably some JS loaded with the page that actually manipulates the View State objects, but I haven't heard of anyone accessing/manipulating it.

Does that help?
This was selected as the best answer
fundooMentalfundooMental

Ahh, now this one is really a great answer. This is what exactly I was looking for as how the view state is playing the role here. Thanks a lot Philip.
It helped but I am still perplexed.

I know the view state might change in a postback request. Now I select the checkbox fine but how does the page knows that it has to make the value of the boolean variable Selected to True from False? Selected is just a Boolean variable of the wrapper class but then how the varibale is getting tied up with the  <apex:inputCheckbox> ? Is it through the value attribute of it?  <apex:inputCheckbox value="{!accWrap.selected}" id="inputId"/> ?

You said "When you click on one of the checkboxes in the browser, you are changing the value of the selected property in the View State " . This is my question, how exactly the value of the Selected property in the View State is becoming True?

Philip NelsonPhilip Nelson
Gyanendra, yes, you are correct that the value attribute of apex:inputCheckbox binds the accWrap.selected property to the rendered checkbox on the page. 

Beyond that, I don't know what specifically happens in the browser to literally manipulate the selected property within the view state object before postback. I presume there is some JS doing that manipulation.

Please take a moment to mark a post as "Best Answer" to help others in the community with similar questions.  Thank you.
 
fundooMentalfundooMental
Thank you Philip for all the replies.