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
stollmeyerastollmeyera 

Validation Errors not displaying on Visualforce page

I have a VF page with a custom extension that works great.  However, when a validation error is triggered on Save, the actual error message does not show.  Instead, the user is either taken back to the standard record detail page, or they are taken to an ugly Visualforce Error screen that says something like this:

 

Visualforce Error


System.DmlException: Update failed. First exception on row 0 with id 006W0000002LwCGIA0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, INSERT VALIDATION RULE ERROR MESSAGE HERE.: [] 


Class.CloseOppRedirect2.SavePage: line 65, column 1

 

 

I have included the <apex:messages> component to my VF page, so I am unsure what else I am missing.  Below is my code:

 

 

 VF Page:

 

<apex:page standardController="Opportunity" title="Close Opportunity - {!Opportunity.Account.Name}" apiVersion="23.0" extensions="CloseOppRedirect2">
    
    <apex:sectionHeader title="Close Sale" subtitle="Step 2 of 4"/>
    <apex:form >
        <apex:pageblock mode="Edit" >
        <b><apex:messages style="color:red"/></b>
        </apex:outputPanel>
            <apex:pageblocksection showHeader="true" columns="2" title="Sale Info" >
                <apex:inputField label="Company Name" Value="{!act.Name}" />
                <br/>
                <br/>
                <apex:inputField Value="{!Opportunity.closedate}" />
                <apex:inputField Value="{!Opportunity.Business_Type__c}" style="{!if(opportunity.Business_Type__c = null,"color:red; font-weight:bold", null)}" required="true" />
                <apex:inputField Value="{!Opportunity.Stagename}" />
                <apex:inputField Value="{!Opportunity.Constant_Contact__c}" style="{!if(opportunity.Constant_Contact__c = null,"color:red; font-weight:bold", null)}" required="true" />
                <apex:inputField Value="{!Opportunity.Reason_Won__c}" required="true" />
                <apex:inputField Value="{!Opportunity.Sale_Notes__c}"  style="width:125pt; height:50pt"/>
                <apex:inputField label="Site ID" Value="{!Opportunity.ZZSiteID__c}"/>
                <apex:pageblockSectionItem helpText="If there is no referral or you do not know the name of the business, put 'None'"  >
                    <apex:outputLabel value="MB Client Referred By" />
                    <apex:inputField value="{!act.Referred_By_MB_Client__c}" required="{!if(Opportunity.LeadSource = "Another Client", "true", "false")}" />
                </apex:pageblockSectionItem>
            </apex:pageblocksection>
            
            <apex:pageblocksection showHeader="true" columns="1" title="Outstanding Issues" rendered="{!IF(OR(Opportunity.Account.ValidationPhone__c = "True", Opportunity.Account.ValidationAmpersand__c="True") = true, "True", "False")}">
            <h4>Please make sure to remove any ampersands from the Account fields and remove all letters from Phone fields before closing</h4>
                <apex:inputField Value="{!act.Phone}" rendered="{!Opportunity.Account.ValidationPhone__c}" />
                <apex:inputField Value="{!act.Phone_2__c}" rendered="{!Opportunity.Account.ValidationPhone__c}" />
                <apex:inputField Value="{!act.Email__c}" rendered="{!IF(CONTAINS(act.Email__c, "&") = true, "True", "False")}"/>
                <apex:inputField Value="{!act.Website}" rendered="{!IF(CONTAINS(act.Website, "&") = true, "True", "False")}"/>
                <apex:inputField Value="{!act.BillingStreet}" rendered="{!IF(CONTAINS(act.BillingStreet, "&") = true, "True", "False")}"/>
                <apex:inputField Value="{!act.BillingCity}" rendered="{!IF(CONTAINS(act.BillingStreet, "&") = true, "True", "False")}" />
                <apex:inputField Value="{!act.BillingState}" rendered="{!IF(CONTAINS(act.BillingStreet, "&") = true, "True", "False")}" />
                <apex:inputField Value="{!act.BillingCountry}" rendered="{!IF(CONTAINS(act.BillingStreet, "&") = true, "True", "False")}" />
            </apex:pageblocksection>
            
            <apex:pageblocksection showHeader="true" columns="2" title="Miscellaneous" >
                <apex:inputField label="Are they interested in ID Solutions?" Value="{!Opportunity.ID_Solutions__c}" required="true"/>
                <apex:inputField Value="{!Opportunity.Site_Template__c}" />
                <apex:inputField label="Did they request a conversion?" Value="{!Opportunity.Requested_Conversion__c}" required="true" />
                <apex:inputField Value="{!Opportunity.PAC_Services__c}" />
            </apex:pageblocksection>
            
            <apex:pageblocksection showHeader="true" columns="1"  title="Product Details">
            <a href="https://na4.salesforce.com/{!Opportunity.ID}#{!LEFT(Opportunity.ID, 15)}_RelatedLineItemList_target" target="_blank"><h2>**Click Here to Change**</h2></a>
                <apex:outputfield Value="{!Opportunity.Amount}" />
                <apex:outputField Value="{!Opportunity.Hosting__c}" />
                <apex:outputField Value="{!Opportunity.Hardware__c}" />
                <apex:outputField Value="{!Opportunity.Support__c}" />
                <apex:outputField Value="{!Opportunity.Setup__c}" />
            </apex:pageblocksection>

            <apex:pageblocksection title="Assign Trade Show (if applicable)" rendered="false" />

                <apex:pageblockTable value="{!campaigns}" var="c" rendered="false" >
                    <apex:column title="Copy/Paste into below field" headerValue="Active Trade Shows - Copy/Paste into below field" value="{!c.Name}" />
                </apex:pageblockTable>
            
            <apex:pageblocksection showHeader="true" columns="1">
                <apex:inputfield label="Trade Show" Value="{!Opportunity.CampaignID}" />
            </apex:pageblocksection>

        </apex:pageBlock>
             <center>
             
             <html>
                <head>
                    <script type="text/javascript">
                    function goBack()
                      {
                      window.history.back()
                      }
                    </script>
                </head>
                <body>
                <input type="button" class="btn" value="Back" onclick="goBack()" />
                </body>
            </html>
                <apex:commandButton value="Next Step" action="{!SavePage}" style="width:20%" />
                <apex:commandbutton value="Cancel" action="{!cancel}" />
            </center>
    </apex:form>
</apex:page>

 

 

Below is my Extension:

 

public class CloseOppRedirect2{

    //Get the Account Fields
    public Account act {get; set;}
    
    ApexPages.StandardController controller;
    List<Opportunity> opps = new List<Opportunity>();
    public CloseOppRedirect2(ApexPages.StandardController controller){
        Opportunity o = (Opportunity)controller.getRecord();
        o.StageName = '5 - Closed Won';
        o.CloseDate = Date.today();
        this.controller = controller;
        
        o = [Select ID,
                    AccountID,
                    Account.Name,
                    Account.Phone,
                    Account.Phone_2__c,
                    Account.BillingCity, 
                    Account.BillingStreet, 
                    Account.BillingState, 
                    Account.BillingCountry,
                    Account.Website,
                    Account.Email__c,
                    Account.Referred_By_MB_Client__c
                    from Opportunity where ID=:controller.getRecord().Id limit 1];
        
        act = o.Account;
        
        if(o.ID != null){
            opps.add(o);
        }
        
     }
     
     
    public PageReference SavePage() {
    
        Opportunity o = (Opportunity)controller.getRecord();
        update act;
        if(act.Referred_By_MB_Client__c == 'None' && o.LeadSource == 'Another Client'){
            o.LeadSource = 'Word of Mouth';
            opps.remove(0);
            opps.add(o);
        }
            update opps;
                
        controller.save();
        
        List<Opportunity> opp = [Select AccountID, Reason_Won__c, Hosting__c from Opportunity where ID =:ApexPages.CurrentPage().getParameters().get('id')];
        if(opp.size() > 0 && opp[0].Hosting__c > 0){
            PageReference SavePage= new PageReference('/apex/closeopp3?id='+opp[0].AccountID);
            SavePage.setRedirect(true);
            return SavePage;
        }
        else{
            if(opp.size() > 0 && opp[0].Hosting__c == 0){
                PageReference SavePage= new PageReference('/' +opp[0].ID);
                SavePage.setRedirect(true);
                return SavePage;
            }
            else{
                return null;
            }
        }
        
   }
        
}

 

Any help is greatly appreciated.  

TejTej

include - <apex:pagemessages/> and try again

 

And instead of using required = true in visualforce component, write the validation rule in your controller.

 

                        if( myname == null || myname== '' ){
                                ApexPages.addMessage( new ApexPages.Message( ApexPages.Severity.ERROR, 'Please enter my Name'));
                                return null;            
                        }
stollmeyerastollmeyera

@Tej

 

Thanks for the reply, I was really hoping it was going to be that easy, but unfortunately <apex:pagemessages> didnt work.  Any other ideas on how to get the validation errors to display on the VF page, rather than redirecting to a new page and showing the Visualforce Error?

 

Also, I am curious as to why I would not want to use the 'Required' attribute in my component.  The main reason I do that is to get the red bar next to the field denoting that it is required.

TejTej

<apex:outputLabel value="Last Name" for="fname"/>
<apex:outputPanel layout="block" styleClass="requiredInput">
<apex:outputPanel layout="block" styleClass="requiredBlock"></apex:outputPanel>
<apex:inputText value="{!lastName}" id="lname"/>
</apex:outputPanel>

 

use the above code to put the red block for required fields.

 

required = true dont show the logical error messages, what is actually wrong.

 

put the validation in controller and use page messages it should work.

 

let me know if you still run into any issues.

 


stollmeyerastollmeyera

@Tej, thanks again for the replies.  That is an intersting approach to required fields that I will start to implement.  

 

Unfortunately I am still unablet to get the validation errors to show on the Visualforce page and, instead, am still getting the ugly apex errors on a separate page after Save.  Any other suggestions or ideas?

Starz26Starz26

I ran into this once and IIRC I resolved it by adding ad ID to the apex:messages and rerendering that id

stollmeyerastollmeyera

@ Starz26, would you mind sharing an example of your code?