5

I have found a strange behaviour and I can't find why does it happening. I have custom object Test2_c with custom text field Status_c. I want to change it's status asynchronously, so I prepare a VF page:

<apex:page standardController="Test2__c" extensions="test2ExtController">
  <apex:form id="someform">
    <apex:commandButton action="{!statusClose}" value="Close" 
       rendered="{!Test2__c.Status__c == 'Open'}" rerender="someform"/>
    <apex:commandButton action="{!statusOpen}" value="Reopen" 
       rendered="{!Test2__c.Status__c == 'Closed'}" rerender="someform" />

    <apex:detail id="detail"/>

  </apex:form>
</apex:page>

and controller extension:

public class test2ExtController {
  private final Apexpages.Standardcontroller stdController ;

  public void statusClose() {
   SObject obj = stdController.getRecord();
   obj.put('Status__c', 'Closed');
   update obj;
  }
  public void statusOpen() {        
   SObject obj = stdController.getRecord();
   obj.put('Status__c', 'Open');
   update obj;
  }
  public test2ExtController(ApexPages.StandardController controller) {
    stdController = controller;
  }
}

Now strange things are happening:

  1. I click the button -> status is updated, buttons are rerendered, BUT <apex:details> remain the same
  2. I click the second button -> status is updated, buttons are rerendered AND <apex:details> are rerendered but in a WRONG way. It reflect changes made in step 1!!!

From this behaviour i conclude, that <apex:details> IS rerendered but BEFORE the object is updated and buttons are rerendered AFTER object is updated. Why?

Am I making something wrong? How can I get details refreshed after async update call?

2
  • So does it sound like the apex:detail is typical one change off?
    – joshbirk
    Feb 21 '13 at 16:27
  • 1
    you're code looks perfect, the answers may give you some work arounds, but for the sake of future developers, can you log a case with support so they're aware of the issue and reference this stackexchange post? Feb 22 '13 at 16:30
3

This is just a workaround. Like @Ralph commented, your code looks like it should work, so you might want to contact support.

Create an apex:actionFunction that reRenders a section containing the detail and then call that function from the oncomplete of the apex:commandButton.

<apex:page standardController="Test2__c" extensions="test2ExtController">
  <apex:form id="someform">

    <apex:commandButton action="{!statusClose}" value="Close" 
       rendered="{!Test2__c.Status__c == 'Open'}" rerender="someform" 
       oncomplete="getDetailSection();" />

    <apex:commandButton action="{!statusOpen}" value="Reopen" 
       rendered="{!Test2__c.Status__c == 'Closed'}" 
       oncomplete="getDetailSection();"/>

    <apex:outputPanel id="detailContainer">
        <apex:detail id="detail"/>
    </apex:outputPanel>

  </apex:form>

  <apex:actionFunction name="getDetailSection" reRender="detailContainer"/>
</apex:page>
1
  • works fine, will file the bug anyways. the only thing now is that if apex:details has relatedLists="true", it hides quicklinks to them usually displayed over details.
    – dpedro
    Feb 23 '13 at 20:28
2

First it is not a good idea to rerender a form object. For that use apex:outputPanel, it is much comfortable.

Second thing is, use PageReference methods for the action on the command button.

So your code will look like this:

<apex:page standardController="Test2__c" extensions="test2ExtController">
    <apex:form id="someform">

        <apex:outputPanel id="mainBlock">

            <apex:commandButton action="{!statusClose}" 
                  value="Close" 
                  rendered="{!Test2__c.Status__c == 'Open'}" 
                  reRender="mainBlock"/>
            <apex:commandButton action="{!statusOpen}" 
                  value="Reopen" 
                  rendered="{!Test2__c.Status__c == 'Closed'}" 
                  reRender="mainBlock" />

            <apex:detail id="detail"/>

        </apex:outputPanel>

    </apex:form>
</apex:page>

Controller:

public class test2ExtController {
    private final Apexpages.Standardcontroller stdController ;

    public PageReference statusClose() {
        SObject obj = stdController.getRecord();
        obj.put('Status__c', 'Closed');
        try{
            update obj;
        }
        catch(Exception e){

        }

        return null;
    }
    public PageReference statusOpen() {        
        SObject obj = stdController.getRecord();
        obj.put('Status__c', 'Open');
        try{
            update obj;
        }
        catch(Exception e){

        }

        return null;
    }
    public test2ExtController(ApexPages.StandardController controller) {
        stdController = controller;
    }
}
2
  • While general suggestions are useful, these changes aren't getting apex:details to rerender correctly :(
    – dpedro
    Feb 22 '13 at 12:12
  • @mast0r can you elaborate on why it's not good to rerender a form object? Just curious since I do this all the time and haven't heard of any issues, and would love to know if this is something I should be changing. Feb 22 '13 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.