You need to sign in to do that
Don't have an account?

Dynamic Grid using Checkboxes
I have been coming across some odd behaviour using checkboxes and VF page/controllers and
would greatly appreciate if someone can guide me as to what I am doing wrong.
Scenario:
The grid is populated from a button on an Account page.
Going across, are the assets that are available on the account (variable listing).
As it is variable, I am using a repeater process instead of a DataTable.
Each cell for the assets has a checkbox to "select all" of the contacts under it.
Going down, are the contacts for the account (variable listing).
The grid is a set of checkboxes; I am trying to capture the values from a custom
service table (AccountId,ContactId,AssetId,ActiveFlag) which will hold values
from the user's selections.
Account Name: XYZ
Contacts/Assets Asset01 Asset02 Asset03 Asset04
[x] [ ] [ ] [ ]
Contact01 [x] [x] [ ] [ ]
Contact02 [x] [ ] [x] [ ]
Contact03 [x] [ ] [ ] [x]
Issues:
#1 - The all feature works to enable the column, but does not work to uncheck the column
#2 - The checked values in the grid details don't seem to get set.
#3 - I need to persist the original settings from the custom table for comparison cases;
Ideally, a single case will be created for new requests/changes.
Currently I have been using the save button for debugging before/after grid changes;
Orig: TFFF,TFFF,TFFF,TFFF (should be all False)
Chgs: TFFF,TFFF,TFFF,TFFF (appears the all feature took affect on both)
Ideal: TFFF,TTFF,TFTF,TFFT
Source Page: <apex:page sidebar="false" standardController="Account" extensions="myServiceGridController" tabstyle="Account" standardstylesheets="false" > <apex:stylesheet value="{!$Resource.myServiceGridStyles}" /> <apex:form id="addAssetForm"> <apex:pageBlock id="Page" > <apex:pageBlockButtons location="bottom"> <apex:commandButton value="Save" action="{!save}" /> <apex:commandButton value="Cancel" action="{!cancel}" /> </apex:pageBlockButtons> <table align="center" id="hdr" > <tr><td>Account Name: <apex:outputLink value="/{!account.Id}">{!account.Name}</apex:outputLink></td> </tr> <!-- 01. Assets --> <tr> <td> <table cellpadding="5" border="1" cellspacing="0" class="border" > <tr> <td>Contact/Assets</td> <apex:repeat value="{!assetList}" var="a" > <td><apex:outputLink styleclass="asset" value="/{!a.ast.Id}">{!a.ast.Name}</apex:outputLink> <p /> <apex:inputCheckbox id="asset" value="{!a.Selected}" > <apex:actionSupport event="onclick" action="{!setSelectedColumn}" onsubmit="checkAll(this,'{!a.ast.id}')" rerender="assetBlock" > <apex:param name="c1" value="{!a.ast.Id}" assignTo="{!assetId}" /> </apex:actionSupport> </apex:inputCheckbox> </td> </apex:repeat> <apex:pageBlock id="assetBlock" rendered="false" /> </tr> <apex:pageBlock id="matrixStart" rendered="false" /> <!-- 02. Contact, AssetBoxes; no re-rendering is needed --> <apex:repeat value="{!contactList}" var="c"> <tr> <td><apex:outputLink styleclass="contact" value="/{!c.Id}">{!c.Name} <apex:param name="c1" value="{!c.Id}" assignTo="{!contactId}" /> </apex:outputLink></td> <!-- 03. Contact, AssetBoxes; no re-rendering is needed --> <apex:repeat value="{!assetList}" var="a" > <td class="datacell" > <apex:inputCheckbox id="service" value="{!ServiceDetail}" title="{!a.ast.Id}" > <apex:actionSupport event="onclick" action="{!setSelectedBox}" rerender="contactBlock" > <apex:param name="m1" value="{!c.Id}" assignTo="{!contactId}" /> <apex:param name="m2" value="{!a.ast.Id}" assignTo="{!assetId}" /> </apex:actionSupport> </apex:inputCheckbox> <apex:pageBlock id="contactBlock" rendered="false" /> </td> </apex:repeat> </tr> </apex:repeat> </table> </td> </tr> </table> </apex:pageBlock> </apex:form> <script type="text/javascript" > function checkAll(cb,astID) { var inputElem = document.getElementsByTagName("input"); for(var i=0; i<inputElem.length; i++) { if(inputElem[i].title.indexOf(astID)!= -1 ) { inputElem[i].checked = cb; } } } </script> </apex:page> Source Controller: public with sharing class myServiceGridController { private final Account acct; private ApexPages.Standardcontroller controller {get; set;} public List<Contact> contactList; public List<serviceWrapper> originalServicesList; public List<assetWrapper> assetList {get; set;} public List<serviceWrapper> changedList {get; set;} public Boolean checkedAssetAll {get; set;} public Boolean checkedContactAsset {get; set;} public string assetId {get; set;} public string contactId {get; set;} public Boolean ServiceDetail {get; set;} public myServiceGridController(ApexPages.StandardController controller) { this.controller = controller; this.acct = (Account)controller.getRecord(); string url = ApexPages.currentPage().getUrl(); //system.debug('------------- VFController: Acct:' + acct.Name + '(url: ' + url + ')'); if (originalServicesList == null ) { assetList = getAssetList(); contactList = getContactList(); originalServicesList = getOriginalServices(); //pulls up booleans on last service records changedList = originalServicesList; //inits the array, but will be later altered by the user checkedAssetAll = false; checkedContactAsset = false; } } public PageReference setSelectedColumn() { string assetSum = ''; for (assetWrapper asw : assetList) { if (asw.ast.id == assetId ) { checkedAssetAll = asw.selected; for (serviceWrapper svw : changedList ) { if (svw.ast.id == assetId ) { svw.selected = checkedAssetAll; } } } if (asw.selected == true ) { assetSum = assetSum + 'T'; } if (asw.selected == false ) { assetSum = assetSum + 'F'; } if (asw.selected != true && asw.selected != false) { assetSum = assetSum + '?'; } } system.debug('------------- setSelectedColumn: ' + assetId + '/' + assetSum + '/' + checkedAssetAll); return null; } public PageReference setSelectedBox() { for (serviceWrapper svw : changedList ) { if (svw.ast.id == assetId ) { if (svw.con.id == contactId ) { //checkedContactAsset = svw.selected; svw.selected = checkedContactAsset; } } } system.debug('------------- setSelectedBox: ' + assetId + '/' + contactId + '/' + checkedContactAsset ); return null; } // this is to generate the asset list going across; public string parseList (List<serviceWrapper> a) { Integer c=0; Integer j=0; string strSum = ''; for (serviceWrapper svw : a ) { if (svw.selected == true ) { strSum = strSum + 'T'; } if (svw.selected == false ) { strSum = strSum + 'F'; } if (svw.selected != true && svw.selected != false ) { strSum = strSum + '?'; } c = c + 1; if (c >= assetList.size() ) { c=0; j=j+1; if (j<contactList.size()) { strSum = strSum + ',' ; } } } return strSum; } public List<assetWrapper> getAssetList() { List<assetWrapper> results = new List<assetWrapper>(); for (Asset ast : [ SELECT Id, Name, Metric__c FROM Asset where AccountId = :acct.Id order by Name ]) { results.add(new assetWrapper(ast,false)); } system.debug('------------- assetSize: ' + results.size() ); return results; } public List<Contact> getContactList() { List<Contact> results = new List<Contact>(); results = [SELECT Id,Name FROM Contact where AccountId = :acct.Id order by Name ]; system.debug('------------- contactSize: ' + results.size() ); return results; } // per the current matrix, load the booleans for the contact's assets values public List<serviceWrapper> getOriginalServices() { List<serviceWrapper> results = new List<serviceWrapper> (); List<Services__c> serviceGrid = new List<Services__c>(); serviceGrid = [ SELECT sv1.Account_Name__c, sv1.Asset__c, sv1.Contact__c, Case__c, Active__c from services__c sv1 where sv1.Account_Name__c = :acct.Name and sv1.isDeleted = false order by sv1.Case__c desc ]; system.debug('------------- contactSize: ' + contactList.size() ); system.debug('------------- assetSize: ' + assetList.size() ); system.debug('------------- serviceGridSize: ' + serviceGrid.size() ); for (contact con1 : contactList) { for (assetWrapper asw : assetList ) { boolean sel1 = false; Asset as1 = asw.ast; for (Services__c svw : serviceGrid ) { if (svw.Asset__c == asw.ast.id ) { if (svw.Contact__c == con1.id) { sel1 = svw.Active__c; } } } results.add(new serviceWrapper(as1,con1,sel1)); } } return results; } // getService/serviceList - used to store the result of each asset/contact checkbox public Boolean ServiceDetail() { system.debug('------------- getServices: assetId:' + assetId+ '/contactId' + contactId ); boolean results = false; for (serviceWrapper svw : changedList ) { if (svw.ast.id == assetId) { if (svw.con.id == contactId ) { results = svw.selected; } } } return results; } // assetWrapper - used to hold the boolean/checkbox selection for the account, for the asset-select-all public class assetWrapper { public Asset ast{get; set;} public Boolean selected {get; set;} public assetWrapper(Asset b, Boolean sel) { ast = b; if (selected == null ) { selected = false; } else { selected = sel; } } } // serviceWrapper - wrapper class to hold the boolean/checkbox for the matrix detail public class serviceWrapper { public Asset ast{get; set;} public Contact con{get; set;} public Boolean selected {get; set;} public Boolean Original_selection {get; set;} public serviceWrapper(Asset b, Contact c, Boolean sel) { ast = b; con = c; if (selected == null ) { selected = false; } else { selected = sel; } Original_selection = selected; } } public PageReference Save() { string strOrig = parseList(OriginalservicesList); string strChanged = parseList(ChangedList); system.debug('------------- Save: (orig) ' + strOrig); system.debug('------------- Save: (new) ' + strChanged); return null; } }