Symfony2 Festlegen einer Standardauswahlfeldauswahl


69

Ich erstelle ein Formular auf folgende Weise:

$form = $this->createFormBuilder($breed)
             ->add('species', 'entity', array(
                  'class' => 'BFPEduBundle:Item',
                  'property' => 'name',
                  'query_builder' => function(ItemRepository $er){
                      return $er->createQueryBuilder('i')
                                ->where("i.type = 'species'")
                                ->orderBy('i.name', 'ASC');
                  }))
             ->add('breed', 'text', array('required'=>true))
             ->add('size', 'textarea', array('required' => false))
             ->getForm()

Wie kann ich einen Standardwert für das Artenlistenfeld festlegen?


Vielen Dank für Ihre Antwort, ich entschuldige mich, ich denke, ich sollte meine Frage umformulieren. Wie setze ich diesen Wert als SELECTED = "yes" für den entsprechenden Wert in der Artenauswahlliste, wenn ich einen Wert habe, den ich aus dem Modell abrufe?

Die in der TWIG-Ansicht ausgegebene Auswahloption sieht also folgendermaßen aus:

<option value="174" selected="yes">Dog</option>

@Mat Ich bin nicht sicher, ob die ausgewählte Antwort (siehe, was ich dort gemacht habe?) Die beste ist.
Crmpicco

Antworten:


60

Wenn Sie die Lösung von Cristian verwenden, müssen Sie die EntityManagerin Ihre FormType-Klasse einfügen. Hier ist ein vereinfachtes Beispiel:

class EntityType extends AbstractType{
    public function __construct($em) {
        $this->em = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options){
         $builder
             ->add('MyEntity', 'entity', array(
                     'class' => 'AcmeDemoBundle:Entity',
                     'property' => 'name',
                     'query_builder' => function(EntityRepository $er) {
                         return $er->createQueryBuilder('e')
                             ->orderBy('e.name', 'ASC');
                     },
                     'data' => $this->em->getReference("AcmeDemoBundle:Entity", 3)
        ));
    }
}

Und dein Controller:

 // ...    

 $form = $this->createForm(new EntityType($this->getDoctrine()->getManager()), $entity);

// ...

Aus Doctrine Docs :

Mit der Methode EntityManager # getReference ($ entityName, $ identifier) ​​können Sie einen Verweis auf eine Entität abrufen, für die der Bezeichner bekannt ist, ohne diese Entität aus der Datenbank zu laden. Dies ist beispielsweise als Leistungsverbesserung nützlich, wenn Sie eine Zuordnung zu einer Entität herstellen möchten, für die Sie die Kennung haben.


5
Perfekte Antwort für Vorauswahlfeld in Symfony2
Ajay Patel

1
Dies wird auch funktionieren, um ein Array zu erstellen, das für 'bevorzugte_Wahlen' für einen Entitätsfeldtyp verwendet werden kann
j_goldman

Was wäre die Alternative in Symfony2.0 für die Optiondata
Smarber

1
Wenn diese Lösung Ihnen hilft, geben Sie Cristians Lösung unbedingt eine positive Bewertung :)
Carrie Kendall

Wie würden Sie dies in Symfony3 tun? Sie können den Entity Manager nicht mehr injizieren, oder?
Roubi

113

Sie können den Standardwert über das Attribut 'data' definieren. Dies ist Teil des abstrakten Feldtyps ( http://symfony.com/doc/2.0/reference/forms/types/field.html ).

$form = $this->createFormBuilder()
            ->add('status', 'choice', array(
                'choices' => array(
                    0 => 'Published',
                    1 => 'Draft'
                ),
                'data' => 1
            ))
            ->getForm();

In diesem Beispiel wird "Entwurf" als standardmäßig ausgewählter Wert festgelegt.


Das hat bei mir funktioniert. Ich habe eine Reihe von Standardeinstellungen im Attribut 'data' angegeben, und das hat auch funktioniert. Vielen Dank!
Nils Luxton

3
Dies scheint bei Optionsfeldern nicht zu funktionieren. Es könnte nur ich sein.
Jason Swett

2
Die Daten müssen sich auf den Schlüssel des Auswahlarrays beziehen. Wenn Sie mehrere Möglichkeiten haben: Array ('foo1' => 'bar1', 'foo2' => 'bar2', ...), müssen Sie 'data' => array ('foo1', 'foo2', angeben. ..). Jason, vielleicht war das dein Problem.
Julien

Ich denke, das sollte die bevorzugte Antwort sein. Es ist sehr einfach zu bedienen.
Alvin Bunk

Dies wird den Wert von Entität überschreiben, wenn Sie eine Entität an Ihr Formular übergeben (zum Beispiel zum Bearbeiten der Seite), kein guter Weg
Vincent Decaux

23

Die Lösung: Verwenden Sie für die Typentität die Option "Daten", aber der Wert ist ein Objekt. dh:

$em = $this->getDoctrine()->getEntityManager();

->add('sucursal', 'entity', array
(

    'class' => 'TestGeneralBundle:Sucursal',
    'property'=>'descripcion',
    'label' => 'Sucursal',
    'required' => false,
    'data'=>$em->getReference("TestGeneralBundle:Sucursal",3)           

))

7

Ich denke, Sie sollten einfach verwenden $breed->setSpecies($species), zum Beispiel in meiner Form, die ich habe:

$m = new Member();
$m->setBirthDate(new \DateTime);
$form = $this->createForm(new MemberType, $m);

und das setzt meine Standardauswahl auf das aktuelle Datum. Sollte für externe Entitäten genauso funktionieren ...


Mein Problem ist genau so mit einem DateType - aber meine Geschichte ist, "" => "Auswählen ..." als die standardmäßig ausgewählte Option hinzuzufügen, um eine vernünftige Auswahl für ein Geburtsdatum zu erzwingen. Ich kann Choose in den Optionen anzeigen lassen, nur nicht standardmäßig. Bei jedem Versuch beschwert sich Symfony, dass ein Argument vom Typ DateTime erwartet wird. Ich bin auf einer älteren Version von Symfony2; Ich denke, sie haben es mit der neuen Platzhalteroption verbessert.
Phpguru

4

Wenn Sie eine Reihe von Doctrine-Entitäten übergeben möchten, versuchen Sie Folgendes (Symfony 3.0+):

protected $entities;
protected $selectedEntities;

public function __construct($entities = null, $selectedEntities = null)
{
    $this->entities = $entities;
    $this->selectedEntities = $selectedEntities;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('entities', 'entity', [
        'class' => 'MyBundle:MyEntity',
        'choices' => $this->entities,
        'property' => 'id',
        'multiple' => true,
        'expanded' => true,
        'data' => $this->selectedEntities,
    ]);
}

1
Gute Lösung, funktioniert hervorragend, wenn Entitäten als Kontrollkästchen gerendert werden und wenn einige aktiviert werden müssen, basierend auf einem bestimmten Eigenschaftswert der Entität.
TheGhost

funktioniert nicht in Symfony 2.8+, wenn Sie den Klassennamen anstelle des Objekts

3

Ich denke nicht, dass Sie die dataOption verwenden sollten, da dies mehr als nur das Festlegen eines Standardwerts bedeutet. Sie überschreiben auch alle Daten, die während der Erstellung an das Formular übergeben werden. Im Grunde brechen Sie die Unterstützung für diese Funktion. - Was möglicherweise nicht wichtig ist, wenn Sie den Benutzer Daten erstellen lassen, aber wichtig ist, wenn Sie (eines Tages) das Formular zum Aktualisieren von Daten verwenden möchten.

Siehe http://symfony.com/doc/current/reference/forms/types/choice.html#data

Ich glaube, es wäre besser, Standarddaten während der Formularerstellung zu übergeben. In der Steuerung.

Sie können beispielsweise eine Klasse übergeben und den Standardwert in Ihrer Klasse selbst definieren. (bei Verwendung der Standardeinstellung Symfony\Bundle\FrameworkBundle\Controller\Controller)

$form = $this->createForm(AnimalType::class, [
    'species' => 174 // this id might be substituted by an entity
]);

Oder wenn Sie Objekte verwenden:

$dog = new Dog();
$dog->setSpecies(174); // this id might be substituted by an entity

$form = $this->createForm(AnimalType::class, $dog);

Noch besser bei der Verwendung einer Fabrik: (wo sich der Hund wahrscheinlich vom Tier erstreckt)

$form = $this->createForm(AnimalType::class, DogFactory::create());

Auf diese Weise können Sie die Formularstruktur und den Inhalt voneinander trennen und Ihr Formular in mehreren Situationen wiederverwendbar machen.


Oder verwenden Sie die preferred_choicesOption, dies hat jedoch den Nebeneffekt, dass die Standardoption an den Anfang Ihres Formulars verschoben wird.

Siehe: http://symfony.com/doc/current/reference/forms/types/choice.html#preferred-choices

$builder->add(
    'species', 
    'entity', 
    [
        'class' => 'BFPEduBundle:Item',
        'property' => 'name',
        'query_builder' => ...,
        'preferred_choices' => [174] // this id might be substituted by an entity
     ]
 );

2

Ich bin mir nicht sicher, was Sie hier falsch machen, wenn ich ein Formular mit Formularklassen erstelle. Symfony kümmert sich um die Auswahl der richtigen Option in der Liste. Hier ist ein Beispiel für eine meiner Formen, die funktioniert.

In der Steuerung für die Bearbeitungsaktion:

$entity = $em->getRepository('FooBarBundle:CampaignEntity')->find($id);

if (!$entity) {
throw $this->createNotFoundException('Unable to find CampaignEntity entity.');
}


$editForm = $this->createForm(new CampaignEntityType(), $entity);
$deleteForm = $this->createDeleteForm($id);

return $this->render('FooBarBundle:CampaignEntity:edit.html.twig', array(
        'entity'      => $entity,
        'edit_form'   => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    ));

Die Klasse des Kampagnenentitätstyps (src: Foo \ BarBundle \ Form \ CampaignEntityType.php):

namespace Foo\BarBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Doctrine\ORM\EntityRepository;

class CampaignEntityType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
        ->add('store', 'entity', array('class'=>'FooBarBundle:Store', 'property'=>'name', 'em'=>'my_non_default_em','required'  => true, 'query_builder' => function(EntityRepository $er) {return $er->createQueryBuilder('s')->orderBy('s.name', 'ASC');}))
        ->add('reward');
    }
    public function getName()
    {
        return 'foo_barbundle_campaignentitytype';
    }
}

Ich denke, ich baue die Formulare möglicherweise falsch. Vielen Dank für Ihr Beispiel. Ich werde es versuchen und Sie wissen lassen, wie es geht!
Matt G

Hallo Chris, ich bin ein wenig verwirrt darüber, wie Sie scheinbar zwei Formulare in einer Ansicht erstellen. Könnten Sie ein Beispiel für die Zweigvorlage veröffentlichen und wie Sie die beiden Formulare in Ihrer Zweigvorlage ansprechen?
Matt G

Entschuldigung für die Verzögerung in der Antwort ... habe Ihren Kommentar nicht gesehen :( Für das Bearbeitungs- / Löschformular hier ist, was ich in meinem Zweig habe<form action="{{ path('myroute_campaign_entity__update', { 'campaignId':campaignId,'id': entity.id }) }}" method="post" {{ form_enctype(edit_form) }}> {{ form_widget(edit_form) }} <p> <button type="submit">Edit</button> </p> </form> <form action="{{ path('myroute_campaign_entity__delete', { 'campaignId':campaignId,'id': entity.id }) }}" method="post"> {{ form_widget(delete_form) }} <button type="submit">Delete</button> </form>
Chris

und hier ist auch die Funktion createDeleteFormprivate function createDeleteForm($id) { return $this->createFormBuilder(array('id' => $id)) ->add('id', 'hidden') ->getForm() ; }
Chris

2

Aus den Dokumenten:

public Form createNamed(string|FormTypeInterface $type, string $name, mixed $data = null, array $options = array())

gemischte $ data = null sind die Standardoptionen. So habe ich zum Beispiel ein Feld namens status und habe es folgendermaßen implementiert:

$default = array('Status' => 'pending');

$filter_form = $this->get('form.factory')->createNamedBuilder('filter', 'form', $default)
        ->add('Status', 'choice', array(
            'choices' => array(
                '' => 'Please Select...',
                'rejected' => 'Rejected',
                'incomplete' => 'Incomplete',
                'pending' => 'Pending',
                'approved' => 'Approved',
                'validated' => 'Validated',
                'processed' => 'Processed'
            )
        ))->getForm();

2

Festlegen der Standardauswahl für das Optionsfeld symfony2

            $builder->add('range_options', 'choice', array(
                'choices' => array('day'=>'Day', 'week'=>'Week', 'month'=>'Month'),
                'data'=>'day', //set default value 
                'required'=>true,
                'empty_data'=>null,
                'multiple'=>false,
                'expanded'=> true                   
        ))

2
Funktioniert nicht, wenn Sie eine vorhandene Entität bearbeiten.
Diese

Verwenden Sie empty_datastatt data, um den Standardwert festzulegen und die Entität dennoch bearbeiten zu können.
Ryguydg

Nein, empty_datazeigt keinen Standardwert im Formular an, der nur beim Senden des Formulars verwendet wird
Vincent Decaux

1

Das Formular sollte den Wert für species-> id automatisch dem ausgewählten Entity-Auswahlfeld zuordnen. Wenn Sie beispielsweise eine Breed-Entität haben, die eine OnetoOne-Beziehung zu einer Species-Entität in einer Join-Tabelle mit dem Namen 'breed_species' hat:

class Breed{

    private $species;

    /**
    * @ORM\OneToOne(targetEntity="BreedSpecies", mappedBy="breed")
    */
    private $breedSpecies;

    public function getSpecies(){
       return $breedSpecies->getSpecies();
    }

    private function getBreedSpecies(){
       return $this->$breedSpecies;
    }
}

Das Feld 'Spezies' in der Formularklasse sollte den Wert species-> id aus dem Attributobjekt 'species' in der an das Formular übergebenen Breed-Klasse abrufen.

Alternativ können Sie den Wert explizit festlegen, indem Sie die Artenentität mit SetData () explizit an das Formular übergeben:

    $breedForm = $this->createForm( new BreedForm(), $breed );
    $species   = $breed->getBreedSpecies()->getSpecies();

    $breedForm->get('species')->setData( $species );

    return $this->render( 'AcmeBundle:Computer:edit.html.twig'
                        , array( 'breed'     => $breed
                               , 'breedForm' => $breedForm->createView()
            )
    );

0

Sie können entweder den richtigen Standardwert für das Modell definieren, das Sie mit diesem Formular bearbeiten möchten, oder Sie können eine Option für leere Daten angeben, damit Ihr Code wie folgt wird:

$form = $this
    ->createFormBuilder($breed)
    ->add(
        'species',
        'entity',
        array(
            'class'         => 'BFPEduBundle:Item',
            'property'      => 'name',
            'empty_data'    => 123,
            'query_builder' => function(ItemRepository $er) {
                return $er
                    ->createQueryBuilder('i')
                    ->where("i.type = 'species'")
                    ->orderBy('i.name', 'ASC')
                ;
            }
        )
    )
    ->add('breed', 'text', array('required'=>true))
    ->add('size', 'textarea', array('required' => false))
    ->getForm()
;

Die Eigenschaft 'empty_data' scheint nichts zu tun
Matt G

-1

Sie können "Preferred_choices" verwenden und den Namen, den Sie auswählen möchten, an den Anfang der Liste "drücken". Dann wird es standardmäßig ausgewählt.

'preferred_choices' => array(1), //1 is item number

Entität Feldtyp


4
Wenn Sie die Eigenschaft "reserved_choices" verwenden, wird der Name zwar an den Anfang der Liste verschoben, aber nicht standardmäßig ausgewählt. Da in der TWIG-Vorlage ein Standardwert wie folgt festgelegt ist: {{form_widget (form.species, {'empty_value': 'Bitte auswählen ...'})}} wird der Wert 'Bitte auswählen ...' von ausgewählt Standard und wenn Sie auf das Listenfeld klicken, ist das Element 'Preferred_choice' die erste Auswahl, die darunter verfügbar ist
Matt G

Ja, das mag schön zu wissen sein, aber es scheint keine Antwort auf die Frage zu sein.
Jason Swett
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.