I have a Visualforce page that displays a list of Account Location custom objects related to the Account object.
Each Account Location in the table contains a "Del" link. Clicking on this link invokes code in the Controller class that deletes the Account Location object. The link then re-renders the containing pageBlock as well as an outputPanel. The rerender works fine up until I use the "Del" link to delete the last Account Location. When I do that, the last Account Location object is deleted. However, the rerender displays the table with the just deleted Account Location object. When I look at the related list on the Account object, there are no Account Locations present, so I know the Account Location was deleted.
I've included a slimmed-down version of the actual code below.
Does anyone have an idea on how I can resolve this issue?
Visualforce page:
<apex:page controller="AccountLocationSelectionController" title="Update Sites" id="pg">
<script type="text/javascript">
var __sfdcSessionId = '{!GETSESSIONID()}';
</script>
<script src="/soap/ajax/21.0/connection.js" type="text/javascript"></script>
<script src="/soap/ajax/21.0/apex.js" type="text/javascript"></script>
<script type="text/javascript">
function validatestate(){
var sMessage = document.getElementById('pg:idLocationMessage').innerHTML;
if(sMessage!=''){
console.log(sMessage);
}
}
function confirmbeforedelete(){
return confirm("Are you sure ?");
}
function canBeDeletedHandler(recordId,accountId){
if(sforce.apex.execute("AccountLocationSelectionController","canBeDeleted",{rId:recordId,accId:accountId})
== 'true'){
if(confirm("Are you sure ?")){
return true;
}
return false;
}
else{
alert('This site cannot be deleted because it has been selected on other RFPs.');
return false;
}
}
</script>
<apex:pageMessages />
<apex:outputpanel id="idLocationMessage">{!AccountLocationMessage}</apex:outputpanel>
<apex:form id="theForm">
<apex:pageBlock id="TablePanelAvail"
rendered="{!availableLocations.hasLocations}"
title="Available Locations">
<apex:actionStatus id="TableUpdateStatusAvail">
<!-- loading message -->
<apex:facet name="start">
<apex:outputPanel layout="block" styleClass="message infoM4">
<apex:panelGrid columns="2" styleClass="messageTable" columnClasses="messageCell" style="padding:0px;margin:0px;">
<apex:panelGroup >
<img class="loading-icon" src="/s.gif" />
</apex:panelGroup>
<apex:panelGroup >
<div class="messageText">Please wait...</div>
</apex:panelGroup>
</apex:panelGrid>
</apex:outputPanel>
</apex:facet>
<!-- Available Locations table -->
<apex:facet name="stop">
<apex:pageblocktable value="{!availableLocations.AccountLocationList}" var="record"
title="Total available account locations: {!availableLocations.totalAccountLocations}"
rendered="{!availableLocations.totalAccountLocations > 0}">
<!-- Selected -->
<apex:column >
<apex:facet name="header">
<input type="checkbox" id="TablePanelAvailCbx" class="selectall" value="Selected"/> <span style="font-weight:bold;">Action</span>
</apex:facet>
<apex:inputCheckbox value="{!record.selected}"/>
<!--oncomplete="validatestate();" -->
<apex:commandlink value="Del" onclick="if(!canBeDeletedHandler('{!record.loc.id}','{!accountId}')) return false;"
action="{!doDelete}"
oncomplete="validatestate();"
rerender="idLocationMessage,TablePanelAvail"
status="TableUpdateStatusAvail">
<apex:param name="rId" value="{!record.loc.id}" assignTo="{!recordId}"/>
</apex:commandlink>
</apex:column>
<apex:column value="{!record.loc.Name}" headerValue="Name" />
<apex:column value="{!record.loc.Id}" headerValue="Id" />
</apex:pageblocktable>
</apex:facet>
</apex:actionStatus>
</apex:pageBlock>
</apex:form>
</apex:page>
Controller class:
global with sharing class AccountLocationSelectionController {
public ID accountId {get; set;}
public ID recordId {get; set;}
public String AccountLocationMessage{get;set;}
public AccountLocationMgr availableLocations {get; set;}
public AccountLocationSelectionController() {
accountId = ApexPages.currentPage().getParameters().get('accountId');
System.debug('accountId: ' + accountId);
availableLocations = new AccountLocationMgr(accountId);
System.debug('Available Site IDs = ' + availableLocations );
System.debug('---- exiting ctor');
}
public PageReference doDelete() {
System.debug('delete');
Account_Location__c accountLocation = new Account_Location__c();
accountLocation.Id = recordId;
delete accountLocation;
AccountLocationMessage ='Location deleted.';
availableLocations.updateAccountLocationsList();
System.debug('Available Site IDs = ' + availableLocations.accountLocationList );
return null;
}
webService static boolean canBeDeleted(String rId,String accId) {
boolean bRet = true;
// Code removed for simplicity
return bRet;
}
}
Helper classes:
public class AccountLocationMgr {
public Boolean hasLocations {get; private set;}
public List<AccountLocationWrapper> accountLocationList {get; set;}
public ID accountId {get; set;}
public Integer totalAccountLocations {get; set;}
public AccountLocationMgr ( String accountId )
{
this.accountId = accountId;
updateAccountLocationsList();
}
public void updateAccountLocationsList() {
this.accountLocationList = new List<AccountLocationWrapper>();
String query = 'select ' +
'Name, ' +
'AccountId__c ' +
'from Account_Location__c ' +
'where AccountId__c = :accountId';
System.debug('----------- updateAccountLocationsList query:');
System.debug(query);
List<Account_Location__c> temp = Database.query(query);
System.debug('temp.size = ' + temp.size());
if ( (temp != null) && (!temp.isEmpty()) && (temp.size() > 0) ) {
System.debug('Total account locations found for this Account = ' + accountLocationList.size());
System.debug('temp total: ' + temp.size());
this.hasLocations = true;
for(Account_Location__c record : temp)
{
this.accountLocationList.add(new AccountLocationWrapper(record, false));
}
}
else
{
System.debug('No available locations found');
this.hasLocations = false;
}
String totAvailLocnQuery = 'select count() from Account_Location__c ' +
'where AccountId__c = :accountId ';
totalAccountLocations = database.countQuery(totAvailLocnQuery);
}
}
public class AccountLocationWrapper {
public Account_Location__c loc { get; private set; }
public Boolean selected { get; set; }
public AccountLocationWrapper(Account_Location__c loc) {
this.loc = loc;
this.selected = false;
}
public AccountLocationWrapper(Account_Location__c loc, boolean selected) {
this.loc = loc;
this.selected = selected;
}
}