2017-08-16 21 views
5

支払い方法と配送先住所で住所書式を作成しようとしています。配送先住所のチェックボックスがオンになっている場合、その住所にあるフォームの検証がスキップされます。チェックボックスがチェックされている場合、フォームタイプの検証をオフにします。

以下のフォームタイプをトグルオプションで作成しました。このオプションは、チェックボックスを表示して処理しますが、チェックしてもフォームは引き続き有効です。

symfonyはdocumentation on how to implement such a formです。私はほぼ同じコードを持っていますが、チェックしても検証はオフになりません。検証グループを使用していないので、デフォルトグループを無効にしてエンティティの検証を無効にするだけです。 (NotBlankCallbackような特定のフィールドに注釈制約を有する)Addressクラスのフォームを構築

AddressType。私は今、数時間のために、この乗り越えてきたが、私は検証はオフ、およびIされていない理由を推測することはできませんよ

$addressForm = $this 
    ->createFormBuilder([ 
     "paymentAddress" => $paymentAddress, 
     "shippingAddress" => $shippingAddress 
    ]) 
    ->add("paymentAddress", AddressType::class, [ 
     "label" => false 
    ]) 
    ->add("shippingAddress", AddressType::class, [ 
     "label" => false, 
     "toggle" => "Use payment address" 
    ]) 
    ->add("submit", SubmitType::class, [ 
    ]) 
    ->getForm(); 

:私はこのようなタイプを使用

class AddressType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     if ($options["toggle"]) { 
      $builder->add("toggle", CheckboxType::class, [ 
       "mapped" => false, 
       "required" => false, 
       "label" => $options["toggle"] 
      ]); 
     } 

     $builder 
      ->add("name", TextType::class, [ 
       "required" => !$options["toggle"] 
      ]) 
      ->add("address", TextType::class, [ 
       "required" => !$options["toggle"] 
      ]) 
      ->add("zipcode", TextType::class, [ 
       "label" => "Postcode", 
       "required" => !$options["toggle"] 
      ]) 
      ->add("city", TextType::class, [ 
       "required" => !$options["toggle"] 
      ]) 
      ->add("countryCode", ChoiceType::class, [ 
       "choices" => Address::COUNTRY_CODES 
      ]); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      "toggle" => false, 
      "data_class" => Address::class, 
      "validation_groups" => function(FormInterface $form) { 
       if ($form->has("toggle") && $form->get("toggle")->getData() === true) { 
        return []; 
       } 

       return ["Default"]; 
      } 
     ]); 

     $resolver->setAllowedTypes("toggle", ["bool", "string"]); 
    } 
} 

この小さな詳細については、フォームを立ち上げても構いません。

AddressTypeの検証がconfigureOptionsのクロージャによってオフにされないのはなぜですか?これがうまくいかない場合は、妥当な方法でバリデーションを部分的に無効にするより良い解決策はありますか?

EDIT:デフォルトでは、"validation_groups" => falseを設定しても、ビルダーで作成された子でも、フォームの使用でも、引き続き検証が行われます。それは閉鎖とは関係ありません。 symfonyの独自のリソースを含むすべてのオンラインリソースは、[...]それはしかし...

答えて

2

を動作するはずと述べているので、私はちょうどエンティティの検証を無効にするには、既定のグループを無効にします。

&制約は次のようになりAddressその性質を仮定:

/** 
* @Assert\NotBlank() 
*/ 
private $name; 

// etc. 

「バリデータは、」彼はいつも考えているので、これらの特性は、Defaultグループで評価されることを前提とし、空validation_groups(例えばreturn [];['Default']として(チェックされていると、検証はオフになりません)。

https://symfony.com/doc/current/validation/groups.html: グループが指定されていない場合は、グループDefaultに属するすべての制約が適用されます。

一部

きちんとした方法で検証をオフに達成するためのソリューションは、それを達成するための多くの方法があるはずですが、私はあなたにそれらの2を示しています。

  1. なしている場合data_classがルートフォームに設定されている場合は、このレベルのみを確認するためにFormグループを利用できます。

    $addressForm = $this 
        ->createFormBuilder([...], [ 
         'validation_groups' => 'Form', // <--- set 
        ]) 
    
    をして:トグルをオフにして提出するには、

    public function configureOptions(OptionsResolver $resolver) 
    { 
        $resolver->setDefaults([ 
         // ... 
         "validation_groups" => function(FormInterface $form) { 
          if ($form->has("toggle") && $form->get("toggle")->getData() === true) { 
           return ['Form']; // <--- set 
          } 
    
          return ['Address']; // <--- set 
         }, 
         'constraints' => [new Assert\Valid()], // <--- set 
        ]); 
    } 
    

    意味:「トグル」チェックされているが、また、カスケード検証のためのValid()制約を追加する場合

    次に、configureOptions方法では、デフォルトとしてAddressグループとFormグループを設定しますアドレスフィールドにはAddressグループが適用され、それ以外の場合はFormグループのみが適用されます。 Addressクラスで

  2. (別の方法)すべての制約に「必要」グループを追加し、それはDefaultグループと、これらのプロパティ検証回避:

    /** 
    * @Assert\NotBlank(groups={"Required"}) // <--- set 
    */ 
    private $name; 
    
    // etc. 
    

    次に、configureOptions方法では、デフォルトのグループとしてRequiredを設定し、Default場合トグルがチェックされます。この場合

    public function configureOptions(OptionsResolver $resolver) 
    { 
        $resolver->setDefaults([ 
         // ... 
         "validation_groups" => function(FormInterface $form) { 
          if ($form->has("toggle") && $form->get("toggle")->getData() === true) { 
           return ['Default']; // <--- set 
          } 
    
          return ['Required']; // <--- set 
         }, 
         'constraints' => [new Assert\Valid()], // <--- set 
        ]); 
    } 
    

    、トグルをオフにして提出するには:DefaultRequiredグループはアドレスフィールドに適用され、それ以外の場合はDefaultグループのみが必要なフィールドをスキップします。ルートオブジェクトから切断オブジェクトを含む

ネストされたフォームはnew Valid()に制約のオプションを設定することによって検証することができます。

+1

詳細な回答ありがとうございます。私は既にすべての制約にグループを追加しようとしましたが、デフォルトではvalidation_groupsクロージャからそれらのグループを戻していました。私にとって欠けていたのは、Valid制約でした。追加されたフィールドがAddressTypeの子になり、したがって制約が必要であるということは私には起こりませんでした。 – Villermen

関連する問題