Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

So I'm trying to Embed a VF page on my Incoming_Payment__c object, that will allow connecting a few opportunities to it. I want to:

  1. Show all opportunities related to the same account (Works!)

2. If opportunity is already connected to the payment, show the checkbox as checked (my current problem)

  1. Add a button that would connect the opportunities based on page selection (my future problem, didn't get to this yet but I'm noting it so it would be clear that I need the user to be able to be able to change the default value)

I can't see how I can control the checkbox value based on attributes in my controller (I can easily find the ones that are supposed to be checked, but how do I tell the page that?)

My page:

<apex:page standardcontroller="Incoming_Payment__c" extensions="vfAddOppsToPayment" >
<apex:pagemessages id="errmsg"/>  <apex:form >
<apex:outputPanel id="main">
<table>
<tr>
 <apex:repeat value="{!headers}" var="h">
  <td class="hdr">{!h}</td>
 </apex:repeat>
</tr>
<apex:repeat value="{!Opps}" var="a">
 <tr>
  <td ><apex:inputCheckbox value="{!a.id}" selected="true" /></td>
  <td>"{!a.name}" </td>
  <td>"{!a.Account.name}" </td>
  </tr>
</apex:repeat>
</table>    </apex:outputPanel>
 </apex:form>   
 </apex:page>

My Controller:

public with sharing class vfAddOppsToPayment {

public vfAddOppsToPayment(ApexPages.StandardController controller)   {

//this.MonthlyReport = (Monthly_Report__c)controller.getSubject();   this.payment =    (Incoming_Payment__c)controller.getrecord();   payment
= [select id, Account__c from Incoming_Payment__c p where id=:payment.id ];       this.ViableOpps = [ SELECT Id,Invoice_Receipt__c, name, Account.name, AccountId 
                    FROM Opportunity o WHERE o.AccountId = :payment.Account__c ];   }

 // public Getter to provide table headers

  public string[] getheaders() { 

   return new string []   {'Related','Opportunity Name','Account'} ;
     }


  // public Getter to get child list

   public Opportunity[] getOpps() {

   return this.ViableOpps;

   }
     // class variables

   Incoming_Payment__c  payment;

   Opportunity[] ViableOpps;

  }
share|improve this question
add comment

1 Answer 1

up vote 3 down vote accepted

How I would set this up is by way of a wrapper class. Here's a nifty trick that uses a Set to determine the state of each checkbox that's lightweight, and has the bonus of providing you with a populated Set of selected records for your controller to use automatically.

public with sharing class vfAddOppsToPayment {

    public vfAddOppsToPayment(ApexPages.StandardController controller)   {
        //this.MonthlyReport = (Monthly_Report__c)controller.getSubject();   
        payment = (Incoming_Payment__c)controller.getrecord();   
        payment = [select id, Account__c from Incoming_Payment__c p where id=:payment.id ];       
        ViableOpps = [SELECT Id,Invoice_Receipt__c, name, Account.name, AccountId 
                        FROM Opportunity o WHERE o.AccountId = :payment.Account__c];
        selectedOpps = new Set<Id>();

        // HERE:: Determine which opps to select by default simply by adding their ID to selectedOpps
    }

    // public Getter to provide table headers
    public string[] getheaders() { 
        return new string [] {'Related','Opportunity Name','Account'} ;
    }

    // public Getter to get child list
    public OpportunityWrapper[] getOpps() {
        OpportunityWrapper[] items = new OpportunityWrapper[0];
        for(Opportunity record: ViableOpps) {
            items.add(new OpportunityWrapper(this, record));
        }
        return items;
    }

    // class variables
    Incoming_Payment__c  payment;
    Opportunity[] ViableOpps;
    Set<Id> selectedOpps;

    // Wrapper class
    public class OpportunityWrapper {
        public OpportunityWrapper(vfAddOppsToPayment controller, Opportunity record) {
            this.controller = controller;
            this.record = record;
        }
        vfAddOppsToPayment controller;
        public Opportunity record { get; set; }
        public Boolean isSelected { 
            get { 
                return controller.selectedOpps.contains(record.Id); 
            }
            set { 
                if(value)
                    controller.selectedOpps.add(record.Id);
                else
                    controller.selectedOpps.remove(record.Id);
            }
        }
    }
}

Then, you simply change your page as follows:

<apex:page standardcontroller="Incoming_Payment__c" extensions="vfAddOppsToPayment" >
<apex:pagemessages id="errmsg"/>  <apex:form >
<apex:outputPanel id="main">
<table>
<tr>
 <apex:repeat value="{!headers}" var="h">
  <td class="hdr">{!h}</td>
 </apex:repeat>
</tr>
<apex:repeat value="{!Opps}" var="a">
 <tr>
  <td ><apex:inputCheckbox value="{!a.isSelected}" /></td>
  <td>"{!a.record.name}" </td>
  <td>"{!a.record.Account.name}" </td>
  </tr>
</apex:repeat>
</table>    </apex:outputPanel>
 </apex:form>   
 </apex:page>
share|improve this answer
    
Looks good! but it seems the wrapper class doesn't get the values from controller.selectedOpps - that always comes up as null. –  Uri Jun 16 at 13:09
    
Worked great in the end - Thanks! I just forgot to add "this." when defining "selectedOpps" –  Uri Jun 17 at 8:13
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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