function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
developerjdk470developerjdk470 

ApexPages.Message not shown if button Rererender action enabled

I made a button to disable scheduled apex jobs, and I want to show a confirmation once completed.  I also want that button to disappear once completed as it serves no purpose if there aren't any active jobs.


I can't make both of these work at the same time though :(  Any tips?

 

VF Page:

 

<apex:page controller="c" >
  <apex:pagemessages />


    <apex:form >
        <apex:pageBlock id="thePageBlock"  >
            <apex:pageBlockButtons >
                <apex:commandButton id="disableButton" value="Disable Integration" rendered="{!schedulersActive}" action="{!deactivateScheduler}">
	                <apex:actionSupport event="oncomplete" action="{!renderButtons}"/>
	                <apex:actionSupport event="oncomplete" rerender="disableButton"/> 
                </apex:commandButton>
            </apex:pageBlockButtons>    
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

Controller methods:

public class c{

    public Boolean schedulersActive { get; set; }

    public c(){
        renderButtons();
    }//method c

	public static void deactivateScheduler(){
		myUtils.deactivateScheduler();
        ApexPages.Message confirmation=new ApexPages.Message(ApexPages.severity.CONFIRM, 'Confirmed: The daily synchronization has been deactivated.');
        ApexPages.addmessage(confirmation);
	}//deactivateScheduler
    
    public void renderButtons(){
        List<CronTrigger> cts=myUtils.getCronTriggers();
        //If there isn't a result here, that means the scheduler hasn't been started
        if (cts.size()==myUtils.numScheduledJobs){
            schedulersActive = TRUE;
        } else {
//            system.debug('ct.CronExpression= '+ct[0].CronExpression);
            schedulersActive = FALSE;
        }//if 1
        system.debug('The number of cron jobs active is: '+cts.size()+' and the value of SchedulersActive is:'+schedulersActive);
    }//renderScheduler
	

}//class c

 

Best Answer chosen by Admin (Salesforce Developers) 
developerjdk470developerjdk470

Finally got it working.  The culprit was having "static" in the "deactivate" method, trying to rerender, and trying to call the method to calculate the value of the Rendered var.  

 

Not 100% sure why, but it seems rerender screws up the order and the page doesn't refresh.  It also seems actionSupport doesn't always fire in the order written, so that's unreliable.  Having "static" in the deactivate method prevented me from calling the renderButtons method AFTER doing its dirty work, so I think the order of operations was messed up there.

 

The final solution:

 

<apex:page controller="myController" action="{!autoRun}">
  <apex:pagemessages id="messages" />
    <apex:form >
        <apex:pageBlock id="thePageBlock"  >
            <apex:pageBlockButtons >
                <apex:commandButton id="authenticateButton" value="Authorize Access" action="{!authenticateOAuth}" />
                <apex:commandButton id="disableButton" value="Disable Integration" action="{!deactivateScheduler}" rendered="{!schedulersActive}" />

            </apex:pageBlockButtons>    
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

public class myController{

    public Boolean schedulersActive { get; set; }

    public myController(){

        renderButtons();
    }//method

    public PageReference authenticateOAuth(){
        return new PageReference(someOtherClass.OAuthURL());
    }//authenticateOAuth
    
    public static void autoRun(){
        //does unrelated stuff including some DML, so can't be in the controller constructor
    }//autoRun
    
  public void deactivateScheduler(){         //Deactivate some scheduled jobs
		someOtherCLass.deactivateScheduler();
//run this again
 renderButtons();
        ApexPages.Message confirmation=new ApexPages.Message(ApexPages.severity.CONFIRM, 'Confirmed: The daily synchronization has been deactivated.');
	    ApexPages.addmessage(confirmation);
	}//deactivateScheduler
    
    public void renderButtons(){
        List<CronTrigger> cts=g2wUtils.getCronTriggers();
        //If there isn't a result here, that means the scheduler hasn't been started
        if (cts.size()==someOtherClass.numScheduledJobs){
            schedulersActive = TRUE;
        } else {
//            system.debug('ct.CronExpression= '+ct[0].CronExpression);
            schedulersActive = FALSE;
        }//if 1
        system.debug('The number of cron jobs active is: '+cts.size()+' and the value of SchedulersActive is:'+schedulersActive);
    }//renderScheduler
	

}//class 

 

All Answers

apapapap

The following line in the code :-

<apex:actionSupport event="oncomplete" rerender="disableButton"/> 

 

 

its not necessary i think because button render functionality is  taken care by   the code  -> rendered="{!schedulersActive}"

aballardaballard

You need to tell it to rerender both the section with the button and the apex:messages.     Put an id on the apex:messages and specify both ids in the rerender attribute on the button. 

developerjdk470developerjdk470

Thanks both for replying.  

 

Unfortunately removing the "rerender="authenticationButton" didn't help, rerender="messages" didn't work, and rerender="thePageBlock" didn't rerender the button.

 

If I take out all the <apex:actionSupport> tags, then the message shows up without any rerender needed, but with any of those, it won't display the message.  I'll keep trying stuff and will post if I figure it out.

 

apapapap

I tried embedding the second action support tag inside the first one and it worked fine. 

 

Page->

<apex:page Controller="SiteController"  >
  <apex:pagemessages />
  <apex:form >
  <apex:pageBlock >
  
<apex:commandButton value="Click this!" action="{!showmsg}" id="button" rendered="{!bool}">
     <apex:actionSupport event="oncomplete" action="{!action1}"> 
     <apex:actionSupport event="oncomplete" rerender="button" />
     </apex:actionSupport>
</apex:commandButton>
</apex:pageBlock>
</apex:form>
</apex:page>

 Controller

public class SiteController {
    
    public boolean bool{get;set;}
    public SiteController()
    {
        bool=true;    
    }
    
    public void showmsg()
    {
    ApexPages.Message confirmation=new ApexPages.Message(ApexPages.severity.CONFIRM, 'Test message');
    ApexPages.addmessage(confirmation);
    }
    
    public void action1()
    {
    ApexPages.Message confirmation=new ApexPages.Message(ApexPages.severity.CONFIRM, 'action1 complete!');
    ApexPages.addmessage(confirmation);
    bool=true;
    }
}

 

aballardaballard

Why do you need two action support tags? I'm surprised that works.  Can't you just put the rerender attribute on the same tag as the action?

developerjdk470developerjdk470

Finally got it working.  The culprit was having "static" in the "deactivate" method, trying to rerender, and trying to call the method to calculate the value of the Rendered var.  

 

Not 100% sure why, but it seems rerender screws up the order and the page doesn't refresh.  It also seems actionSupport doesn't always fire in the order written, so that's unreliable.  Having "static" in the deactivate method prevented me from calling the renderButtons method AFTER doing its dirty work, so I think the order of operations was messed up there.

 

The final solution:

 

<apex:page controller="myController" action="{!autoRun}">
  <apex:pagemessages id="messages" />
    <apex:form >
        <apex:pageBlock id="thePageBlock"  >
            <apex:pageBlockButtons >
                <apex:commandButton id="authenticateButton" value="Authorize Access" action="{!authenticateOAuth}" />
                <apex:commandButton id="disableButton" value="Disable Integration" action="{!deactivateScheduler}" rendered="{!schedulersActive}" />

            </apex:pageBlockButtons>    
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

public class myController{

    public Boolean schedulersActive { get; set; }

    public myController(){

        renderButtons();
    }//method

    public PageReference authenticateOAuth(){
        return new PageReference(someOtherClass.OAuthURL());
    }//authenticateOAuth
    
    public static void autoRun(){
        //does unrelated stuff including some DML, so can't be in the controller constructor
    }//autoRun
    
  public void deactivateScheduler(){         //Deactivate some scheduled jobs
		someOtherCLass.deactivateScheduler();
//run this again
 renderButtons();
        ApexPages.Message confirmation=new ApexPages.Message(ApexPages.severity.CONFIRM, 'Confirmed: The daily synchronization has been deactivated.');
	    ApexPages.addmessage(confirmation);
	}//deactivateScheduler
    
    public void renderButtons(){
        List<CronTrigger> cts=g2wUtils.getCronTriggers();
        //If there isn't a result here, that means the scheduler hasn't been started
        if (cts.size()==someOtherClass.numScheduledJobs){
            schedulersActive = TRUE;
        } else {
//            system.debug('ct.CronExpression= '+ct[0].CronExpression);
            schedulersActive = FALSE;
        }//if 1
        system.debug('The number of cron jobs active is: '+cts.size()+' and the value of SchedulersActive is:'+schedulersActive);
    }//renderScheduler
	

}//class 

 

This was selected as the best answer