2014-12-23 54 views
5

我使用symfony 2,我有一個窗體,我把@Assert \ NotBlank()註釋。 我自動填充字段,我的表單不通過isValid和isSubmitted測試,並在這些行後我得到一個非null值爲退出(var_dump($ recipeForm-> getErrors()));symfony2:表單錯誤不顯示在樹枝儘管非空getErrorsAsString()

private 'errors' => 
    array (size=4) 
     0 => 
     object(Symfony\Component\Form\FormError)[4119] 
      private 'message' => string 'Cette valeur doit être vide.' (length=29) 
      protected 'messageTemplate' => string 'This value should be blank.' (length=27) 
      protected 'messageParameters' => 
      array (size=1) 
       ... 
      protected 'messagePluralization' => null 
      private 'cause' => 
      object(Symfony\Component\Validator\ConstraintViolation)[4062] 
       ... 
      private 'origin' => null 

在我的樹枝模板中,我使用簡單的表單(表單)渲染表單。 form_errors(form)或form_errors(form.field)不會顯示錯誤。爲什麼?爲什麼我可以進一步瞭解問題來自哪裏?

我有一個非常複雜的類型。對於我網站的其他形式,這些錯誤是正確顯示的。 我喜歡的類型:

<?php 
//src/AppBundle/Form/FoodAnalytics/RecipeType.php 
namespace AppBundle\Form\FoodAnalytics; 

use AppBundle\Form\Core\MediaType; 
use AppBundle\Repository\FoodAnalytics\UnitRepository; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class RecipeType extends AbstractType 
{ 
    protected $recipeIngredientQueryBuilder; 
    protected $recipeSubrecipeQueryBuilder; 
    protected $unitRepository; 
    protected $action; 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'appbundle_foodanalytics_recipe' . $this->action; 
    } 

    public function __construct(UnitRepository $unitRepository, $recipeIngredientQueryBuilder=null, $recipeSubrecipeQueryBuilder=null, $action = null) 
    { 
     $this->recipeIngredientQueryBuilder = $recipeIngredientQueryBuilder; 
     $this->recipeSubrecipeQueryBuilder = $recipeSubrecipeQueryBuilder; 
     $this->unitRepository = $unitRepository; 
     $this->action = $action == null ? null : '_' . $action; 
    } 

    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('recipeCategories', 'genemu_jqueryselect2_entity',array(
        'multiple' => true, 
        'class' => 'AppBundle:FoodAnalytics\RecipeCategory', 
        'label' => 'Catégories', 
        'required' => false, 
        'by_reference' => false, 
        'attr'=>array(
         'data-toggle'=>"tooltip", 
         'data-placement'=>"top", 
         'title'=>"Indiquez les catégories dans lesquelles enregistrer la recette pour un recherche future plus facile", 
        ))) 
      ->add('isProduct', null, array(
        'label'=>'Correspond à un produit fini', 
        'required'=>false, 
        'attr'=>array(
         'data-toggle'=>"tooltip", 
         'data-placement'=>"top", 
         'title'=>"La recette correspond-elle à un produit fini qui peut être mis en vente ?", 
        ))) 
      ->add('name', null, array(
        'label'=>'Nom détaillé', 
        'attr'=>array(
         'data-toggle'=>"tooltip", 
         'data-placement'=>"top", 
         'title'=>"Indiquez le nom détaillé de la recette. Par exemple : 'millefeuilles praliné ganache vanille sur feuilletage inversé'", 
        ))) 
      ->add('nickName', null, array(
        'label'=>'Nom raccourci', 
        'attr'=>array(
         'data-toggle'=>"tooltip", 
         'data-placement'=>"top", 
         'title'=>"Indiquez un nom raccourci pour la recette. Par exemple : 'millefeuilles'", 
        ))) 
      ->add('recipeIngredients', 'collection', array(
        'type' => new RecipeIngredientType($this->unitRepository, $this->recipeIngredientQueryBuilder), 
        'by_reference' => false, 
        'label'=>'Ingrédient', 
        'allow_add' => true, 
        'allow_delete' => true, 
        'cascade_validation' => true, 
       )) 
      ->add('subrecipes', 'collection', array(
        'type' => new RecipeSubrecipeType($this->unitRepository, $this->recipeSubrecipeQueryBuilder), 
        'by_reference' => false, 
        'label'=>'Sous-recette', 
        'allow_add' => true, 
        'allow_delete' => true 
       )) 
      ->add('recipeSteps', 'collection', array(
        'type' => new RecipeStepType(), 
        'by_reference' => false, 
        'label'=>'Etape de production', 
        'allow_add' => true, 
        'allow_delete' => true 
       )) 
      ->add('portions', null, array(
        'label'=>'Nombre de parts/de pièces', 
        'required' => false, 
        'attr'=>array(
         'data-toggle'=>"tooltip", 
         'data-placement'=>"top", 
         'title'=>"Indiquez le nombre d'éléments disponibles dans la recette. Cela peut permettre d'utiliser l'unité 'U' dans les recettes parentes qui l'utiliseront", 
        ))) 
      ->add('shortDescription', null, array(
        'label'=>'Description courte', 
        'required'=>false, 
        'attr'=>array(
         'data-toggle'=>"tooltip", 
         'data-placement'=>"top", 
         'title'=>"Décrivez succinctement la recette", 
        ))) 
      ->add('medias', 'collection', array(
        'type' => new MediaType(), 
        'by_reference' => false, 
        'label'=>'Medias', 
        'allow_add' => true, 
        'allow_delete' => true, 
        'required' => false, 
        'attr'=>array(
         'data-toggle'=>"tooltip", 
         'data-placement'=>"top", 
         'title'=>"Ajoutez des images ou vidéos pour décrire la recette", 
        ))) 
      ->add('content', 'textarea', array(
        'label'=>'Instructions générales', 
        'required'=>false, 
        'attr' => array(
         'data-toggle'=>"tooltip", 
         'data-placement'=>"top", 
         'class' => 'summernote', 
         'title'=>"Ajoutez du contenu supplémentaire pour détailler la recette", 
        ))) 
      ->add('workingDuration', 'timepicker', array(
         'label'=>'Temps total de travail', 
         'required' => false, 
         'attr'=>array 
         (
          'class' => 'timepicker', 
          'data-toggle'=>"tooltip", 
          'data-placement'=>"top", 
          'title'=>"Indiquez le temps total de travail consacré à la recette si il diffère du temps de travail cumulé des étapes de production", 
         ))) 
      ->add('sleepDuration', 'timepicker', array(
        'label'=>'Temps total de repos', 
        'required' => false, 
        'attr'=>array 
        (
         'data-toggle'=>"tooltip", 
         'class'=>'timepicker', 
         'data-placement'=>"top", 
         'title'=>"Indiquez le temps total de repos consacré à la recette si il diffère du temps de repos cumulé des étapes de production", 
        ))) 
     ; 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\FoodAnalytics\Recipe', 
//   'cascade_validation' => true, 
     )); 
    } 
} 

編輯:保持這種形式只有一個簡單的現場並不能改變什麼,錯誤將不會顯示

回答

0

看來,錯誤是由上的屬性驗證規則引起的這是您的Recipe實體的一部分,但未添加到RecipeType,因此錯誤無法鏈接到任何子表單。

測試一下實體,並找到該酒店的驗證規則,而不是添加到RecipeType要麼添加一個默認值屬性或使用Validation Groups

+0

好吧,錯誤實際上是由添加到配方類型的字段引起的,並且我知道哪一個是我自願將其錯誤地放入。 form-> geterrorsasstring顯示正確的錯誤,但不顯示樹枝模板,這是奇怪的部分。 –

6

看看錯誤的方式在這裏呈現:http://symfony.com/doc/current/cookbook/form/form_customization.html#customizing-error-output

使用{{ form_errors(form) }}的問題是它顯示全局表單錯誤,而不是單個字段,而getErrorsAsString()將在所有字段中向下鑽取。如果您想要通過{{ form_errors(form) }}訪問所有單個字段錯誤,則需要編輯表單中的每個字段並添加選項error_bubbling => true

如果您沒有在所有字段上將錯誤冒泡設置爲true,那麼您將需要單獨呈現每個字段的錯誤信息 - 例如:{{ form_errors(form.name) }}或僅使用{{ form_row(form.name) }},它會呈現標籤,表單元素和錯誤都在一個鏡頭中。

+1

不幸的是,error_bubbling => true不起作用。如果我使用form(form)或form_errors(form.field)或form_row(form.field)渲染表單,則沒有任何變化。對於這些值,我也有一個空的轉儲,而getErrorsAsString不是空的。我的網站上的其他一些表單工作正常......你知道如何跟蹤他們被捕獲的地方到他們展示的地方的錯誤嗎?我想我需要額外的調試技巧... –

+0

您是否確保在每個單獨的字段上放置'error_bubbling => true'?當我第一次開始使用Symfony表單時,我認爲我可以爲整個表單設置該選項,但事實並非如此。它必須是每場。也許你可以發佈你添加錯誤冒泡的配置,以及用於顯示錶單的Twig代碼? –

+0

好吧,如果我在nickname上放了error_bubbling,並且還放了一個Assert \ NotBlank(),我只會得到相同的結果:沒有錯誤顯示,但是我可以在getErrorsAsString中看到錯誤。我會放一個更簡單的表單錯誤示例來嘗試縮小它的範圍 –

3

我的天啊!

對不起,我讓人失去了這個時間!問題是我作爲響應傳遞了一個數組$response = array(form->createView()),但是在處理請求之前生成了這個數組響應。因此,爲什麼我可以在vardump中看到它,而不是在樹枝上。

+1

它幾乎總是很簡單。很高興你明白了。 –