E
E
e-hot2015-06-16 08:07:54
symfony
e-hot, 2015-06-16 08:07:54

Symfony 2. How to display in form value selected in embedded form list?

Welcome all. Initial situation:
(missing non-essential parts of the code)
Oldemand entity:

namespace Acme\AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
...
class Oldemand
{
...
     /**
     * @var integer
     * 
     * @ORM\Column(name="status_id", type="integer")
     * @ORM\ManyToOne(targetEntity="Status", inversedBy="status_id")
     * @ORM\JoinColumn(name="status_id", referencedColumnName="id")
     */
    private $status_id;
...
}

formEditOldemandType:
namespace Acme\AppBundle\Form;

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

use Acme\AppBundle\Form\formStatusType;

class formEditOldemandType extends AbstractType
{
    public function buildForm( FormBuilderInterface $builder, array $options )
    {
        $builder->add( 'status', new formStatusType() )
        ...
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'Acme\AppBundle\Entity\Oldemand',
        );
    }

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

Form StatusType embedded in formEditOldemandType:
namespace Acme\AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormBuilderInterface;
//use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class formStatusType extends AbstractType
{
    public function buildForm( FormBuilderInterface $builder, array $options )
    {
        $builder->add( 'status', 'entity', array(
                            'class' => 'Acme\AppBundle\Entity\Status',
                            'property' => 'status_name',
                            'label'  => 'Статус: '
                        )
                    );
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'Acme\AppBundle\Entity\Status',
        );
    }

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

Status entity:
namespace Acme\AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

...
class Status {
    
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="bigint", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\Column(name="status_id", type="bigint")
     */
    private $status_id;
    
    /**
     * @var string
     *
     * @ORM\Column(name="status_name", type="string")
     */
    private $status_name;
    ...
}

With such a description of the entities and the method of introducing the form, in my formEditOldemandType form, a
complete list of statuses from the embedded Status entity is displayed, but such an output of all
possible statuses is good when an application (Oldemand => demand - application) is created -
they chose the desired status and saved a new application in the database .
But I have formEditOldemandType - a form for editing an already existing request
with an existing status value, i.e. in the status field,
all statuses from the Status entity and the embedded StatusType form should be listed, where the existing
value from the Oldemand entity should be selected - all.
Or in other words: formEditOldemandType should output the current value highlighted as selected
in the list of all statuses from the embedded StatusType form.
What do I need to do in the above code to get the selected value?
Thank you in advance for your help.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
A
Alexey Pavlov, 2015-06-16
@lexxpavlov

The problem seems to be that when the form is created, a new status object is also created that has no set status:
Try passing the status object to the form:

class formEditOldemandType extends AbstractType
{
    public function buildForm( FormBuilderInterface $builder, array $options )
    {
        $builder->add( 'status', $options['status'] )
        ...
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'Acme\AppBundle\Entity\Oldemand',
            'status' => new formStatusType(),
        );
    }

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

You have an old version of Symfony - the getDefaultOptions() method was removed in version 2.3, and already in version 2.1, the setDefaultOptions() method is used instead, and in version 2.7, configureOptions() is used. You should have stated this fact in the question. What version is used in your project?

M
Mikhail Osher, 2015-06-16
@miraage

Try like this.

$builder->add( 'status', 'entity', array(
    'class' => 'Acme\AppBundle\Entity\Status',
    'property' => 'status_name',
    'label'  => 'Статус: ',
    'data' => 5, // selected value
));

D
Denis, 2015-06-16
@prototype_denis

As always, there are several options.
The first is to pass the id through the options and use the query_builder.

$builder->add( 'status', $options['status_id'] );
//
$builder->add( 'status', 'entity', [
    'query_builder' => ....

Or to hang up on the form of the listener.
// status
$builder->addEventSubscriber(new MyFormListener($arguments));

And directly in the listener to do anything with this form.
// MyFormListener
    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::PRE_SET_DATA => 'onPreSetData',
            FormEvents::PRE_SUBMIT   => 'onPreSubmit',
        );
    }

    public function onPreSetData(FormEvent $event)
    {
        $data  = $event->getData();
        $form = $event->getForm();
    }

Well, the third option. Declare the form a service and push some manager (or listener) into it that operates with data.
UPD: corrected formatting

E
e-hot, 2015-06-22
@e-hot

Thanks to everyone for the answers and advice - so far nothing has helped, so I read once again the documentation on Doctrine 2 - here, I think I have problems understanding the mapping of relationships between entities, and the documentation on forms and embedded forms.
In connection with all this, my situation is as follows:
1. I corrected the display of relationships between entities, i.e. in test mode, I can take parent entities from the controller and, through their field properties, query related (child) entities and, accordingly, any of their field properties - in total: everything is fine here, everything is set up.
2. Now I'm trying to put calls from the class (s) of forms on all mappings of entities and mappings of relationships between entities, or in other words: to tie the work of forms to existing related entities - this is where I have a wedge. I read up and down the docks on forms and embedded forms (subforms as a collection) and I can’t comprehend the mechanism of this -
and the QUESTION itself:
how to indicate relationships between forms, base and embedded in it, on top of mappings of relationships in entities. On other forums they write, use the documentation - everything is there, yes, the documentation has about displaying links - separately, about forms - separately. I can’t understand: in order for the embedded forms to work in the base form, I must enter an additional field-property into the parent entity in order to subsequently link the collection of child entities through it? Or should I just modify an existing field in the parent entity for the binding? Can you help me figure this out? Thank you in advance.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question