Form: Avoid setting null to non submitted field

牧云@^-^@ 提交于 2019-12-03 16:06:05

If is only a problem of parameters (GET parameters) you can define the default value into routing file

route_name:
pattern: /users/?form[page]={page}&form[limit]={limit}
defaults: { _controller: CompanyNameBundleName:ControllerName:ActionName, 
                         limit:10 }

An alternative way could be to use a hook (i.e. PRE_BIND) and update manually that value into this event. In that way you haven't the "logic" spreaded into multi pieces of code.

Final code - suggested by Adrien - will be

<?php

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;

class IgnoreNonSubmittedFieldSubscriber implements EventSubscriberInterface
{
    private $factory;

    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        return array(FormEvents::PRE_BIND => 'preBind');
    }

    public function preBind(FormEvent $event)
    {
        $submittedData = $event->getData();
        $form = $event->getForm();

        // We remove every child that has no data to bind, to avoid "overriding" the form default data
        foreach ($form->all() as $name => $child) {
            if (!isset($submittedData[$name])) {
                $form->remove($name);
            }
        }
    }
}

Here's a modification of the original answer. The most important benefit of this solution is that validators can now behave as if the form post would always be complete, which means there's no problems with error bubbling and such.

Note that object field names must be identical to form field names for this code to work.

<?php
namespace Acme\DemoBundle\Form;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;

class FillNonSubmittedFieldsWithDefaultsSubscriber implements EventSubscriberInterface
{
    private $factory;

    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        return array(FormEvents::PRE_BIND => 'preBind');
    }

    public function preBind(FormEvent $event)
    {
        $submittedData = $event->getData();
        $form = $event->getForm();

        // We complete partial submitted data by inserting default values from object
        foreach ($form->all() as $name => $child) {
            if (!isset($submittedData[$name])) {
                $obj = $form->getData();

                $getter = "get".ucfirst($name);
                $submittedData[$name] = $obj->$getter();
            }
        }
        $event->setData($submittedData);

    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!