I'm trying to create a apex:form
with an input section
where several fields are rendered and the user can save the record. Below this form, is an apex:datatable
. I want to rerender the input fields
and the datatable
in after clicking the save Apex:commandbutton
.
Problem
I can only get the input fields to rerender
, the table data will not
rerender.
Bonus points
Why is rerendering a datable so much harder than rerendering other components?
Attempted Solutions
apex:actionsupport
withapex:actionRegion
wrapping the dataTable components.apex:outputpanel
and targeting it for the rerender from the save button.- setting id on the
visualforce component
and attempting to rerender the whole component to simulate a page reload.
Goal
This is a single visualforce page with several visualforce components in a list. Our goal is to rerender the form and datatable without rerendering the page so that we can make a reusuable component.
Component w/ table and form.
<apex:component id='theComponent' controller="HB_BS_EducationCardCont" allowDML="true">
<div class="slds-scope">
<article class="slds-card">
<div class="slds-card__header slds-grid">
<header class="slds-media slds-media_center slds-has-flexi-truncate">
<div class="slds-media__figure"></div>
<div class="slds-media__body">
<h2 class="slds-card__header-title">
<span>Education History</span>
</h2>
</div>
</header>
</div>
<div class="slds-card__body slds-card__body_inner">
<apex:form id="theDataTableForm">
<apex:commandButton id="EduSaveButton" styleClass="slds-button slds-button_brand" action="{!save}" value="Save" rerender="EducationEditFields, eduRecsPanel"
status="pageSavingStatus" />
<apex:outputPanel id="EducationEditFields">
<apex:repeat value="{!fields}" var="f">
<div class="slds-form-element">
<label class="slds-form-element__label" for="text-input-id-53">{!f.label}</label>
<div class="slds-form-element__control slds-input-has-icon slds-input-has-icon_right">
<apex:inputField styleClass="slds-input" value="{!educationForm[f.fieldPath]}" />
</div>
</div>
</apex:repeat>
</apex:outputPanel>
<apex:actionStatus id="pageSavingStatus">
<apex:facet name="start">
<apex:outputPanel>
<img src="/img/loading32.gif" width="25" height="25" />
<apex:outputLabel value="Saving..." />
</apex:outputPanel>
</apex:facet>
</apex:actionStatus>
<apex:outputPanel id="eduRecsPanel">
<apex:dataTable value="{!EduRecords}" var="edu" id="theTable" rowClasses="odd,even" styleClass="slds-table slds-table_cell-buffer slds-table_bordered">
<apex:column>
<apex:facet name="header">School</apex:facet>
<apex:outputText value="{!edu.Other_School__c}" />
</apex:column>
<apex:column>
<apex:facet name="header">Degree</apex:facet>
<apex:outputText value="{!edu.Degree__c}" />
</apex:column>
<apex:commandButton styleClass="slds-button slds-button_brand" action="{!deleteEdu}" value="Delete" reRender="theComponent" status="deletingTableRecord">
<apex:param name="eduRecordId" value="{!edu.Id}" assignTo="{!selectedEduId}"/>
</apex:commandButton>
</apex:column>
</apex:dataTable>
</apex:outputPanel>
<apex:actionStatus id="deletingTableRecord">
<apex:facet name="start">
<apex:outputPanel>
<img src="/img/loading32.gif" width="25" height="25" />
<apex:outputLabel value="Deleting..." />
</apex:outputPanel>
</apex:facet>
</apex:actionStatus>
</apex:form>
</div>
</article>
</div>
Controller
public without sharing class HB_BS_EducationCardCont {
// Declare variables for methods.
public List<Contact_Details__c> eduRecords;
public Contact_Details__c educationForm {get;set;}
public String selectedEduId {get; set;}
private User user;
private Id eduRecordTypeId = Schema.SObjectType.Contact_Details__c.getRecordTypeInfosByDeveloperName().get('Education').getRecordTypeId();
private Id contactId = [SELECT Id, ContactId FROM User WHERE Id =: UserInfo.getUserId()].ContactId;
//Constructor - runs first.
public HB_BS_EducationCardCont() {
// this.eduRecords = getEduRecords();
this.educationForm = getFormEduRecord();
}
public void deleteEdu(){
String siteURL = Site.getBaseUrl();
PageReference pageRef = new PageReference(siteURL + '/apex/HB_BS_EducationPage');
//Check for null to make sure we don't bomb
if (selectedEduId == null) {
// return pageRef;
}
//Get the record from my collection
Contact_Details__c recordToDelete = null;
for (Contact_Details__c myRecToDelete : eduRecords) {
if (myRecToDelete.Id == selectedEduId) {
recordToDelete = myRecToDelete;
break;
}
}
if (recordToDelete != null) {
delete recordToDelete;
// eduRecords = getEduRecords();
}
// return pageRef;
}
public List<Contact_Details__c> getEduRecords(){
if (eduRecords == null) {
eduRecords = [
SELECT
Id,
Other_School__c,
Degree__c,
Degree_Type__c,
Grad_Year__c
FROM Contact_Details__c
WHERE RecordTypeId =: eduRecordTypeId AND Contact__c =: contactId
ORDER BY Grad_Year__c DESC
];
}
System.debug(eduRecords.size());
return eduRecords;
}
// Get Edu Field Set
public List<Schema.FieldSetMember> getFields(){
return SObjectType.Contact_Details__c.FieldSets.HB_BS_EducationCardFields.getFields();
}
public Contact_Details__c getFormEduRecord(){
Contact_Details__c educationForm = new Contact_Details__c(
Contact__c = contactId,
RecordTypeId = eduRecordTypeId
);
return educationForm;
}
public void save(){
try {
insert educationForm;
//Reset form values
this.educationForm = getFormEduRecord();
getEduRecords();
System.debug(eduRecords.size());
} catch (Exception e) {
System.debug(e.getMessage());
}
String siteURL = Site.getBaseUrl();
PageReference pageRef = new PageReference(siteURL + '/apex/HB_BS_EducationPage');
// return pageRef;
}
}