You need to sign in to do that
Don't have an account?
Problem with editing table of related records
I have a "Special Event" object, which has a child object, "Attendance" that links it to the Contact object. Each attendance records the invitation and status of a Contact that has been invited to the event. On the Special Event detail page, I have a button leading to a VF page that can be used to modify the status of multiple Attendance objects in the table of existing Attendances for that Event. However, the standard "Save" function gives me an error message:
An internal server error has occurred |
An error has occurred while processing your request. The salesforce.com support team has been notified of the problem. If you believe you have additional information that may be of help in reproducing or correcting the error, please contact Salesforce Support. Please indicate the URL of the page you were requesting, any error id shown on this page as well as any other related information. We apologize for the inconvenience.
|
I'm worried that this is actually an error in my code. Is something written incorrectly? Here is the VF page:
<apex:page standardController="SFDC_Special_Event__c" extensions="DinnerInviteController" >
<apex:form >
<apex:pageBlock >
<apex:pageMessages />
<apex:pageBlockButtons >
<apex:commandButton action="{!save}" value="Save"/>
<apex:commandButton action="{!cancel}" value="Cancel" />
</apex:pageBlockButtons>
<apex:pageBlockTable value="{!existingInvitations}" var="i">
<apex:column value="{!i.ContactName__c}" headerValue="Attendee"/>
<apex:column headerValue="Attendance Status">
<apex:inputField value="{!i.Status__c}" />
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
Here is the relevant controller code:
public with sharing class DinnerInviteController {
private SFDC_Special_Event__c event = new SFDC_Special_Event__c();
private Executive_3D_Group__c currentGrp = new Executive_3D_Group__c();
private List<Contact> toInvite = new List<Contact>();
private List<SFDC_Attendence__c> existingInvitations = new List<SFDC_Attendence__c>();
private List<Contact> existingInvitees = new List<Contact>();
private SFDC_Attendence__c att = new SFDC_Attendence__c();
public DinnerInviteController(ApexPages.StandardController cont){
//Get Special Event record from standard controller
this.event = [Select Id, Executive_3D_Group__c from SFDC_Special_Event__c where
Id=:cont.getId()];
//Get existing Attendance objects
this.existingInvitations = [Select Id, Contact_Attendee__c, Special_Event__c, Status__c, ContactName__c from SFDC_Attendence__c
where Special_Event__c =: this.event.Id ];
//Get existing invitees from existing Attendance list
for(SFDC_Attendence__c a: existingInvitations){
Contact toAdd = [Select Id from Contact where Id=: a.Contact_Attendee__c limit 1];
this.existingInvitees.add(toAdd);
}
//Get group from special event record
this.currentGrp = [Select Id, Group_Number__c from Executive_3D_Group__c where
Id=:this.event.Executive_3D_Group__c limit 1];
}
public List<SFDC_Attendence__c> getExistingInvitations(){
return this.existingInvitations;
}
Is there an error that I am missing?
Thanks a lot
Something that jumps out at me, though I don't believe it is the problem, is that you are using extensions to a standard controller for a single object (SFDC_Special_Event__c), but you are allowing the user to potentially make changes to a number of related objects (SFDC_Attendence__c).
The Save behaviour from the standard controller will be to apply changes only to the contained SFDC_Special_Event__c record, which will result in any changes made to the SFDC_Attendence__c object being discarded.
I'd suggest that you need a Save method in your parent controller that applies updates from the existingInvitations list to the database.
As I say though, I wouldn't expect this to cause an internal error, rather I'd expect the changes not to be persisted to the database.
All Answers
Something that jumps out at me, though I don't believe it is the problem, is that you are using extensions to a standard controller for a single object (SFDC_Special_Event__c), but you are allowing the user to potentially make changes to a number of related objects (SFDC_Attendence__c).
The Save behaviour from the standard controller will be to apply changes only to the contained SFDC_Special_Event__c record, which will result in any changes made to the SFDC_Attendence__c object being discarded.
I'd suggest that you need a Save method in your parent controller that applies updates from the existingInvitations list to the database.
As I say though, I wouldn't expect this to cause an internal error, rather I'd expect the changes not to be persisted to the database.
Ok, I'll try that.
In doing so, how do I pass the picklist values of the Status field back into the controller in order to update each record? I figure once I do that, its pretty simple to do a for each loop to access each Attendance record, modify Status, then Update, but I'm not sure how to pass the VF table of Attendance records back into the controller.
Thanks for the response.
The best way to do this is to hold the list as a property (rather than a variable in the method) and when the get method is called, populate it using the select method if it is null.
Then, as you are backing the table with the list elements that are stored in the controller, the status updates that are made by a user on the page are applied to the list elements without any further involvement from you. Thus in your save method, you can simply execute a Database.update passing the elements in the list as a parameter.
Sorry - getting confused in my various posts!
You already have this information in your controller as a property, and you are using this to back the table on the page. Therefore when your save method is called, the elements in the list will contain the latest status values chosen by the users.
So your save method shoud be as simple as:
public PageReference save()
{
update this.existingInvitations;
return null;
}
Worked perfectly...looks like the error with saving a separate object was what was causing the internal error. But your solution worked.
Thanks!