First, best wishes to all for this 2016 new year !
I'm facing a problem I did not manage to resolve on my own.
I'm working on a Silex (~1.3
) application. I coded simple CRUDs on my domain classes. I created as well some Type forms to be able to modify my basic domain classes. In this case, I have to manage the notion of State
within a Country
. Each is a specific class, and a State
has one Country
attribute.
In my form, I declared some text fields, and a Choice
field to be able to select the country (the form class is copied below).
My problem is that when I try to modify an existing State
with the following controller, the text fields name
, code
, unloc
are filled with the data from the database, but not the choices country
nor hub
(the controller class is copied below).
Please note that i'm NOT using Doctrine, but a home-made (and quite basic) DAO.
Here is my code and some information :
The view is done using twig, with the 'standard' bootstrap example which can be found here : Form Customization, using Bootstrap layout and Form layout :
{% extends 'layout.html.twig' %} {% block title %}{{ title }}{% endblock %} {% block content %} {% if form and is_granted('IS_AUTHENTICATED_FULLY') and is_granted('ROLE_ADMIN')%} {% form_theme form 'bootstrap_3_layout.html.twig' %} {{ form_start(form) }} <div class="form-group"> {{ form_errors(form) }} {{ form_widget(form) }} <input type="submit" class="btn btn-primary" value={% if button is not defined %} "Save"{% else %}"{{ button }}"{% endif %} /> </div> {{ form_end(form) }} {% else %} <div> <p>Ask an admin to add/modify information.</p> </div> {% endif %} {% endblock %}
composer.json content :
{ "require": { "silex/silex": "~1.3", "doctrine/dbal": "2.5.*", "symfony/security": "2.7.*", "twig/twig": "1.21.*", "symfony/twig-bridge": "2.7.*", "symfony/form": "2.7.*", "symfony/translation": "2.7.*", "symfony/config": "2.7.*", "jasongrimes/silex-simpleuser": "*", "twig/extensions": "1.3.*", "symfony/validator": "2.*", "phpoffice/phpexcel": "1.*" }, "require-dev": { "phpunit/phpunit": "*", "symfony/browser-kit": "*", "symfony/css-selector": "*", "silex/web-profiler": "*", "symfony/monolog-bridge": "*" }, "autoload":{ "psr-4":{"Easytrip2\\": "src"} } }
Form code :
<?php namespace Easytrip2\Form\Type; use Easytrip2\DAO\CountryDAO; use Easytrip2\DAO\GeopointDAO; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class StateType extends AbstractType { /** * @CountryDAO * \Easytrip2\DAO\CountryDAO * allow to find the Country for the form. */ private $countryDAO; /** * @GeopointDAO * \Easytrip2\DAO\GeopointDAO * allow to find the Country for the form. */ private $geopointDAO; /** * * {@inheritDoc} * * @see \Symfony\Component\Form\AbstractType::buildForm() */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add ( 'name', 'text', array ( 'label' => 'State name' ) ); $builder->add ( 'code', 'text', array ( 'label' => 'State code' ) ); $builder->add ( 'unloc', 'text', array ( 'label' => 'State code' ) ); $countries = $this->countryDAO->findAll (); $choices = array (); $labels = array (); foreach ( $countries as $value ) { $choices [] = $value; $labels [] = $value->getName (); } $builder->add ( 'country', 'choice', array ( 'choice_list' => new ChoiceList ( $choices, $labels ) ) ); $hubs = $this->geopointDAO->findAllHubs (); $choices = array (); $labels = array (); foreach ( $hubs as $value ) { $choices [] = $value; $labels [] = $value->getName (); } $builder->add ( 'hub', 'choice', array ( 'choice_list' => new ChoiceList ( $choices, $labels ), 'required' => false ) ); } /** * * {@inheritDoc} * * @see \Symfony\Component\Form\AbstractType::configureOptions() */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults ( array ( 'data_class' => 'Easytrip2\Domain\State' ) ); } /** * * {@inheritDoc} * * @see \Symfony\Component\Form\FormTypeInterface::getName() */ public function getName() { return 'state'; } /** * allow use of a CountryDAO */ public function __construct(CountryDAO $countryDAO, GeopointDAO $geopointDAO) { $this->geopointDAO = $geopointDAO; $this->countryDAO = $countryDAO; } }
Controller content :
public function stateUpdateByIdAction($id, Request $request, Application $app) { if ($app ['security.authorization_checker']->isGranted ( 'IS_AUTHENTICATED_FULLY' ) and $app ['security.authorization_checker']->isGranted ( 'ROLE_ADMIN' )) { $obj = $app ['dao.state']->findById ( $id ); $form = $app ['form.factory']->create ( new StateType ( $app ['dao.country'], $app ['dao.geopoint'] ), $obj ); $form->handleRequest ( $request ); if ($form->isSubmitted () && $form->isValid ()) { if ($app ['dao.state']->save ( $obj )) { $app ['session']->getFlashBag ()->add ( 'success', 'The state was succesfully updated.' ); return $app->redirect ( $app ['url_generator']->generate ( 'state' ) ); } else { $app ['session']->getFlashBag ()->add ( 'error', 'Something went wrong...' ); } } return $app ['twig']->render ( 'form.html.twig', array ( 'form' => $form->createView (), 'title' => 'Edit states' ) ); } else { $app ['session']->getFlashBag ()->add ( 'error', 'Don\'t have the rights...' ); return $app->redirect ( $app ['url_generator']->generate ( 'home' ) ); } }