Showing posts with label Field Error Visualforce Page Validation. Show all posts
Showing posts with label Field Error Visualforce Page Validation. Show all posts

Friday, 22 April 2011

Field Level Error Messages with Visualforce - Part 1

A question came up on the Visualforce discussion board this week asking how to display validation error messages for particular fields on a Visualforce page.

For simple "field required" rules, there's nothing to be done as long as you are using <apex:inputField> components - the field will be decorated with a red bar and an attempt to save a record without the field populated presents a nice error message beneath the field, as shown below:


However, if a validation rule is added - in this case one of email or phone must be defined - you get redirected to a page similar to the following:


Not the greatest user experience in the world.  Clearly handling this via validation rules alone isn't going to work, so the next option that presents itself is to carry out the validation in the controller and send an error message back to the page.  Looking in the Visualforce docs, there is an <apex:pageMessages> component that can do exactly this, we just need to traverse the contacts and add the errors to the page as follows:

Boolean error=false;
Integer idx=1;
for (Contact cand : contacts)
{
 if ( (null==cand.Email || cand.Email.length()==0) &&
      (null==cand.Phone || cand.Phone.length()==0) )
 {
  error=true;
  ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Line ' + idx + ' - one of email or phone must be defined'));
 }
 idx++;
}

The resulting page is shown below:


Looking better, but still not the nicest page in the world.    What we really want is an error tied to the field itself, much like the required fields.  The secret here is to use the addError method available to sObject fields.  In this case, I've traversed the list of contacts and where both the email and phone are blank, added an error to each of the email and phone field detailing the error:

Boolean error=false;
Integer idx=1;
for (Contact cand : contacts)
{
 if ( (null==cand.Email || cand.Email.length()==0) &&
      (null==cand.Phone || cand.Phone.length()==0) )
 {
  error=true;
  cand.email.addError('Either email or phone must be defined');
  cand.phone.addError('Either email or phone must be defined');
 }
 idx++;
}

This results in exactly the behaviour I am looking for, and even better I don't have to make any changes the page, as its standard Visualforce that displays the error:


In part 2, we'll look at how to replicate this when the inputs aren't tied to an sobject field, for example if they come from a wrapper class.