6

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
    Commented Feb 21, 2013 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? Commented Feb 22, 2013 at 16:30

2 Answers 2

4

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
    Commented Feb 23, 2013 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
    Commented Feb 22, 2013 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. Commented Feb 22, 2013 at 16:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .