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
KevinBrKevinBr 

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: &nbsp; <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;
        
    }
}