+ Start a Discussion
KtobenerKtobener 

Wrapper Class Not Registering Checkbox Selected from Visualforce Page (Selected Always False)

I've been working on a Visualforce page that displays An account, it's child charitable contributions, and then offers the user the ability to select accounts to recieve charitable donations. The list of accounts is parsed in through the URL. I have the page looking perfect exactly as I'd like (See screen shot below)

 

VF Screen Shot

 

 

The trouble exists when I go to process the selected orders. The selections made on the page do not appear in the class as selected. I confirmed that I can hardcode the list of orders as selected in the class and they will appear checked in the page, but I cannot make the logic work in the other direction. I'm wondering if this has something to do with the nesting of the repeat within a pageblocktable? If anyone has a sense of where I'm making a mistake I'd greatly appreciate it. I can probably solve the problem with javascript, but I'd love to improve my skills with visualforce and apex! I've included the portions of the page and class that I think are relevant, but I can include all the relevant code if there is a piece of the puzzle missing.

 

 

Page Snippet:

<apex:pageBlockTable value="{!Account.Food_Donation_Contributions__r}" var="c" cellpadding="4" id="contributetable">
<apex:column headerValue="Contribution Name" value="{!c.Name}"/>
<apex:column headerValue="Product Type" value="{!c.Product_Type__c}"/>
<apex:column headerValue="Remaining Packs" value="{!c.Total_Remaining_Packs__c}"/>
<apex:column headerValue="Remaining Cases" value="{!c.Total_Remaining_Cases__c}"/>
<apex:column headerValue="Remaining Pallets" value="{!c.Total_Remaining_Pallets__c}"/>
<apex:column headerValue="Choose Recieving Accounts">
<table width="600" border="0">
<tr>
<th align="left">Target Account:</th>
<th align="left">Account Information:</th>
<th align="right">Select</th>
</tr>
<apex:repeat value="{!orders}" var="o">
<apex:outputpanel >
<tr>
<td align="left">{!o.awoname}</td>
<td align="left">Sample Program 1, Sample Program 2, Sample Program 3</td>
<td align="right" width="35"><apex:inputCheckbox value="{!o.selected}"/></td>
</tr>
</apex:outputpanel>
</apex:repeat>
</table>
</apex:column>
</apex:pageBlockTable>
<BR/><BR/><BR/><BR/><BR/>
</apex:pageBlock>
</apex:form>

 

 

Controller Snippet:

 

public pagereference processSelected(){

/*We create a new list of Orders that we be populated only with Ordersif they are selected*/

List<PFD_AWO_Order__c> selectedorders = new List<PFD_AWO_Order__c>();

/*We will cycle through our list of cOrders and will check to see if the
selected property is set to true, if it is we add the Order to the selectedorders list. */
for(cOrder cO : orderList){
if(cO.selected == true){
selectedorders.add(cO.order);
}
}

/* Now we have our list of selected orders and can perform any type of
logic here. In this instance, when active, we will insert the list of orders. */


for(PFD_AWO_Order__c AWOORDER : selectedOrders){
ordermessage = ordermessage + '[Order from'+AWOORDER.PFD_Contribution__c +' for ' +AWOORDER.Animal_Welfare_Org__c+' ]';
}

insert selectedorders;
return null;
}

 

 

Thanks!

 

 

bob_buzzardbob_buzzard
The snippets you've posted look okay.  Can you post the wrapper class?  That's what should be capturing the checkbox status.
KtobenerKtobener

public class PFDOrders{ public Account primaryaccount { get; set;} public String idstring{get;set;} public List<cOrder>orderList {get; set;} public boolean hascreatedorders {get;set;} public string ordermessage {get;set;} public Account getAccount() { primaryaccount = [SELECT id, name, Program_Enrollment__c,(Select Weight__c, Weight_Type__c, Total_Remaining_Pallets__c, Total_Remaining_Packs__c, Total_Remaining_Cases__c, Product_Type__c, Name, Donor_Org__c From Food_Donation_Contributions__r), Type FROM Account WHERE id = :ApexPages.currentPage().getParameters().get('id')]; return primaryaccount; } /* 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.*/ public class cOrder{ public PFD_AWO_Order__c order {get; set;} public Boolean selected {get; set;} public String awoname {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 cOrder(PFD_AWO_Order__c o){ order = o; selected = false; awoname = ''; } } // This is the method for putting the individual Orders as checkbox options next to each Contribution public List<cOrder> getOrders(){ system.debug('here is orderList= '+orderlist); if(orderList == null){ // The list of Valid Contributions List<PFD_Contributions__c> conlist = primaryaccount.Food_Donation_Contributions__r; // The List of Accounts list<Account> accountlist = new list<Account>(); //The List of Account ID's (For passing to creation methods) list<id> idL = new list<id>(); // Grab the unproccessed string list from the URL string urlidstring = ApexPages.currentPage().getParameters().get('urlidstring'); // Proccess the string into a valid list list<string> idstringlist = new list<string>(urlidstring.split(',',0)); // The List of valid Accounts list<Account> acclist = new list<Account>([select id, name from account where id in: idstringlist]); //Create The ID List (To reuse the contact list code) For(Account a1:acclist){ idL.add(a1.id); } //Map The Primary Contacts Map<Id, Contact> contactmap = getPrimaryContact(idL); orderList = new List<cOrder>(); For(account acc : acclist){ for(PFD_Contributions__c c:conlist){ // Create a cOrder for every combination of Contribution and Account PFD_AWO_Order__c Order1 = new PFD_AWO_Order__c(); //Donor Account Order1.Contributing_Account__c = primaryaccount.id; //Recieving Account Order1.Animal_Welfare_Org__c = acc.id; //Master Contribution Order1.PFD_Contribution__c = c.id; // Order Status Order1.Status__c = 'Donation Offered'; //Set the Primary Contact if(contactmap.get(acc.id)!= null){ Contact Con1 = contactmap.get(acc.id); Order1.Contact_Lookup__c = Con1.id; Order1.Phone__c = Con1.Phone; Order1.Cell__c = Con1.MobilePhone; Order1.Contact__c = Con1.Name; } //Turn the Order into a cOrder and add to list! cOrder co = new cOrder(Order1); co.awoname = acc.name; system.debug('CO AFTER ' +co); orderList.add(co); } } } return orderList; } public pagereference processSelected(){ /*We create a new list of Orders that we be populated only with Orders if they are selected*/ List<PFD_AWO_Order__c> selectedorders = new List<PFD_AWO_Order__c>(); /*We will cycle through our list of cOrders and will check to see if the selected property is set to true, if it is we add the Order to the selectedorders list. */ for(cOrder cO : orderList){ system.debug('Here is the current cO BEFORE' + cO); //cO.selected=true; system.debug('Here is the current cO AFTER' + cO); if(cO.selected == true){ selectedorders.add(cO.order); } } system.debug('We have selected orders: '+selectedorders); /* Now we have our list of selected orders and can perform any type of logic here. In this instance, when active, we will insert the list of orders. */ for(PFD_AWO_Order__c AWOORDER : selectedOrders){ ordermessage = ordermessage + '[Order from '+AWOORDER.PFD_Contribution__c+' for '+AWOORDER.Animal_Welfare_Org__c+' ]'; } system.debug('Here is the ordermessage: '+ordermessage); // insert selectedorders; hascreatedorders=true; return null; }

 



I wondered if the errors had something to do with the repeat containing all combinations of Account and Contribution (Rendered = {! Account.contribution = Contribution.id} so only relevant orders show), but even in the simplest combination of 1 account x 1 contribution = 1 Order it does not sense the selection. The system.debug tucked right inside public List<cOrder> getOrders{  shows the whole list of cOrders as selected=false right after the command button runs processesselected().

 

Thanks for the help!

bob_buzzardbob_buzzard

When you post your information back, do you return to the same page?  (From the code it looks like it, but I don't have sight of the VF page).  If that is the case, are you simply redrawing the page, or rerendering part of the page?

 

I had something weird a couple of weeks ago that sounds similar.  I have nested repeats similar to you, but with buttons with parameters bound to properties in the controller.  When I was using rerender on my pageblock containing my buttons, the property values in the controller were updated correctly.  When I refreshed the entire page, none of them got bound - all were null and none of the getters invoked.

 

So, while this may sound like an odd request, have you tried rerendering?

KtobenerKtobener
Nothing in my visualforce has set rerender to true. However, when I used the commandbutton, it does seem like the page reloads; The url loses the id's, and all the checkboxes that were checked become unchecked. I will try adding a rerender to the pageblocktable and let you know what the result is.
KtobenerKtobener

I added a rerender"form1" to my commandbutton, where form1 is the form containing the account, contributions, and nested repeat. When I click the commandbutton, I get the following:

 

An internal server error has occurred An error has occurred while processing your request. The salesforce.com support team has been notified of the problem. If you believe you have additional information that may be of help in reproducing or correcting the error, please contact Salesforce Support. Please indicate the URL of the page you were requesting, any error id shown on this page as well as any other related information. We apologize for the inconvenience.

Thank you again for your patience and assistance. And thanks for using salesforce.com!

Error ID: 1461116661-2057 (1748741421) 

 

 

 

Not exactly what we were looking for. However, according to the debug log,  all my selected checkboxes are still returning false.

Rajesh ShahRajesh Shah

Maybe because the getOrder function is getting called again for each row. If that is the case, then the orderList is getting generated again for each row and the previous column might lose the reference since the orderList is changed. What happens if you check the checkbox for the last row? Are they reflected as checked in the controller?

 

-- Just checked, you have the condition orderList == null, so the above is incorrect.

 

However, now you have 3 rows each of which iterate over the orderList. So when you check a checkbox in one row ( lets say for test org for contribution 1 but not for test org for contri 2 and 3), how is the controller going to identify which value it should take from the page? Because it has 3 references to the same property in the page.

Message Edited by Rajesh Shah on 02-09-2010 12:57 PM
KtobenerKtobener
That is an interesting point. I worried about this same problem as well. But, I don't think it is the immediate concern, because in cases where there is only one row and one account (1 checkbox), it isn't reflected in the controller. I also tried removing the render logic, to display all the checkboxes in each repeat. Checking all of the boxes does not reflect in the controller also.
Rajesh ShahRajesh Shah
Well now I am not sure of the reason of the problem. But anyways the point I raised earlier will have to be considered in the future. I think it would be best to create a wrapper class containing contribution details as well. You would anyways have to do this or something similar later on.
SindhugsSindhugs

Did you find a solution to your problem? This is happening to me as well..