2012-09-14 39 views
70

我在我的控制器中檢查了一些驗證。而且我想在失敗時將錯誤添加到我的表單的特定元素。我的表單:向Symfony 2表單元素添加錯誤

use Symfony\Component\Form\FormError; 

// ... 

$config = new Config(); 
$form = $this->createFormBuilder($config) 
     ->add('googleMapKey', 'text', array('label' => 'Google Map key')) 
     ->add('locationRadius', 'text', array('label' => 'Location radius (km)')) 
     ->getForm(); 

// ... 

$form->addError(new FormError('error message')); 

addError()方法添加錯誤形成,而不是元素。我如何向locationRadius元素添加錯誤?

回答

145

你可以做

$form->get('locationRadius')->addError(new FormError('error message')); 

表單元素也FormInterface類型。

+1

感謝。它解決了我的問題。 – pltvs

+0

@ m2mdas,很棒的回答!我們將如何翻譯?因爲一旦我們創建了一個FormError實例,它就不會翻譯它,對嗎?我試過了,它沒有翻譯它,我認爲它是有道理的。你將如何翻譯FormError實例? – Mick

+1

你好@Patt,對於遲到的回覆感到抱歉。在將錯誤消息添加到表單之前,Validator組件負責轉換表單約束違規消息。對於添加自定義錯誤,您可以像處理其他字符串一樣翻譯消息,例如'$ this-> get('translator') - > trans('error message')' –

5

好吧,我有另外一種方法。它比較複雜,只適用於特定情況。

我的情況:

我有一個表格,並提交後,我發佈的數據API服務器。還有我從API服務器獲得的錯誤。

API服務器錯誤格式爲:

array(
    'message' => 'Invalid postal code', 
    'propertyPath' => 'businessAdress.postalCode', 
) 

我的目標是獲得靈活的解決方案。讓我們爲相應的字段設置錯誤。

$vm = new ViolationMapper(); 

// Format should be: children[businessAddress].children[postalCode] 
$error['propertyPath'] = 'children['. str_replace('.', '].children[', $error['propertyPath']) .']'; 

// Convert error to violation. 
$constraint = new ConstraintViolation(
    $error['message'], $error['message'], array(), '', $error['propertyPath'], null 
); 

$vm->mapViolation($constraint, $form); 

就是這樣!

注意!addError()方法繞過error_mapping選項。


我的形式(嵌入在公司形式地址形式):

公司

<?php 

namespace Acme\DemoBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\Validator\Constraints; 

class Company extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('companyName', 'text', 
       array(
        'label' => 'Company name', 
        'constraints' => array(
         new Constraints\NotBlank() 
        ), 
       ) 
      ) 
      ->add('businessAddress', new Address(), 
       array(
        'label' => 'Business address', 
       ) 
      ) 
      ->add('update', 'submit', array(
        'label' => 'Update', 
       ) 
      ) 
     ; 
    } 

    public function getName() 
    { 
     return null; 
    } 
} 

地址

<?php 

namespace Acme\DemoBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\Validator\Constraints; 

class Address extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      // ... 
      ->add('postalCode', 'text', 
       array(
        'label' => 'Postal code', 
        'constraints' => array(
         new Constraints\NotBlank() 
        ), 
       ) 
      ) 
      ->add('town', 'text', 
       array(
        'label' => 'Town', 
        'constraints' => array(
         new Constraints\NotBlank() 
        ), 
       ) 
      ) 
      ->add('country', 'choice', 
       array(
        'label' => 'Country', 
        'choices' => $this->getCountries(), 
        'empty_value' => 'Select...', 
        'constraints' => array(
         new Constraints\NotBlank() 
        ), 
       ) 
      ) 
     ; 
    } 

    public function getName() 
    { 
     return null; 
    } 
} 
+0

你在哪裏放置這些代碼?$ vm = new ViolationMapper(); –

+0

@vidyvideni ,控制器將處理表單提交的操作,並且您可以調整這段代碼並將其移至單獨的方法 – Jekis