1

(Problem / Question listed at the bottom, below explanation content)

Background: I've created a relatively simple VisualForce page with the intention of allowing our customers to update data about their account contacts. I've done this by creating a Custom VF page that uses the Standard Account controller and extends it with a custom extension.

Among other things, the controller extension creates a ContactWrapper class, and then my contactList (which I iterate through on the VF page in a data table) loops through all contacts related to the acct.Id and adds them to the contactList before returning the multi-select list to the page.


Controller Extension:

    public class ContactWrapper {
        public Contact con {get; set;}
        public Boolean checked {get; set;}

        public ContactWrapper(Contact c) {
            con = c;
            checked = false;
        }
    }  

    public List<ContactWrapper> contactList {
        get{
            if(contactList == null){           
                contactList = new List<ContactWrapper>();
                for(Contact contact : [SELECT FirstName,LastName,Authorized_Personnel__c,Title__c FROM Contact WHERE AccountId = :acct.Id]){
                    contactList.add(new ContactWrapper(contact));
                }
            }   
            return contactList;
        }
        set;
    }

VF Page:

<apex:pageblock >
  <apex:DataTable value="{!contactList}" var="cl" style="width:50%;margin:0 auto;">
      <apex:column style="" width="80px" headerValue="Select">
          <apex:inputCheckbox value="{!cl.checked}" />
      </apex:column>
      <apex:column value="{!cl.con.FirstName}" headerValue="First Name" />
      <apex:column value="{!cl.con.LastName}" headerValue="Last Name" />
      <apex:column headerValue="Title">
          <apex:inputField value="{!cl.con.Title__c}" />
      </apex:column>
      <apex:column value="{!cl.con.Authorized_Personnel__c}" headervalue="Authorized Personnel?" />
  </apex:DataTable>

This results in the following output:

enter image description here


I then created a {!setAuthorized} commandButton which loops through any ContactWrappers in the contactList that have checked = true (selected), and adds them to a selectedContacts list, which I use to query the contact list from the database, update the appropriate boolean to True for each appropriate contact, add them to an update list, and finally update the list if size > 0.

    public PageReference setAuthorized() {

        selectedContacts.clear();

        for(ContactWrapper cw : contactList){
            if(cw.checked){
                selectedContacts.put(cw.con.Id, cw);
            }
        }

        contactsToAuthorize = new List<Contact>([SELECT FirstName,LastName,Authorized_Personnel__c FROM Contact WHERE Id IN :selectedContacts.keySet()]);        
        contactsToUpdate = new List<Contact>();

        for(Contact contact : contactsToAuthorize){
            contact.Authorized_Personnel__c = true;
            contactsToUpdate.add(contact);
        }

        if(contactsToUpdate.size() > 0){
            update contactsToUpdate;
            return Page.AuthorizedPersonnelForm;
        } 
        else{
            ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.ERROR, 'Please select at least one Contact'));
            return null;
        }
    }

Problem: This worked fine when all I wanted to do was update the Boolean to True or False depending on which button they pressed... but the scope of the design has changed and I now want them to be able to change the contact's title from an available picklist (as seen in the screenshot above) as well, and update all associated contacts at once as the result of pressing the command button.

My flaw here (I think) is that I am getting a new list of contacts (contactsToAuthorize) by querying the DB for any contacts where the ID is in my selectedContacts keySet, and then using that new list as my basis for field updates and DML. I need a way to dynamically update the values of the title for the contacts based on the values that were selected on the page before pressing the commandButton. I am fairly new to VisualForce and Custom Controllers still, so what may be simple to some veterans is perplexing me slightly. How would I best approach this?

1

I think I solved this, not sure if this is the best approach or not so would love some feedback on this before I mark this answer as correct, but what I did was I modified the for() loop through the contactsToAuthorize and changed it from this:

        for(Contact contact : contactsToAuthorize){
                contact.Authorized_Personnel__c = true;
                contactsToUpdate.add(contact);
            }
        }

To this:

        for(Contact contact : contactsToAuthorize){
            if(selectedContacts.containsKey(contact.Id)){
                Contact selectedContact = selectedContacts.get(contact.Id).con;
                System.debug('MM++++ Selected Contact: ' + selectedContact);
                contact.Authorized_Personnel__c = selectedContact.Authorized_Personnel__c;
                contact.Title__c = selectedContact.Title__c;
                contactsToUpdate.add(contact);
            }
        }

So during the loop through each individual contact, I am:

  1. double checking to make sure that the map contains the contact.Id
  2. using the maps key/value pair to build a temporary contact record, based on the value of 'con' in the map, that relates to this contact but provides the content from the ContactWrapper map
  3. assigning the values for DML update based on the values in the temporary contact record
  4. Adding the updated contact record to the update list

Then once I'm outside of the loop I update the contact list as normal.

Is this the best approach for this type of scenario?

  • So far, your approach is good. – Santanu Boral Jul 8 '16 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.