[SalesForce] Visualforce: Selected InputCheckbox value not updating

** UPDATED (Simplified my custom object to no longer be a wrapper within a wrapper) **

Since posting I've made some adjustments, so at the moment I have a custom wrapper object called ShipmentInvoiceLineItem which basically represents 1 of 2 possible custom objects as well as a boolean selected value:

public class ShipmentInvoiceLineItem {

    public Custom1__c c1 {get; set;}
    public Custom2 c2 {get; set;}
    public String accountId {get; set;}
    public String shipmentId {get; set;}
    public Boolean selected {get; set;}

    public ShipmentInvoiceLineItem(Custom1 c1, Boolean selected){
        this.c1 = c1;
        this.accountId = c1.Shipment__r.Account__c;
        this.shipmentId = c1.Shipment__c;
        this.selected = selected;
    }

    public ShipmentInvoiceLineItem(Custom2 c2, Boolean selected){
        this.c2 = c2;
        this.accountId = c2.Account__c;
        this.shipmentId = c2.Shipment__c;
        this.selected = selected;
    }

}

On the front end I have multiple <apex:repeat> fields that iterates through custom maps I created in my controller (this way I could group by Accounts and Shipment types without my previous complex multi-dimensional map object). The issue I'm having is with the actual form within each of these groupings. Within the form I iterate through my wrapper object like so:

<apex:repeat value="{!ShipmentInvoiceLineItemsByShipment[shipment.Id]}" var="item">

Note: ShipmentInvoiceLineItemsByShipment is structured as list of ShipmentInvoiceLineItems indexed by their shipment Id Map<String,List<ShipmentInvoiceLineItem>>

Visually everything appears to be working fine, as expected the boxes are pre-checked (assuming the user will want these to be checked), but when I uncheck any of of the checkboxes and submit it like so:

enter image description here

When I attempt to iterate through the ShipmentInvoiceLineItemsByShipment it doesn't appear to have SET the boolean value to false as expected.

public PageReference markLineItemsAsPaid() {
    // I passed this as a parameter in <apex:commandLink>
    String id = ApexPages.currentPage().getParameters().get('processID'); 
    for(ShipmentInvoiceLineItem lineItem : getShipmentInvoiceLineItemsByShipment().get( id )){
        if(lineItem.selected == TRUE) {
            System.debug('::SELECTED::');
        }
    }
    return NULL;
}

Any ideas of what could be the problem here?

Best Answer

Keep in mind the documentation on <apex:form> states:

"As of API version 18.0, ​this tag can't be a child component of <apex:repeat>"

So, your <apex:form> should be outside of your <apex:repeat>

Then, you should apex:actionRegion tags so that you only have one form tag. With this you can submit the data by region instead of multiple forms as stated here:

http://th3silverlining.com/2009/10/19/multiple-forms-in-a-single-visualforce-page/