+ Start a Discussion
Robin BarnwellRobin Barnwell 

Custom visualforce list view page with group select enabled

I'm stuck.  I've created a custom VF page that lists some records. 

I want to include the ListView select option so the user can pick some of them and update them, List this....

User-added image
How do I get the checkbox to work for a cutom VF page??
Gaurish Gopal GoelGaurish Gopal Goel
Hi Robin, Please paste your VF page code so that I can help. I have developed this type of feature many times. Thanks.
Robin BarnwellRobin Barnwell
Here you go:

<apex:page Controller="UpdateAssignments">
    <apex:form >        
        <apex:pageBlock >        
            <apex:pageBlockButtons location="top">
                <apex:commandButton value="Update Records" action="{!UpdateRecords}"/>
            </apex:pageBlockButtons>       
        
            <apex:pageBlockTable value="{!assignment}" var="a">        
                <apex:column style="width:100px" headerValue="Subscription Id" value="{! a.OrderApi__Subscription__r.OrderApi__Account__r.Name}"/>  
                <apex:column style="width:100px" headerValue="Subscription Id" value="{! a.OrderApi__Subscription__r.Name}"/>             
                <apex:column style="width:100px" headerValue="Assignment Name" value="{! a.name }"/>
                <apex:column style="width:100px" headerValue="Active?" value="{! a.OrderApi__Is_Active__c }"/>
                <apex:column style="width:100px" headerValue="Assignment Item Name" value="{! a.OrderApi__Item__r.Name   }"/> 
                <apex:column style="width:100px" headerValue="Subscription Item Name" value="{! a.OrderApi__Subscription__r.OrderApi__Item__r.Name   }"/>           
                
            </apex:pageBlockTable>
        </apex:pageBlock>    
    </apex:form>
</apex:page>

public class UpdateAssignments {
    public List<OrderApi__Assignment__c> assignment { get; private set; }
    
    public UpdateAssignments () {
        assignment = [SELECT Id, 
                            Name,
                            OrderApi__Is_Active__c,
                            OrderApi__Item__r.Id,
                            OrderApi__Item__r.Name,
                            OrderApi__Subscription__r.Id,                           
                            OrderApi__Subscription__r.Name,
                            OrderApi__Subscription__r.OrderApi__Item__r.Id,
                            OrderApi__Subscription__r.OrderApi__Item__r.Name,
                            OrderApi__Subscription__r.OrderApi__Account__r.Name

                        FROM OrderApi__Assignment__c
                        WHERE OrderApi__Item__r.id = null 
                            AND OrderApi__Subscription__r.Id != null
                            AND OrderApi__Subscription__r.OrderApi__Item__r.Name != 'Membership Individual'
                            AND OrderApi__Is_Active__c = True
                            
                            
                        LIMIT 1000 ];
    }

    public void UpdateRecords() {
        For ( OrderApi__Assignment__c a : assignment){
            system.debug(a.id);
        }
    }
}

 
Gaurish Gopal GoelGaurish Gopal Goel
Hi Robin,

You can use an inner class commonly known as wrapper class in programming terms. This is how it works:

VF Page Code
<apex:page controller="outerClass">
	<apex:form>
		<table>
			<tr><td>Select</td><td>Account Name</td></tr>
			<apex:repeat value="{!innerWrapper}" var="i">
				<tr><td><apex:selectCheckbox value="{!i.isCheck}"/></td></tr>
				<tr><td><apex:outputField value="{!i.acc.Name}"</td></tr>
			</apex:repeat>
		</table>
	</apex:form>
</apex:page>
Apex Controller Code
public class outerClass
{
	public List<innerClass> innerWrapper{get;set;}
	
	public outerClass()
	{
		innerWrapper = new List<innerClass>();
		List<Account> accList = [SELECT Id,Name FROM Account WHERE Name LIKE '%John%' LIMIT 50000];
		if(accList != null && accList.size() > 0)
		{
			for(Account acc: accList)
			{
				innerWrapper.add(new innerClass(acc));
			}
		}
	}
	
	public class innerClass
	{
		public Boolean isCheck{get;set;}
		public Account acc{get;set;}
		public innerClass(Account acc)
		{
			isCheck = false;
			this.acc = acc;
		}
	}
}
Gaurish Gopal GoelGaurish Gopal Goel
Correction in VF Page code
<apex:page controller="outerClass">
	<apex:form>
		<table>
			<tr><td>Select</td><td>Account Name</td></tr>
			<apex:repeat value="{!innerWrapper}" var="i">
				<tr><td><apex:selectCheckbox value="{!i.isCheck}"/></td>
				<td><apex:outputField value="{!i.acc.Name}"</td></tr>
			</apex:repeat>
		</table>
	</apex:form>
</apex:page>
Gaurish Gopal GoelGaurish Gopal Goel
Hi Robin, This is how you can have checkboxes along with your records from any sObject. This is just an example, you will need to go through, understand and then implement it according to your own requirement. Thanks.
Robin BarnwellRobin Barnwell
OK, thanks, let me work through the code and see if I get the idea.  Thanks for your help Gaurish, much appreciated
Robin BarnwellRobin Barnwell
Also, how did you get you code samples to show correctly for copy & paste?
Robin BarnwellRobin Barnwell
How do I set-up a button to call the UpdateRecords apex method with those selected?
Gaurish Gopal GoelGaurish Gopal Goel
You can use your wrapper list "innerWrapper".
for(innerClass i: innerWrapper)
{
      if(i.isCheck)
      {
             //It means that this record was checked and you can now write your logic here.
             Account acc = i.acc;
      }
}

 
Robin BarnwellRobin Barnwell
Thanks, but I can't seem to define a button that calls the Apex function when apex:repeat is used. 

If I revert back to apex:pageBlockTable then the button does work, as per my original code.  But the Checkbox doesn't display for the Boolean defined in the innerclass. 

Hence if I use apex:repeat I can't get a button to call the Apex update method.  If I use apex:pageBlockTable I can't get the Boolean to render as a checkbox.  

What do you suggest please?
Gaurish Gopal GoelGaurish Gopal Goel
Hi Robin, You must doing something wrong. Repeat and Pageblocktable are conceptually the same things, they are used to iterate over a list. Try this:
VF PAGE CODE:
<apex:page controller="outerClass">
	<apex:form id="formId">
		<table>
			<tr><td>Select</td><td>Account Name</td></tr>
			<apex:repeat value="{!innerWrapper}" var="i">
				<tr><td><apex:selectCheckbox value="{!i.isCheck}"/></td></tr>
				<tr><td><apex:outputField value="{!i.acc.Name}"</td></tr>
			</apex:repeat>
			<tr><td><apex:commandButton value="Save" action="{!save}" rerender="formId"/></td></tr>
		</table>
	</apex:form>
</apex:page>
APEX CLASS CODE:
public class outerClass
{
	public List<innerClass> innerWrapper{get;set;}
	 
	public outerClass()
	{
		innerWrapper = new List<innerClass>();
		List<Account> accList = [SELECT Id,Name FROM Account WHERE Name LIKE '%John%' LIMIT 50000];
		if(accList != null && accList.size() > 0)
		{
			for(Account acc: accList)
			{
				innerWrapper.add(new innerClass(acc));
			}
		}
	}
	
	public void save()
	{
		List<Account> accListToUpdate = new List<Account>();
		for(innerClass i: innerWrapper)
		{
			if(i.isCheck)
			{
				//adding the checked accounts into a list and updating their name.
				accListToUpdate.add(new Account(Id=i.acc.Id, Name=i.acc.Name+'--Updated'));
			}
		}
		update accListToUpdate;
	}
	
	public class innerClass
	{
		public Boolean isCheck{get;set;}
		public Account acc{get;set;}
		public innerClass(Account acc)
		{
			isCheck = false;
			this.acc = acc;
		}
	}
}
Robin BarnwellRobin Barnwell
I've taken the code and added a debug statement to see if the Apex method function is accessed.  In Console the debug doesn't show.  Hence I don't think the command button on the VF page is calling it correctly.  I did a couple of bug fixes to the VF code to get it compile
 
public class outerClass
{
    public List<innerClass> innerWrapper{get;set;}
     
    public outerClass()
    {
        innerWrapper = new List<innerClass>();
        List<Account> accList = [SELECT Id,Name FROM Account WHERE Name LIKE '%' LIMIT 50000];
        if(accList != null && accList.size() > 0)
        {
            for(Account acc: accList)
            {
                innerWrapper.add(new innerClass(acc));
            }
        }
    }
    
    public void save()
    {
        system.debug('Hello');
        List<Account> accListToUpdate = new List<Account>();
        for(innerClass i: innerWrapper)
        {
            if(i.isCheck)
            {
                //adding the checked accounts into a list and updating their name.
                accListToUpdate.add(new Account(Id=i.acc.Id, Name=i.acc.Name+'--Updated'));
            }
        }
        update accListToUpdate;
    }
    
    public class innerClass
    {
        public Boolean isCheck{get;set;}
        public Account acc{get;set;}
        public innerClass(Account acc)
        {
            isCheck = false;
            this.acc = acc;
        }
    }
}
<apex:page controller="outerClass">
    <apex:form id="formId">
        <table>
            <tr><td>Select</td><td>Account Name</td></tr>
            <apex:repeat value="{!innerWrapper}" var="i">
                <tr><td><apex:selectCheckboxes value="{!i.isCheck}"/></td>
                <td><apex:outputField value="{!i.acc.Name}"/></td></tr>
            </apex:repeat>
            <tr><td><apex:commandButton value="Save" action="{!save}" rerender="formId"/></td></tr>
        </table>
    </apex:form>
</apex:page>


 
Gaurish Gopal GoelGaurish Gopal Goel
Hi Robin, Please check your debug filters are correctly set.