2016-06-29 79 views
0

Symfony2.8項目 窗體驗證不陽明 沒有實體或學說參與Symfony2的集合,子窗體驗證沒有註釋工作

主要形式驗證的註釋確定。收集字段,子窗體無法驗證。無論您輸入什麼內容,主表單字段都有效時,子表單中的每個字段都將被視爲有效。

我已經試過很多的建議在網上,

'error_bubbling', 'cascade_validation' 和@Valid()標籤。什麼都沒有

我添加的var_dump(...),以RangeValidator控件類的代碼庫Symfony2的,它不會創建/調用。爲了證明它沒有被使用,我將子表單字段複製到主表單中,然後調用框架的驗證器來進行範圍檢查,它應該對子表單中的某些字段執行檢查,而不是對其進行範圍檢查。

顯然有更多的代碼,包括客戶端的JavaScript,但這裏是低於基本的代碼片段(從我的代碼散列彌補了這個問題):

Main form: 

class SubsetAdd extends AbstractType 
{ 
    /** 
    * @var string 
    * 
    * @Assert\NotBlank(
    *  message="Subset name should not be blank" 
    *) 
    * @Assert\Regex(
    *  pattern="/^[\w\s\d\:\_\-\+]{1,64}$/", 
    *  message="Subset name should contain ..." 
    *) 
    */ 
    protected $subsetName; 


    /** 
    * @var string 
    * 
    * @Assert\Regex(
    *  pattern="/^[\d]{1,4}[Kk]{1}$/", 
    *  message="Baud rate should be <n>K" 
    *) 
    */ 
    protected $baud; 

    /** 
    * @Assert\Valid() 
    */ 
    protected $entries; 


    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->setMethod('POST'); 

     $builder->add('subsetName', 
      Type\TextType::class, 
      array(
       'attr' => array(
        'title' => 'Subset name string', 
       ), 
       'required' => true, 
       'label' => 'Subset' 
      ) 
     ); 
     $builder->add('baud', Type\ChoiceType::class, array(
      'label' => 'Baud', 
      'attr' => array(
       'title' => 'Baud rate', 
       ), 
      'placeholder' => 'Select Baud', 
      'required' => true, 
      'choices' => array('9600'=>'9600','115200'=>'115200'), 
      )); 

     $builder->add('entries', Type\CollectionType::class, array(
      'label' => 'Entries', 
      'type' => Module\EntryType::class, 
      'allow_add' => true, 
      'allow_delete' => true, 
      'required' => true, 
      'prototype' => true, 
      'prototype_name' => 'entries__name__', 
     )); 

     if ($options['submit']) { 
      // manual debugging aid. normally client side ajax does the submit so no button required 
      $builder->add('submit',Type\SubmitType::class); 
     } 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setRequired(array(
      'submit', 
     )); 

     $resolver->setDefaults(array(
      'submit'=>false, 
      'translation_domain' => 'SerialBundle-forms', 
     )); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => __CLASS__,  // this class is the data object the form represents 
     ); 

     return $options; 
    } 

    public function getName() 
    { 
     $cn=substr(__CLASS__,(strlen(__NAMESPACE__)>0?1+strlen(__NAMESPACE__):0)); // class name - namespace 

     return strtolower(substr($cn,0,1)).substr($cn,1); // lower case first letter 
    } 

    public function getBlockPrefix() { 
     return $this->getName(); 
    } 

    public function setSubsetName($name) 
    { 
     $this->subsetName = $name; 
     return $this; 
    } 

    public function getSubsetName() 
    { 
     return $this->subsetName; 
    } 

    public function setBaud($baud) 
    { 
     $this->baud = $baud; 
     return $this; 
    } 

    public function getBaud() 
    { 
     return $this->baud; 
    } 

    public function setEntries($entries) { 
     $this->entries=$entries; 
    } 
    public function getEntries() { 
     return $this->entries; 
    } 
} 


Subform: 

class EntryType extends AbstractType 
{ 
    /** 
    * @var string 
    * 
    * @Assert\Regex(
    *  pattern="/^[\dA-F]+$/", 
    *  message="Ident should be hex value" 
    *) 
    * @Assert\Valid() 
    */ 
    protected $ident; 

    /** 
    * @var integer 
    * 
    * @Assert\Range(
    *  min = 0, 
    *  max = 64, 
    *  minMessage="Start minimum value?", 
    *  maxMessage="Start maximum value?" 
    *) 
    * @Assert\Valid() 
    */ 
    protected $start; 

    /** 
    * @var integer 
    * 
    * @Assert\Range(
    *  min = 0, 
    *  max = 64, 
    *  minMessage="Length minimum value?", 
    *  maxMessage="Lenght maximum value?" 
    *) 
    * @Assert\Valid() 
    */ 
    protected $length; 


    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->setMethod('POST'); 

     $builder->add('ident', 
      Type\TextType::class, 
      array(
       'attr' => array(
        'title' => 'Ident value', 
       ), 
       'required' => true, 
       'label' => 'Ident' 
      ) 
     ); 

     $builder->add('start', 
      Type\TextType::class, 
      array(
       'attr' => array(
        'title' => 'Start value', 
       ), 
       'required' => true, 
       'label' => 'Start' 
      ) 
     ); 

     $builder->add('length', 
      Type\TextType::class, 
      array(
       'attr' => array(
        'title' => 'Length value', 
       ), 
       'required' => true, 
       'label' => 'Length' 
      ) 
     ); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setRequired(array(
     )); 

     $resolver->setDefaults(array(
      'translation_domain' => 'SerialBundle-forms', 
     )); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => __CLASS__,  // this class is the data object the form represents 
     ); 

     return $options; 
    } 

    public function getName() 
    { 
     $cn=substr(__CLASS__,(strlen(__NAMESPACE__)>0?1+strlen(__NAMESPACE__):0)); // class name - namespace 

     return strtolower(substr($cn,0,1)).substr($cn,1); // lower case first letter 
    } 

    public function getBlockPrefix() { 
     return $this->getName(); 
    } 

    public function setIdent($id) 
    { 
     $this->ident = $id; 

     return $this; 
    } 

    public function getIdent() 
    { 
     return $this->ident; 
    } 

    public function setStart($start) 
    { 
     $this->start = $start; 

     return $this; 
    } 

    public function getStart() 
    { 
     return $this->start; 
    } 

    public function setLength($length) 
    { 
     $this->length = $length; 

     return $this; 
    } 

    public function getLength() 
    { 
     return $this->length; 
    } 
} 


Basic controller: 

class SubsetsController extends Controller 
{ 
    ... 

    /** 
    * @Route("/add", name="subsets-add") 
    * @Method({"GET","POST"}) 
    */ 
    public function addFormAction(Request $request) 
    { 
     $subsetAdd=new ModuleForm\SubsetAdd(); 

     $options=array(
      'submit'=>false, 
     ); 
     $form = $this->createForm(ModuleForm\SubsetAdd::class, $subsetAdd, $options); 

     $form->handleRequest($request); 

     if ($form->isSubmitted()) {   
      var_dump('Submitted'); 
      if ($form->isValid()) { 
       var_dump('Valid'); 

       var_dump("<pre>"); 
       var_dump($subsetAdd->getEntries()); 
       var_dump("</pre>"); 
      } 
     } 

     return $this->render("SerialBundle:Subsets/form.subsets.html.twig', array(
      'anyerrors' => (($form->isSubmitted() && !$form->isValid())?true:false), 
      'form' => $form->createView(), // invoked after handlerequest 
     )); 
    } 
} 

回答

0

有關使用「約束」 =>新的有效的什麼()?

$builder->add('entries', Type\CollectionType::class, array(
     'constraints' => new Valid(), 
     'label' => 'Entries', 
     'type' => Module\EntryType::class, 
     'allow_add' => true, 
     'allow_delete' => true, 
     'required' => true, 
     'prototype' => true, 
     'prototype_name' => 'entries__name__', 
));