+ Start a Discussion
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student 

cancel button immediate="True" Required Fields Help

Hey there,

I have a Cancel button on my visualforce page, it works for every single one of my custom objects except the transactions object. Upon testing it out manually It would not cancel the record creation page and return to my tabbed VF page because of required fields. I searched a bit and learnt about immediate="true" which would trigger the cancel function before the validation rules can take effect. 

Upon inserting the immediate="true" parameter into my visualforce page and testing, I was re-directed to a page that said I had insufficient privledges to access the page.

Below are my extension and VF page with relevent sections highlighted. Any light on the subject would be appreciated.

Extension:

public class extSaveTraButton {

    public Transaction__c tra {get;set;}
   
    public extSaveTraButton(ApexPages.StandardController controller) {
  
        this.tra = (Transaction__c)controller.getRecord();

    }
   
   
    Public PageReference saveDestinyTransaction(){
   


    if(System.currentPageReference().getParameters().get('clone') == '1'){

        //Set record id to null

        tra.Id = null;

    }
   
        insert tra;
        // Send the user to the detail page for the new account.
       PageReference pageRef= new PageReference('/apex/DestinyAccount?id='+tra.account__c+'&Sfdc.override=1');
        pageRef.getParameters().put('tab','Transactions');
        return pageRef;
   
    }
   
    Public PageReference cancelDestinyTransaction(){
    PageReference pageRef = new PageReference('/apex/DestinyAccount?id='+tra.account__c+'&Sfdc.override=1');
    pageRef.getParameters().put('tab','Transactions');
    return pageRef;

   
    }

}

VF page:

<apex:page standardController="Transaction__c" extensions="extSaveTraButton">
    <apex:form >
        <apex:pageBlock >
       
       
            <apex:commandButton value="Save" action="{!saveDestinyTransaction}"/>
            <apex:commandButton value="Cancel" immediate="true" action="{!cancelDestinyTransaction}"/>
           
            <apex:pageBlockSection >
           
           
            <apex:repeat value="{!$ObjectType.Transaction__c.FieldSets.TransactionsFieldSet}" var="f"> 
                <apex:inputfield value="{!Transaction__c[f]}"> 
            </apex:inputfield></apex:repeat>
          
          </apex:pageBlockSection>
           

 
                  
</apex:pageBlock>
    </apex:form>
   
    </apex:page>
Best Answer chosen by Developer.mikie.Apex.Student
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Well...I am not sure how I beat it...But, I just added the tag: &retUrl={!$CurrentPage.Url} to the end of the commandbutton and I no longer got the insufficient privleges. I am so happy!!

All Answers

Phillip SouthernPhillip Southern
setting immediate to true is good to bypass config valdiation and requirements....however I've experienced that is also cuts off view state, so if you made changes to data or input and then click a button...that data does not make it back to the controller and you are not working with data thats been set. 

In that scenario you have two options:

1.) remove immediate tag from the button
2.) place actionsupport onchange inside each input, have it call a void method that is blank in the controller...purpose being to update view state when the onchange event occurs for each input.
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Philip you are an answering machine today. Thank you so much!

I assume that I need to keep the immediate="true" tag as a result of the validation rules preventing redirection to the page before upon clicking cancel.

Which would mean that I would have to go with option 2? How would I go about adding actionsupport? Do i add it to the commandbutton on the VF page or to the class?
Phillip SouthernPhillip Southern
So, do you really need immediate on the button?  What's causing issues that made you go that route?

For the action support approach, do a blank method in your controller something like:
public void refreshvariables()
{
}

Then for each input field something like this:

<apex:inputfield value="{!Transaction__c[f]}">
<apex:actionSupport event="onchange" action="{!refreshvariables}"/>
</apex:inputfield>
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

The problem that made me use the immediate on the button was that upon clicking cancel, when the button was meant to redirect to my tabbed VF page with the transactions tab open (transaction is a child of account and part of my tabbed VF page). It gave me an error and stayed on the page as the required fields stopped the page navigation.

 

I will attempt this action support approach.

Thank you so much for your assistance phillip, you have been a massive help.

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
This was my attempt..but it would not let me save.

public class extSaveTraButton {

    public Transaction__c tra {get;set;}
   
    public extSaveTraButton(ApexPages.StandardController controller) {
  
        this.tra = (Transaction__c)controller.getRecord();

    }
   
   
    Public PageReference saveDestinyTransaction(){
   


    if(System.currentPageReference().getParameters().get('clone') == '1'){

        //Set record id to null

        tra.Id = null;

    }
   
        insert tra;
        // Send the user to the detail page for the new account.
       PageReference pageRef= new PageReference('/apex/DestinyAccount?id='+tra.account__c+'&Sfdc.override=1');
        pageRef.getParameters().put('tab','Transactions');
        return pageRef;
   
    }
   
Public PageReference cancelDestinyTransaction(){
    PageReference pageRef = new PageReference('/apex/DestinyAccount?id='+tra.account__c+'&Sfdc.override=1');
    pageRef.getParameters().put('tab','Transactions');
    return pageRef;
   
    }
   
    public void refreshvariables()
{

<apex:inputfield value="{!Transaction__c[Amount__c]}">
<apex:actionSupport event="onchange" action="{!refreshvariables}"/>
</apex:inputfield>

<apex:inputfield value="{!Transaction__c[Date_of_Payment__c]}">
<apex:actionSupport event="onchange" action="{!refreshvariables}"/>
</apex:inputfield>

}

}
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student


ok,  this is my class:

public class extSaveTraButton {

    public Transaction__c tra {get;set;}
 
    public extSaveTraButton(ApexPages.StandardController controller) {

        this.tra = (Transaction__c)controller.getRecord();

    }
 
 
    Public PageReference saveDestinyTransaction(){
 


    if(System.currentPageReference().getParameters().get('clone') == '1'){

        //Set record id to null

        tra.Id = null;

    }
 
        insert tra;
        // Send the user to the detail page for the new account.
       PageReference pageRef= new PageReference('/apex/DestinyAccount?id='+tra.account__c+'&Sfdc.override=1');
        pageRef.getParameters().put('tab','Transactions');
        return pageRef;
 
    }
 
Public PageReference cancelDestinyTransaction(){
    PageReference pageRef = new PageReference('/apex/DestinyAccount?id='+tra.account__c+'&Sfdc.override=1');
    pageRef.getParameters().put('tab','Transactions');
    return pageRef;
 
    }
 
    public void refreshvariables(){

}
}



This is my page:

<apex:page standardController="Transaction__c" extensions="extSaveTraButton">
    <apex:form >
        <apex:pageBlock >
     
      
      
            <apex:commandButton value="Save" action="{!saveDestinyTransaction}"/>
            <apex:commandButton value="Cancel" immediate="True" action="{!cancelDestinyTransaction}"/>
          
            <apex:pageBlockSection >
          
          
            <apex:repeat value="{!$ObjectType.Transaction__c.FieldSets.TransactionsFieldSet}" var="f">
                <apex:inputfield value="{!Transaction__c[f]}">
              
                <apex:actionSupport event="onchange" action="{!refreshvariables}"/>
              
            </apex:inputfield>
          
          
            </apex:repeat>
         
          </apex:pageBlockSection>
          


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


and still whenever i click cancel with immediate="true" it tells me that I do not have the permission and without immediate="true" the validation rules will not allow navigation away from the record creation page
Phillip SouthernPhillip Southern
Hey so couple of things:

Where you say "tra.Id = null" looks like you are trying to clone and force an insert.  I don't think that will work, you don't have permission to write or set the Id field.  A better approach would be:

Transaction__c traClone = tra.clone();

And then insert traclone and redirect to it.


Also after that, if you run into the error again, open up the dev console or do a debug monitor for the user and see what line you are getting the error from.
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Hey philip,

I wrote the suggested line into the code as such:

public class extSaveTraButton {

    public Transaction__c tra {get;set;}
  
    public extSaveTraButton(ApexPages.StandardController controller) {
 
        this.tra = (Transaction__c)controller.getRecord();

    }
  
  
    Public PageReference saveDestinyTransaction(){
  


    if(System.currentPageReference().getParameters().get('clone') == '1'){

        //Set record id to null

        Transaction__c traClone = tra.clone();

    }
  
        insert tra;
        // Send the user to the detail page for the new account.
       PageReference pageRef= new PageReference('/apex/DestinyAccount?id='+tra.account__c+'&Sfdc.override=1');
        pageRef.getParameters().put('tab','Transactions');
        return pageRef;


But I still got a validation rule prevention when attempting to cancel without the immediate="true' tag and I got insufficient privledges when I had it. 

I know this is a stupid question, but how do I use the developer console to find out where the error is?
Phillip SouthernPhillip Southern
Not a stupid question at all....so when you are logged in, go to the upper right hand corner and click on your name...there should be a dropdown and you can click on the developer console.  Make sure the logs tab is highlighted.  Each time you make a request in your environment a log will be generated....so try and click on the button, and once a log is generated double click on that log.  Scroll to the bottom and it should say where the error took place.  example class line 17 or something like that.

(be careful and make sure you click on the right log, you may need to sort them by date/time...also it should list a status like the error message you get)
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Thats so handy. Well, i tried it and I found no failures. The only difference is when I try to cancel from one of the other objects, in the log you see it redirect to the address+accountnumber, where as in the transactions log it redirects to address+"+++++++++++++++++++++++++"+accountId. Which is the address of that page that I get which says I have insufficient privledges. This is weird isnt it?
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Now this is really weird, when i click new record for transactions and then I go to the URL and delete the long line of +'s, then reload the page. Upon clicking cancel it will do as it is supposed to.


Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Well...I am not sure how I beat it...But, I just added the tag: &retUrl={!$CurrentPage.Url} to the end of the commandbutton and I no longer got the insufficient privleges. I am so happy!!
This was selected as the best answer
Peter SchmitkePeter Schmitke
Stumbled across this page and wanted to provide another input if anyone has the docType="html-5.0" tag for their page - just add html-formnovalidate="formnovalidate" to your command button, turning your button  into:
 
<apex:commandButton value="Cancel" action="{!doCancel}" immediate="true" html-formnovalidate="formnovalidate"/>

Credit to this blog post for helping find the right solution! http://www.tgerm.com/2014/06/cancel-out-of-html5-browser-based-validations-novalidate.html