0

Kann dynamische Validierung auf Elementebene implementiert werden? Ich habe this Beispiel verwendet, um die Validierung eines Elements abhängig vom Wert des anderen Elements zu implementieren. Aber zu diesem Zweck muss ich dies für jedes einzelne Formular implementieren, wo ich dieses Element (Kommentar) mit dieser Validierung verwende. Ich habe viele Formen wie diese. Gibt es eine Möglichkeit, Folgendes zu tun:Kann die dynamische Validierung auf Elementebene implementiert werden?

, um diese Filter-/Validierungslogik mit einem Attribut "data-comment-for" auf Elementebene zu bringen und den Wert des Elements abzurufen, von dem es vom übergeordneten Formular abhängt .

Dies ist meine aktuellen Code (aber ich brauche es jetzt für jede Form zu haben, Es sieht überhaupt nicht elegant.):

class CompetencyAdvanceHumanRightsAndJusticeFormFilter extends InputFilter 
{ 
    public function isValid($context = null) 
    { 
     $figradeCommentName = 'applJusticeFIGrade'.'Comment'; 

     $forGrade = $this->get('applJusticeFIGrade'); 
     $gradeComment = $this->get($figradeCommentName); 

     $applJusticeFIGradeRawValue = $forGrade->getRawValue('applJusticeFIGrade'); 

     if(is_numeric($applJusticeFIGradeRawValue)){ 
      $gradeValue = intval($applJusticeFIGradeRawValue); 
     }else{ 
      $gradeValue = $applJusticeFIGradeRawValue; 
     } 

     if ($gradeValue != 'na' && $gradeValue > 0) { 
      $gradeComment->setRequired(true); 
      $validatorChain = new Validator\ValidatorChain(); 
      $validatorChain->attach(
       new Validator\NotEmpty(), 
       true 
      ); 
      $gradeComment->setValidatorChain($validatorChain); 
     } 

     return parent::isValid($context); 
    } 

    public function __construct(){ 
     $this->add(array(
      'name' => 'id', 
      'required' => true, 
      'filters' => array(
       array('name' => 'Int'), 
      ), 
     )); 

     $this->add(array(
      'name' => 'studEvalId', 
      'required' => true, 
      'filters' => array(
       array('name' => 'Int'), 
      ), 
     )); 
    } 
} 

EDIT:

I-Code für das addierte benutzerdefiniertes Element für die Frage. Es gibt einige "Reste" meiner Versuche, diese Logik auf die Elementebene zu stellen.

Kommentar Element

class Comment extends Element implements InputProviderInterface 
{ 

    /** 
    * @var ValidatorInterface 
    */ 
    protected $validator; 

    // set its type 
    protected $attributes = array(
     'type' => 'comment' 
    ); 


    public function init() 
    { 

     if (null === $this->validator) { 

      $validator = new StringLength(); 
      $validator->setMax(10); 

      $validator->setMessage('The comment should not exceed 1000 letters!', StringLength::INVALID); 

      $this->validator = $validator; 
     } 


    } 


    /** 
    * Get a validator if none has been set. 
    * 
    * @return ValidatorInterface 
    */ 
    public function getValidator() 
    { 
     return $this->validator; 
    } 


    /** 
    * @param ValidatorInterface $validator 
    * @return $this 
    */ 
    public function setValidator(ValidatorInterface $validator) 
    { 
     $this->validator = $validator; 
     return $this; 
    } 


    /** 
    * remove require and validator defaults because we have none 
    * 
    * @return array 
    */ 
    public function getInputSpecification() 
    { 
//  return array(
//   'name' => $this->getName(), 
//   'required' => false, 
//   'validators' => array(
//    $this->getValidator(), 
//   ), 
//   'filters' => array(
//    new FIGradeCommentDynamicBufferFilter() 
//   ), 
//  ); 


     return array(
      'name' => $this->getName(), 
      'required' => false, 
      'filters' => array(
       array('name' => 'Zend\Filter\StringTrim'), 
      ), 
      'validators' => array(
       $this->getValidator(), 
      ), 

     ); 
    } 

    // tell it where to find its view helper, so formRow and the like work correctly 
    public function getViewHelperConfig() 
    { 
     return array('type' => '\OnlineFieldEvaluation\View\Helper\FormComment'); 
    } 

} 

Antwort

1

Sie eine Basis abstrakte Input-Filter Klasse machen könnte und eine Schnittstelle und machen Sie alle Ihre Form Filter die Basisklasse erweitern, die die Schnittstelle mit den Methoden implementiert Sie in Ihrem Formular erwarten Klassen, um die Sache richtig zu machen.

eine Schnittstelle mit den Methoden Fabrikat:

interface GradeCommentFormFilterInterface() 
{ 
    protected function getGradeInput(); 

    protected function getCommentInput(); 
} 

Sie dann den gemeinsamen Code in Ihre Basisklasse bewegen:

abstract class BaseGradeCommentFormFilter extends InputFilter implements GradeCommentFormFilterInterface 
{ 
    protected function getGradeInput() 
    { 
     return $this->get(static::GRADE_NAME); 
    } 

    protected function getCommentInput() 
    { 
     return $this->get(static::GRADE_NAME . 'Comment'); 
    } 

    public function isValid($context = null) 
    { 
     $gradeInput = $this->getGradeInput(); 
     $commentInput = $this->getCommentInput(); 
     $rawValue = $this->getRawValue($gradeInput); 

     if(is_numeric($rawValue)) 
     { 
      $gradeValue = intval($rawValue); 
     } 
     else 
      $gradeValue = $rawValue; 

     if ($gradeValue != 'na' && $gradeValue > 0) { 
      $commentInput->setRequired(true); 
      $validatorChain = new Validator\ValidatorChain(); 
      $validatorChain->attach(
       new Validator\NotEmpty(), 
       true 
      ); 
      $commentInput->setValidatorChain($validatorChain); 
     } 
     return parent::isValid($context); 
    } 
} 

Jetzt können Sie Ihre abstrakten Klasse wie folgt verwenden:

class CompetencyAdvanceHumanRightsAndJusticeFormFilter extends BaseGradeCommentFormFilter 
{ 
    const GRADE_NAME = 'applJusticeFIGrade'; 

    //... other code 
} 

Ich habe schnell versucht, es für Ihren Fall zu arbeiten, aber das ist nicht getestet, und wahrscheinlich gibt es Möglichkeiten, dies zu optimieren, aber es gibt Ihnen eine Vorstellung davon, was Sie tun können.

+0

Schön! Also, aber Sie glauben nicht, dass es eine Möglichkeit gibt, es in die Kommentarelement-Spezifikation zu setzen? – vlr

+0

Ich habe der Frage Code für das benutzerdefinierte Element hinzugefügt. Es gibt einige "Reste" meiner Versuche, diese Logik auf die Elementebene zu stellen. – vlr

Verwandte Themen