2009-09-16 18 views
9

Tengo un Formulario donde el usuario puede marcar una casilla de verificación "crear nueva dirección" y luego puede completar los campos de esta nueva dirección en el mismo formulario.Zend_Form: Elemento solo debe requerirse si se marca una casilla

Ahora quiero validar los campos de esta nueva dirección SÓLO si la casilla de verificación ha sido marcada. De lo contrario, deberían ser ignorados.

¿Cómo puedo hacer eso usando Zend_Form con Zend_Validate?

Gracias!

Respuesta

6

Creo que la mejor y de forma más correcta de hacer esto está creando un validador personalizado.

Puede hacer este validador de dos maneras diferentes, una está utilizando el segundo parámetro pasado al método isValid, $ context, que es el formulario actual que se está validando, o, inserte el elemento de casilla de verificación, que debe verificarse para validación para ocurrir, en el constructor. Yo prefiero la última:

<?php 
class RequiredIfCheckboxIsChecked extends Zend_Validate_Abstract { 

    const REQUIRED = 'required'; 

    protected $element; 

    protected $_messageTemplates = array(
     self::REQUIRED => 'Element required' 
    ); 

    public function __construct(Zend_Form_Element_Checkbox $element) 
    { 
     $this->element = $element; 
    } 

    public function isValid($value) 
    { 
     $this->_setValue($value); 

     if($this->element->isChecked() && $value === '') { 
      $this->_error(self::REQUIRED); 
      return false; 
     } 

     return true; 
    } 

} 

Uso:

class MyForm extends Zend_Form { 

    public function init() 
    { 
     //... 

     $checkElement = new Zend_Form_Element_Checkbox('checkbox'); 
     $checkElement->setRequired(); 

     $dependentElement = new Zend_Form_Element_Text('text'); 
     $dependentElement->setAllowEmpty(false) 
      ->addValidator(new RequiredIfCheckboxIsChecked($checkElement)); 

     //... 
    } 

} 

No he probado el código, pero creo que debería funcionar.

1

Me he estado preguntando cómo hacerlo en ZF también, aunque nunca tuve que implementar dicha función de formulario.

Una idea que me viene a la mente es crear un validador personalizado que acepte el campo de casilla de verificación como parámetro y ejecutarlo en una cadena de validación, como documented. Si la casilla de verificación está marcada, el validador podría devolver la falla. Luego puede verificar si todas las validaciones fallaron y solo luego considerará que el formulario ha fallado la validación.

Ese nivel de personalización de la validación de formulario podría ser inconveniente, por lo que quizás sería mejor usar el método isValidPartial de form.

+0

Véase mi respuesta =) – JCM

2

No ejecuté esto, pero debería funcionar dentro de lo razonable. He hecho algo similar antes de que funcionase, pero no podía recordar dónde estaba el código.

<?php 

class My_Form extends Zend_Form 
{ 
    public function init() 
    { 
    $checkbox = new Zend_Form_Element_Checkbox("checkbox"); 
    $checkbox->setValue("checked"); 

    $textField = new Zend_Form_Element_Text("text"); 

    $this->addElements(array("checkbox", "text")); 

    $checkbox = $this->getElement("checkbox"); 

    if ($checkbox->isChecked()) 
    { 
     //get textfield 
     $textField = $this->getElement("text"); 

     //make fields required and add validations to it. 
     $textField->setRequired(true); 
    } 

    } 

} 
2

Aquí es lo que hago si necesito para validar múltiples elementos uno contra el otro

$f = new Zend_Form(); 

if($_POST && $f->isValid($_POST)) { 
    if($f->checkbox->isChecked() && strlen($f->getValue('element')) === 0) { 
    $f->element->addError('Checkbox checked, but element empty'); 
    $f->markAsError(); 
    } 

    if(!$f->isErrors()) { 
    // process 
    ... 
    ... 
    } 
} 
0

Gracias JCM por su buena solución.

Sin embargo 2 cosas que he notado:

  • El método isValid de su validador tiene que volver cierto en caso de éxito.
  • El validador no se ejecutará durante la validación del formulario sin pasar la opción allowEmpty a falso en el campo de texto.
1

Creé un validador personalizado que hará que su elemento sea necesario en función del valor de otro elemento de formulario zend.

Aquí está el completo code. Espero que esto ayude a alguien.

La idea es crear un validador personalizado y pasar el nombre del elemento condicional y el valor de ese elemento condicional al constructor. El método Zend_Validor isValid ya tiene acceso al valor del elemento al que está adjuntando el validador junto con todos los nombres y valores de los elementos del formulario.

Por lo tanto, dentro del método isValid tiene toda la información que necesita para determinar si su elemento de formulario debe ser un elemento obligatorio.

+0

Bienvenido a desbordamiento de pila. Por favor resuma el enlace en su respuesta; De esa forma, si el enlace se queda obsoleto, la respuesta no será completamente inútil. – michaelb958

0

En Zend 1 extender el método isValid, donde se establece necesitarse en función de los datos publicados por ejemplo:

public function isValid($data) 
    { 
     if (!empty($data['companyCar'])) { 
      $this->getElement('carValue')->setRequired(true); 
     } 

     return parent::isValid($data); 
    } 
Cuestiones relacionadas