views:

3281

answers:

8

Say I create a text element like this:

$firstName = new Zend_Form_Element_Text('firstName');
$firstName->setRequired(true);

Whats the best way to change the default error message from:

Value is empty, but a non-empty value is required

to a custom message? I read somewhere that to replace the message, just use addValidator(..., instead (NO setRequired), like this:

$firstName = new Zend_Form_Element_Text('firstName');
$firstName->addValidator('NotEmpty', false, array('messages'=>'Cannot be empty'));

but in my testing, this doesn't work - it doesn't validate at all - it will pass with an empty text field. Using both (addValidator('NotEmp.. + setRequired(true)) at the same time doesn't work either - it double validates, giving two error messages.

Any ideas?

Thanks!

+7  A: 

Give this a shot:

$firstName = new Zend_Form_Element_Text('firstName');
$firstName->setLabel('First Name')
       ->setRequired(true)
       ->addValidator('NotEmpty', true)
       ->addErrorMessage('Value is empty, but a non-empty value is required.');

The key is that "true" on the validator if you set that to true, it'll kill the other validations after it. If you add more than one validation method, but set that to false, it will validate all methods.

Typeoneerror
great! addErrorMessage is what i was looking for. Though i was able to take out the "->addValidator('NotEmpty', true)" line. Thank you
dittonamed
A: 

One small issue. This code:

$zipCode->setLabel('Postal Code')
     ->addValidator('StringLength', true, array( 5, 5 ) )
     ->addErrorMessage('More than 5')
     ->addValidator('Digits', true)
     ->addErrorMessage('Not a digit');

Will generate both error messages if either validation fails. Isn't is supposed to stop after the first fails?

dittonamed
From what I've read, addErrorMessage() adds a general validation error message. It will appear regardless of which validator failed
monzee
yeah that seems to be the case. i was hoping setting the second parameter to true in addValidator would prevent it from showing the next errors, but it didnt
dittonamed
If that's true it could solve a problem I'm having...but can I set it from a form.ini file somehow?
joedevon
You get both message because you are attaching the messages to the queue for the single element, even with the chain break. Try setting the message on the *validator*, not the element. See http://bit.ly/d8vNBJ
David Weinraub
+2  A: 

Try

->addValidator('Digits', false);

or

->addValidator('Digits');

You assume that to check Digits it has to have a string length anyway.

Also, I like to do some custom error messages like this:

$firstName->getValidator('NotEmpty')->setMessage('Please enter your first name');

This allows you to "get" the validator and then "set" properties of it.

Typeoneerror
Your second suggestion works perfect - will change the message nicely and does what its supposed to. Thanks again
dittonamed
One quirk worth mentioning... even though setRequired(true) is supposed to use NotEmpty class behind the scenes, you can't use getValidator('NotEmpty') if setRequired() is used alone without setValidator('NotEmpty... For the love of god, what a strange interface
dittonamed
Moral of the story - Don't change the default error messages if your validating empty sets and others at the same time.
dittonamed
Re: your second comment. That's because the setRequired() adds the NotEmpty validator at the very last minute, i.e. when calling isValid().
monzee
bummer. too bad this wont work: $firstName->setRequired(true, false, array('messages'=>'Must contain only letters'));
dittonamed
A: 

But try this:

$firstName->setRequired(true)
          ->addValidator('NotEmpty', false, array('messages' => 'bar'))
          ->addValidator('Alpha', false, array('messages'=>'Must contain only letters'));

If left empty and submitted, itll give two messages bar & '' is an empty string. Its that second message thats coming from setRequired(true) thats the problem

dittonamed
+2  A: 

An easier way to set this "site-wide" would be to possibly do the following in a bootstrap or maybe a base zend_controller:

<?php    
$translateValidators = array(
            Zend_Validate_NotEmpty::IS_EMPTY => 'Value must be entered',
            Zend_Validate_Regex::NOT_MATCH => 'Invalid value entered',
            Zend_Validate_StringLength::TOO_SHORT => 'Value cannot be less than %min% characters',
            Zend_Validate_StringLength::TOO_LONG => 'Value cannot be longer than %max% characters',
            Zend_Validate_EmailAddress::INVALID => 'Invalid e-mail address'
           );
    $translator = new Zend_Translate('array', $translateValidators);
    Zend_Validate_Abstract::setDefaultTranslator($translator);
?>
Yeah but the link of errors is huge and will probably grow. Hopefully the custom error interface will change. It's too granular which would be ok if the default error messages were usable to present to users who aren't engineers.
joedevon
Disagres with @joedevon, and thanks for posting this John B! You saved me much hassle. I think this is the right approach - the list of error messages is finite and there are only a handful that come up in normal use; all you do is add stuff to this array whenever you see a message that is particularly stupidly written. Why they couldn't have written error messages that sounded sensible in the first place I cannot fathom!
Flubba
@Flubba You feel that way because you haven't experienced what I have. Email errors cascading to host errors due to dependencies etc. etc... And some errors you won't necessarily see in testing... I went through a lot of hassle trying this approach. But give it a shot if you want.
joedevon
@joedevon - re-reading your initial comment, I see we concur on the fatuous default messages! Thanks for the additional detail on your experiences, will take note.
Flubba
+1  A: 

$subjectElement->setRequired(true)->addErrorMessage('Please enter a subject for your message');

This works form me.

A: 

Try this..

$ausPostcode = new Zend_Form_Element_Text('aus_postcode'); $ausPostcode->setLabel('Australian Postcode')
->setRequired(true)
->addValidator('StringLength', false, array(4, 4))
->addValidator(new Zend_Validate_Digits(), false)
->getValidator('digits')->setMessage('Postcode can only contain digits');

This sets the custom error message only for the Digits validator.

Cheers JP.

JP
A: 

if you put:

$element->setRequired(false);

the validations don't work at all, you have to define:

$element->setAllowEmpty(false);

in order to get the correct behavior of the validations.

armandfp