Thomas Clermont
Thomas Clermont

Reputation: 57

Call a form from a herited controller

I have two Bundles:
MainBundle: Who have the different part of my website.
SecondBundle with a form to encode different offers.( The offer Bundle )

My problem is that I want to call my offer form controller in my main page twig of my MainBundle.

I have no problem to call the Form but the data of my form don't save in my DB. On the other side, if I put my Form in my Main Controller, I have no problem and it save all the data correctly.

The form twig code :

{{ form_start(form,{'attr': {'id': 'FootForm'}}) }}
<div class="field-warper">
    {{ form_label(form.titre, "Titre") }}
    {{ form_widget(form.titre,{'attr': {'placeholder': 'Titre'}}) }}
</div>
<div class="field-warper">
    {{ form_label(form.contenu, "Contenu") }}
    {{ form_widget(form.contenu,{'attr': {'placeholder': 'Contenu'}}) }}
</div>
<div class="field-warper">
    {{ form_label(form.price, "Price") }}
    {{ form_widget(form.price,{'attr': {'placeholder': 'Price'}}) }}
</div>
<div class="field-warper submit-warper">
    {{ form_widget(form.send,{'attr':{'class':'submit'}}) }}
</div>
{{ form_end(form) }}

My main page twig :

{% extends "DellexisMainBundle:Common:base.html.twig" %}

{% block body %}
    <div>
        <p>i'm the Body</p>

        {% block formu %}
            {{ render(controller('DellexisOfferBundle:Offer:index')) }}
        {% endblock %}

    </div>
{% endblock %}

My offer controller ( The form controller ) :

class OfferController extends Controller
{
    public function indexAction(Request $request)
    {
        $entity_manager = $this->getDoctrine()->getManager();

        $offer=new Offer();

        $form = $this->get('form.factory')->createBuilder('form', $offer)
            ->add('titre','text')
            ->add('contenu','textarea')
            ->add('price','text')
            ->add('send', 'submit')
            ->getForm();
        // on joint la requete Post à notre classe
        $form->handleRequest($request);

        if($form->isValid()) {
            $entity_manager->persist($offer);
            $entity_manager->flush();
        }

        return $this->render('DellexisOfferBundle:Default:index.html.twig', array(
            'form' => $form->createView()
        ));
    }
}

My main controller :

class DefaultController extends Controller
{
    public function indexAction(Request $request)
    {
        return $this->render('DellexisMainBundle:Home:index.html.twig');
    }
}

routing.yml

dellexis_offer:
    resource: "@DellexisOfferBundle/Resources/config/routing.xml"
    prefix:   /offer

dellexis_main:
    resource: "@DellexisMainBundle/Resources/config/routing.xml"
    prefix:   /

OfferBundle routing.xml

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="dellexis_offer_homepage" path="/offer">
        <default key="_controller">DellexisOfferBundle:Default:index</default>
    </route>
</routes>

MainBundle routing.yml

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="dellexis_main_homepage" path="/">
        <default key="_controller">DellexisMainBundle:Default:index</default>
    </route>
</routes>

EDIT :

With a dump of the request of my OfferController and a dump of my DefaultController ( Main Bundle ), the POST method is on the DefaultController, the OfferController stay on a GET method.

EDIT 2 : THE SOLUTION :

I finaly find the solution. As the second controller didn't have the same request that the first controller. I think to forwark the request to the second controller. And the magic of symfony wants that works !

So if someone has the same problem, just forward the request like that :

public function indexAction(Request $request)
    {
        $this->forward('DellexisOfferBundle:Offer:index', array(
            'request'  => $request
        ));

        return $this->render('DellexisMainBundle:Home:index.html.twig');
    }

Upvotes: 3

Views: 72

Answers (1)

LdiCO
LdiCO

Reputation: 577

First of all, you should have different routes suffixes, Because you use the same one (\) in the two Bundles, witch is bad idea. You can add a suffix to the offerBundle routing config (\offer).

Also, in the routing.yml, you didn't load the offerBundle routing config file.

And, by looking at you controller, There is nothing to save. The indexAction shows the page and save a empty object new Offer().

You have to distinguish between POST Request (when you submit the data) and the GET Request (when you want to show the form)

you code should be something like this:

class OfferController extends Controller
{
    public function indexAction(Request $request)  {
      $entity_manager = $this->getDoctrine()->getManager();

      $offer=new Offer();

      $form = $this->get('form.factory')->createBuilder('form', $offer)
        ->add('titre','text')
        ->add('contenu','textarea')
        ->add('price','text')
        ->add('send', 'submit')
        ->getForm();
      // on joint la requete Post à notre classe
      $form->handleRequest($request);

      if($request->isMethod('POST') && $form->isValid()) {
        $entity_manager->persist($offer);
        $entity_manager->flush();
      }

      return $this->render('DellexisOfferBundle:Default:index.html.twig', array(
          'form' => $form->createView()
      ));
  }


}

Upvotes: 1

Related Questions