H
H
HunteX2014-01-18 12:32:24
symfony
HunteX, 2014-01-18 12:32:24

How to implement mass submission/editing of entities on one form?

Good day.
Started learning symfony2 framework and ran into a problem.
In general, there is such an entity (something like an extended reference):

/**
 * Ns\TestBundle\Entity\Config
 *
 * @ORM\Table(name="configs")
 * @ORM\Entity()
 */
class Config
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=200)
     */
    private $value;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $description;
}

It is necessary to get all these objects of the Config type from the database and present them on the page in one form for their mass editing.
How to implement it? What should be the Controller Actions/FormType/Twig Template?
If you have any other option to solve my problem, I will be glad to know it.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
silentvick, 2014-01-18
@HunteX

Create a wrapper form and embed as many entity forms as you want
1. Создаем класс, который будет просто держать коллекцию нужных нам сущностей. Для примера, назову его ConfigHolder.

namespace Ns\TestBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;

class ConfigHolder
{
    protected $_configs;

    public function getConfigs()
    {
        if ( is_null($this->_configs) ) {
            $this->_configs = new ArrayCollection();
        }

        return $this->_configs;
    }

    public function setConfigs(ArrayCollection $configs)
    {
        $this->_configs = $configs;
    }
}

2. Создадим форму для этого класса. Можно, конечно, было обойтись без отдельного класса, но мне кажется, так код будет немного чище. В конструкторе формы добавляем поле типа collection, и указываем тип встраиваемых полей - ConfigType (класс формы для Config; его создание тривиально, поэтому я буду исходить из того, что он уже написан)
namespace Ns\TestBundle\Form\Type;

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

class ConfigHolderType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('configs', 'collection', array('type' => new ConfigType()));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Ns\TestBundle\Entity\ConfigHolder',
        ));
    }

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

3. Осталось дело за малым. Всего сотня-другая строчек кода... :) Теперь, когда есть все необходимое можно создать форму в контроллере и работать с ней, как и со всеми остальными формами. Например:
namespace Acme\TaskBundle\Controller;

use Ns\TestBundle\Entity\ConfigHolder;
use Ns\TestBundle\Entity\Config;
use Ns\TestBundle\Form\Type\ConfigHolderType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\Common\Collections\ArrayCollection;

class ConfigHolderController extends Controller
{
    public function editAction(Request $request)
    {
        // Подгружаем нужные конфиги из базы, получая массив объектов
        // $configs = ...

        $configHolder = new ConfigHolder();
        $configHolder->setConfigs(new ArrayCollection($configs));

        $form = $this->createForm(new ConfigHolderType(), $configHolder);
        $form->handleRequest($request);

        if ( $form->isValid() )
        {
            // получили данные и делаем с ними все, что захотим,
            // можно, например, в базу данных сохранить...
        }

        return $this->render('NsTestBundle:ConfigHolder:edit.html.twig', array(
            'form' => $form->createView(),
        ));
    }
}

4. Остался вывод формы. Здесь нужно лишь пройтись в цикле по вложенным формам.
{# src/Ns/TestBundle/Resources/views/ConfigHolder/edit.html.twig #}

{{ form_start(form) }}
    {% for config in form.configs %}
        <div>
            {{ form_row(config.name) }}
        </div>
        <div>
            {{ form_row(config.value) }}
        </div>
        <div>
            {{ form_row(config.description) }}
        </div>
    {% endfor %}
{{ form_end(form) }}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question