You need to sign in to do that
Don't have an account?
aapt.dev
Help needed understanding controller extensions
Hi
I'm an advanced administrator but have absolutely no coding skills and am trying to teach myself some basic APEX and VisualForce.
I am having some difficulty understanding standard controller extensions and was hoping that someone can give me a little guidance here. I have scoured the discussion boards but have failed miserably in locating a post that I could understand so apologies in advance if this is a topic that has already been dealt with.
I'm trying to build a VF page that will allow users to mass update the Contacts on an Account e.g. phone numbers, flag as inactive etc.
My code:
public class accountContactList {
public PageReference save() {
return null;
}
public Account getAccount() {
return [select id, name,
(select id, name, firstName, lastName, title, phone, mobilePhone, email from Contacts limit 5)
from Account where id =
:ApexPages.currentPage().getParameters().get('Id') ];
}
public String getName() {
return 'Account Contact List';
}
}
public PageReference save() {
return null;
}
public Account getAccount() {
return [select id, name,
(select id, name, firstName, lastName, title, phone, mobilePhone, email from Contacts limit 5)
from Account where id =
:ApexPages.currentPage().getParameters().get('Id') ];
}
public String getName() {
return 'Account Contact List';
}
}
My VF page:
<apex:page controller="accountContactList" tabStyle="Contact">
<apex:pageBlock title="Mass Edit Contacts">
</apex:pageBlock>
<apex:form >
<apex:pageBlock >
<apex:pageMessages />
<apex:pageBlockButtons >
<apex:commandButton action="{!save}" value="Save" id="theButton"/>
</apex:pageBlockButtons>
<apex:pageBlockTable value="{!account.Contacts}"
var="contact">
<apex:column value="{!contact.name}" width="25" />
<apex:column headerValue="Title" width="100">
<apex:inputField value="{!contact.title}"/>
</apex:column>
<apex:column headerValue="Phone" width="15">
<apex:inputField value="{!contact.phone}"/>
</apex:column>
<apex:column headerValue="Mobile" width="15">
<apex:inputField value="{!contact.mobilephone}"/>
</apex:column>
<apex:column headerValue="E-Mail" width="25">
<apex:inputField value="{!contact.email}"/>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
The above allows me to access and edit the Account's related Contact records but I am unable to save any changes I make
I have tried adding:
private final ApexPages.standardController the Controller
and
return theController.save();
to the Apex Class but without much success (as described in on p391 of the force.com Developer Guide that I picked up at Dreamforce '08)
Any help/guidance would be most appreciated.
Thanks in advance
I have tried to follow the advice here without success. The save is still not working. I am using 2 custom objects although I cant see why that should be a problem. Here is my apex
public class EventsList {
public EventsList(ApexPages.StandardController controller) {
}
public PageReference save() {
return null;
}
public Service__c getService() {
return [select id, name,
(select id, name, Actual_Fee__c, Actual_days__c, Employee__c from ServiceEvents__r limit 200)
from Service__c where id =
:ApexPages.currentPage().getParameters().get('Id') ];
}
public String getName() {
return 'Events List';
}
}
Here is my VF
<apex:page standardController="Service_Event__c" extensions="EventsList" tabstyle="Schedules__tab" sidebar="false" showHeader="false">
<apex:pageBlock title="Hello {!$User.FirstName}!">
You are displaying Schedules from the {!Service.name} Service record.
</apex:pageBlock>
<apex:form >
<apex:pageBlock title="Schedules" >
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!save}"/>
</apex:pageBlockButtons>
<apex:dataTable value="{!Service.ServiceEvents__r}" var="a" cellPadding="4" border="1">
<apex:column >
<apex:facet name="header">Service Event</apex:facet>
{!a.Name}
</apex:column>
<apex:column headerValue="Actual Fee">
<apex:inputField value="{!a.Actual_Fee__c}"/>
</apex:column>
<apex:column headerValue="Actual days">
<apex:inputField value="{!a.Actual_days__c}"/>
</apex:column>
<apex:column headerValue="Employee">
<apex:inputField value="{!a.Employee__c}"/>
</apex:column>
</apex:dataTable>
</apex:pageBlock>
</apex:form>
</apex:page>
All Answers
standardcontroller="Contact" extensions="accountContactList"
That way you can use the standard save method. Otherwise, there are ways to call a custom save() method if you want to use a custom controller.
The rule of thumb is this: Custom controllers overwrite every standard function, so if you want to use any, you must recreate them. Extensions add to existing functionalities and can reference the standard functions if you wish to use them.
Here's a sample custom save method:
- custom controllers do not really overwrite anything and are not related to the standard controller in any way at the code level. The standard controller is actually just a custom controller written by my team and made available as one potential building block.
- extensions can also be very useful with custom controllers (e.g. to customize a third party application)
- you can instantiate the standard controller (and standard list controller too) via Apex Code and use it as a building block inside your custom controllers
The design pattern we use for extensions concept is called a Mix In (there are other patterns e.g. Dependency Injection, Chain of Responsibility, etc that come into play also) and the basic idea is that your code gets "mixed into" a dynamically constructed delegating controller that gives your code first crack at handling messages (get property, set property, and invoke action). You can use this powerful concept to add additional data /or behavior, augment existing data/behavior (e.g. do your stuff then chain to the controller's method), completely replace (or shadow) stuff.FYI we require the use of the standard controller in VF pages that are the targets for an Action/Override in order to insure that the basic behavioral contract will be adhered to (commonly referred to as an isA relationship in OO lingo) - essentially the platform needs to be able to count on certain common things to be present when allowing customization.
Message Edited by dchasman on 12-28-2008 06:09 PM
I have tried to follow the advice here without success. The save is still not working. I am using 2 custom objects although I cant see why that should be a problem. Here is my apex
public class EventsList {
public EventsList(ApexPages.StandardController controller) {
}
public PageReference save() {
return null;
}
public Service__c getService() {
return [select id, name,
(select id, name, Actual_Fee__c, Actual_days__c, Employee__c from ServiceEvents__r limit 200)
from Service__c where id =
:ApexPages.currentPage().getParameters().get('Id') ];
}
public String getName() {
return 'Events List';
}
}
Here is my VF
<apex:page standardController="Service_Event__c" extensions="EventsList" tabstyle="Schedules__tab" sidebar="false" showHeader="false">
<apex:pageBlock title="Hello {!$User.FirstName}!">
You are displaying Schedules from the {!Service.name} Service record.
</apex:pageBlock>
<apex:form >
<apex:pageBlock title="Schedules" >
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!save}"/>
</apex:pageBlockButtons>
<apex:dataTable value="{!Service.ServiceEvents__r}" var="a" cellPadding="4" border="1">
<apex:column >
<apex:facet name="header">Service Event</apex:facet>
{!a.Name}
</apex:column>
<apex:column headerValue="Actual Fee">
<apex:inputField value="{!a.Actual_Fee__c}"/>
</apex:column>
<apex:column headerValue="Actual days">
<apex:inputField value="{!a.Actual_days__c}"/>
</apex:column>
<apex:column headerValue="Employee">
<apex:inputField value="{!a.Employee__c}"/>
</apex:column>
</apex:dataTable>
</apex:pageBlock>
</apex:form>
</apex:page>