2012-10-04 4 views
0

J'implémente un type de formulaire personnalisé qui fournit un champ de saisie semi-automatique pour sélectionner un emplacement (pays, ville ou localité). Le type de formulaire crée deux champs, un champ de texte pour l'entrée de recherche de saisie semi-automatique et un champ masqué pour contenir l'identifiant sélectionné de l'emplacement sélectionné. Lors de la saisie dans le champ de texte, un appel du serveur est effectué et les résultats sont affichés via jquery autocomplete. Si un emplacement est sélectionné, l'identifiant de l'emplacement sélectionné est écrit dans le champ masqué tandis que le nom de l'emplacement est affiché dans le champ de texte. Sur le serveur, j'utilise un transformateur client pour rechercher l'entité de l'id transmis par le champ caché. Le champ de texte est ignoré.Double erreur de validation dans le type de formulaire personnalisé

Ma classe de modèle définit un champ d'emplacement avec une propriété pour réécrire l'entité d'emplacement annotée avec une contrainte de validation NotNull.

Tout fonctionne parfaitement bien mais si je ne sélectionne pas un emplacement, le message de validation "Cette valeur ne doit pas être nulle." est affiché deux fois.

Double validation error

Le faisceau est public et peut être trouvé dans mon repo github. Les classes pertinentes sont LocationFieldType et LocationDataTransformer et form theme.

Et maintenant pour la façon dont j'intègre le type de formulaire dans mon projet. J'ai ajouté tout le code, désolé pour la masse;)

Dans le modèle, je définis la propriété comme suit:

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; 
    } 
} 

Et sous la forme principale j'ajouter le champ comme suit:

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'; 
    } 
} 

Et le code du contrôleur:

/** 
* @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(), 
    ); 
} 

Et Finaly le code de modèle pour afficher le formulaire:J'ai la théorie que cela pourrait être parce que j'utilise deux champs de formulaire, mais je ne sais pas comment résoudre ce problème. Toutes les suggestions sur la façon de résoudre cela plus élégant sont les bienvenus.

+0

À quoi ressemble votre modèle de formulaire et que faites-vous pour déclencher la validation? – fd8s0

+0

@ fd8s0 J'ai ajouté du code plus détaillé, mais je pense que cela a quelque chose à voir avec le type de formulaire personnalisé car le problème se présente également dans d'autres formulaires (l'enregistrement de l'utilisateur par exemple). – room13

Répondre

2

Aussi compliquée que cette question puisse paraître, la réponse est aussi simple que de supprimer {{form_errors (form)}} du bloc de template de widget. Parce que le bloc * form_row * ressemble à:

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

L'erreur a été simplement sortie deux fois.

Questions connexes