In web application most of us have seen "Confirm Form Resubmission” dialog in pages where there is a form. I believe it annoys most of us like myself. In symfony applications you can use example below to prevent it from happening.

If the form fails, form data is stored in a session and used in form when creating it again. As simple as this. I'll keep it short but I believe you'll see how the session is used here.


Form


namespace My\TestBundle\Type;

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

class InterestType extends AbstractType
{
const NAME = 'interest';

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', 'text', ['required' => true]);
$builder->add('surname', 'text', ['required' => true]);
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['data_class' => 'My\TestBundle\Interest']);
}

public function getName()
{
return self::NAME;
}
}

Model


namespace My\TestBundle\Model;

use Symfony\Component\Validator\Constraints as Assert;
use JMS\Serializer\Annotation as Serializer;

class Interest
{
/**
* @var string
*
* @Assert\NotBlank(message = "Please enter a name.")
* @Serializer\Type("string")
*/
public $name;

/**
* @var string
*
* @Assert\NotBlank(message = "Please enter a surname.")
* @Serializer\Type("string")
*/
public $surname;
}

Controller


namespace My\TestBundle\Controller;

use My\TestBundle\Type\InterestType;
use My\TestBundle\Model\Interest;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

/**
* @Route("/interest", service="my_test_bundle.controller.interest")
*/
class InterestController
{
private $formFactory;
private $router;

public function __construct(
FormFactoryInterface $formFactory,
RouterInterface $router
) {
$this->formFactory = $formFactory;
$this->router = $router;
}

/**
* @Method({"GET"})
* @Route("", name="interest_index")
* @Template()
*
* @param Request $request
*
* @return array
*/
public function indexAction(Request $request)
{
$form = $this->createForm();

$session = $request->getSession();
if ($session->has($this->getFormName())) {
$request->request->set(
$this->getFormName(),
unserialize($session->get($this->getFormName()))
);
$request->setMethod('POST');
$form->handleRequest($request);
}

return ['interest_form' => $form->createView()];
}

/**
* @Method({"POST"})
* @Route("", name="interest_create")
*
* @param Request $request
*
* @return RedirectResponse
*/
public function createAction(Request $request)
{
$session = $request->getSession();

$form = $this->createForm();
$form->handleRequest($request);
if ($form->isValid()) {
// Do something with: $form->getData();

$session->remove($this->getFormName());
$routeName = 'home_or_success_route';
} else {
$session->set(
$this->getFormName(),
serialize($request->request->get($this->getFormName()))
);

$routeName = 'interest_index';
}

return new RedirectResponse($this->router->generate($routeName));
}

private function createForm()
{
return $this->formFactory->create(
InterestType::class,
new Interest(),
[
'method' => 'POST',
'action' => $this->router->generate('interest_create'),
'attr' => ['id' => $this->getFormName()],
]
);
}

private function getFormName()
{
return InterestType::NAME;
}
}