2010-03-06 20 views
13

Ho due campi nel mio modulo Zend e voglio applicare la regola di convalida che garantisce che l'utente inserisca uno di questi due campi.Convalida modulo Zend: elemento A o elemento B

$companyname = new Zend_Form_Element_Text('companyname'); 
    $companyname->setLabel('Company Name'); 
    $companyname->setDecorators($decors); 
    $this->addElement($companyname); 

    $companyother = new Zend_Form_Element_Text('companyother'); 
    $companyother->setLabel('Company Other'); 
    $companyother->setDecorators($decors); 
    $this->addElement($companyother); 

Come posso aggiungere un validatore che esaminerà entrambi i campi?

risposta

12

Vedere "Nota: contesto di convalida" al numero page. Zend_Form passa il contesto ad ogni Zend_Form_Element :: isValid call come secondo parametro. Quindi scrivi semplicemente il tuo validatore che analizza il contesto.

EDIT:
Va bene, ho pensato Se mai prendere un colpo a questo me stesso. Non è testato, né è un mezzo per tutti i fini, ma ti darà un'idea di base.

class My_Validator_OneFieldShouldBePresent extend Zend_Validator_Abstract 
{ 
    const NOT_PRESENT = 'notPresent'; 

    protected $_messageTemplates = array(
     self::NOT_PRESENT => 'Field %field% is not present' 
    ); 

    protected $_messageVariables = array(
     'field' => '_field' 
    ); 

    protected $_field; 

    protected $_listOfFields; 

    public function __construct(array $listOfFields) 
    { 
     $this->_listOfFields = $listOfFields; 
    } 

    public function isValid($value, $context = null) 
    { 
     if(!is_array($context)) 
     { 
      $this->_error(self::NOT_PRESENT); 

      return false; 
     } 

     foreach($this->_listOfFields as $field) 
     { 
      if(isset($context[ $field ])) 
      { 
       return true; 
      } 
     } 

     $this->_field = $field; 
     $this->_error(self::NOT_PRESENT); 

     return false; 
    } 
} 

Usage:

$oneOfTheseFieldsShouldBePresent = array('companyname', 'companyother'); 

$companyname = new Zend_Form_Element_Text('companyname'); 
$companyname->setLabel('Company Name'); 
$companyname->setDecorators($decors); 
$companyname->addValidator(new My_Validator_OneFieldShouldBePresent($oneOfTheseFieldsShouldBePresent)); 
$this->addElement($companyname); 

$companyother = new Zend_Form_Element_Text('companyother'); 
$companyother->setLabel('Company Other'); 
$companyother->setDecorators($decors); 
$companyname->addValidator(new My_Validator_OneFieldShouldBePresent($oneOfTheseFieldsShouldBePresent)); 
$this->addElement($companyother); 
0

Non ho trovato una soluzione simile, ma è perfettamente valida quindi +1.

Vorrei estendere Your_Form::isValid() per includere un controllo manuale per i valori di questi due elementi.

Se tutti i campi passano i propri singoli validatori, questa convalida probabilmente appartiene al modulo come un intero e tale potrebbe essere inserito nella convalida del modulo anziché nei campi. Sei d'accordo con questa linea di pensiero?

0

Sono d'accordo con @chelmertz che una funzione come questa non esiste.

Quello che non sono d'accordo si estende Your_Form::isValid(). Invece, vorrei write a custom Validator che accetta i valori di entrambi gli elementi del modulo che devono avere un valore. In questo modo potrei riutilizzarlo su elementi di forma arbitrari. Questo è in qualche modo simile al Identical Validator.

1

La soluzione fornita da @fireeyedboy è a portata di mano, ma non funziona per questo problema esatto.

Zend_Validate_Abstract utilizza il contesto, che non può essere passato come variabile a isValid(). In questo modo quando si utilizza il metodo (indipendentemente dall'originale o sovrascritto) i campi vuoti non vengono passati e convalidati (a meno che non si abbia setRequired(true) o setAllowEmpty(false), che non vogliamo). Pertanto, nel caso in cui lasci entrambi i due campi (companyname e companyother) vuoto, non verrà eseguita alcuna azione. L'unica soluzione di cui sono a conoscenza è l'estensione della classe Zend_Validate per consentire la convalida dei campi vuoti.

Per favore fatemi sapere se conoscete una soluzione migliore in quanto sono alle prese con problemi simili.

Problemi correlati