2012-10-04 31 views
0

我正在實現自定義表單類型,該類型提供了一個自動填充字段來選擇位置(國家,城市或地點)。表單類型創建兩個字段,一個用於自動填充搜索輸入的文本字段和一個用於保存選定位置的選定ID的隱藏字段。自定義表單類型中的雙重驗證錯誤

在文本字段中輸入時,會進行服務器調用,並通過jquery自動完成顯示結果。如果選擇了某個位置,則將所選位置的ID寫入隱藏字段,而位置的名稱將顯示在文本字段中。在服務器上,我使用客戶端變換器來查找由隱藏字段傳遞的id的實體。文本字段被忽略。

我的模型類定義了一個帶有屬性的位置字段,用於寫回帶有NotNull驗證約束條件的註釋的位置實體。

到目前爲止一切正常,但如果我不選擇一個位置,驗證消息「此值不應該爲空。」顯示兩次。

Double validation error

束是公共的,可以在我的GitHub庫中找到。相關的類別是LocationFieldTypeLocationDataTransformerform theme

現在爲了我如何將表單類型集成到我的項目中。我加了整個代碼,遺憾的質量;)

在這個模型中,我定義屬性如下:

class JourneyCreate 
{ 

    /** 
    * @Assert\NotNull() 
    * @Assert\Choice(choices = {"offer", "request"}) 
    */ 
    public $type; 

    /** 
    * @Assert\NotNull() 
    * @Assert\Date() 
    */ 
    public $date; 

    /** 
    * @Assert\NotNull() 
    * @Assert\Time() 
    */ 
    public $time; 

    /** 
    * @Assert\NotNull() 
    * 
    */ 
    public $start; 

    /** 
    * @Assert\NotNull() 
    * 
    */ 
    public $destination; 


    public function buildJourney(User $owner) 
    { 
    switch($this->type) 
    { 
     case 'offer': 
      $journey = new JourneyOffer(); 
      break; 
     case 'request': 
      $journey = new JourneyRequest(); 
      break; 
     default: 
      throw new \InvalidArgumentException('Invalid journey type'); 
    } 

    $journey->setDate($this->date); 
    $journey->setTime($this->time); 

    $journey->addStation(new JourneyStation($this->start)); 
    $journey->addStation(new JourneyStation($this->destination)); 

    $journey->setOwner($owner); 

    return $journey; 
    } 
} 

,並在主窗體我添加字段如下:

class JourneyCreateType extends BaseType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 

    $builder 
     ->add('type','choice', array(
      'choices' => array(
       'offer' => 'Driver', 
       'request' => 'Passanger', 
      ), 
      'empty_value'=>'', 
      'multiple' => false, 
      'expanded' => true, 
     )) 
     ->add('date','date',array(
      'widget' => 'single_text', 
      'format' => $this->getDateFormat(\IntlDateFormatter::TRADITIONAL), 
     )) 
     ->add('time','time',array(
      'widget' => 'single_text', 
     )) 
     ->add('start','room13_geo_location') 
     ->add('destination','room13_geo_location') 
    ; 

    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
    $resolver->setDefaults(array(
     'data_class' => 'Acme\DemoBundle\Form\Model\JourneyCreate', 
    )); 
    } 


    public function getName() 
    { 
    return 'journey_create'; 
    } 
} 

而控制器代碼:

/** 
* @Route("/create/{type}", defaults={"type" = null}) 
* @Template() 
*/ 
public function createAction($type=null) 
{ 

    if($type !== null && !in_array($type,array('request','offer'))) 
    { 
     throw new NotFoundHttpException(); 
    } 

    $journeyCreate = new JourneyCreate(); 
    $journeyCreate->type = $type; 

    $form = $this->createForm(new JourneyCreateType(),$journeyCreate); 

    if($this->isPost()) 
    { 
     $form->bind($this->getRequest()); 

     if($form->isValid()) 
     { 
      $journeyCreate = $form->getData(); 
      $journey = $journeyCreate->buildJourney($this->getCurrentUser()); 
      $this->persistAndFlush($journey); 
      return $this->redirect($this->generateUrl('acme_demo_journey_edit',array('id'=>$journey->getId()))); 
     } 
    } 

    return array(
     'form' => $form->createView(), 
    ); 
} 

而且finaly模板代碼,以顯示形式:

{% block page_body %} 
    <form class="form-horizontal" action="{{ path('acme_demo_journey_create') }}" method="post" novalidate> 
    {{form_widget(form)}} 
    <div class="form-actions"> 
     <button class="btn btn-primary" type="submit">{{'form.submit'|trans}}</button> 
     <a href="{{path("acme_demo_journey_index")}}" class="btn">{{'form.cancel'|trans}}</a> 
    </div> 
    </form> 
{% endblock %} 

我有這樣的理論,這可能是因爲我使用兩個表單域,但不知道如何解決這個問題。歡迎任何關於如何解決這個更優雅的建議。

+0

你的表單模板是什麼樣的,你在做什麼來觸發驗證? – fd8s0

+0

@ fd8s0我已經添加了一些更詳細的代碼,但我認爲它與自定義表單類型有關,因爲問題在其他表單中也存在(例如用戶註冊)。 – room13

回答

2

儘管這個問題看起來很複雜,但答案與從窗口小部件模板塊移除{{form_errors(form)}}一樣簡單。因爲* form_row *塊看起來像:

{% block form_row %} 
{% spaceless %} 
    <div class="form_row"> 
     {{ form_label(form) }} 
     {{ form_errors(form) }} 
     {{ form_widget(form) }} 
    </div> 
{% endspaceless %} 
{% endblock form_row %} 

錯誤只是輸出兩次。