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>
Matt G.
quelle
@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.

Carrie Kendall
quelle
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.

Bentidy
quelle
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)           

))
Cristian Camilo Diaz Agudelo
quelle
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 ...

Kjir
quelle
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,
    ]);
}
Jonathan
quelle
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
     ]
 );
Maurice
quelle
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';
    }
}
Chris
quelle
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();
Hart gekochtes Wunderland
quelle
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                   
        ))
SudarP
quelle
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()
            )
    );
Onshop
quelle
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()
;
Herzult
quelle
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

repincln
quelle
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