I have an entity "group", with a name and a description.
I created a form for update both, but when I click on submit, values are set to NULL.
I also tried to create a new entity. But in this case, their value are set to default value in the field.
Here's my code :
my form :
<form method="post" class="form-signin" {{ form_enctype(form) }}>
<input id="name" name="form[name]" required="required" value="{{ group.name }}"></input>
<textarea id="description" name="form[description]" >{{ group.description }}</textarea>
<input class="btn btn-lg btn-primary btn-block" type="submit" id="_submit" name="_submit" value="submit" />
</form>
my controller :
public function updateParametersAction()
{
$user = $this->get('security.context')->getToken()->getUser();
$repository = $this->getDoctrine()
->getManager()
->getRepository('MyBundle:Groups');
$group = $repository->findOneByIdUser($user->getId());
$form = $this->createFormBuilder($group)
->add('name', 'text')
->add('description', 'textarea')
->getForm();
$request = $this->get('request');
if ($request->getMethod() == 'POST') {
$em = $this->getDoctrine()->getManager();
$em->persist($group);
$em->flush();
}
return $this->render('MyBundle:Client:updateParameters.html.twig', array(
'group' => $group,
'form' => $form->createView()
));
}
What's wrong ?
You have to bind a request to the form:
// (...)
$form = $this->createFormBuilder($group)
->add('name', 'text')
->add('description', 'textarea')
->getForm();
$form->handleRequest($request);
// (...)
Related
I am using symfony 3.1 with regular html forms to make it easier to do front-end styling. I am continuously getting the following two errors. the first is;
The CSRF token is invalid. Please try to resubmit the form.
and the second is
This form should not contain extra fields.
The first is because I don't know how to correctly use the csrf token with plain html forms. My form looks like this:
FormType Class:
class TypeFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('isActive', CheckboxType::class)
->add('descriptor');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Type',
'csrf_protection' => true,
//'allow_extra_fields' => true
]);
}
public function getName()
{
return 'app_bundle_type_form_type';
}
public function getBlockPrefix()
{
// removes the need for the form[$name] requirement for form inputs
return '';
}
}
html form:
<form method="post">
<fieldset class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name">
</fieldset>
<fieldset class="form-group">
<label for="descriptor">Descriptor</label>
<select class="form-control c-select" id="descriptor" name="descriptor">
<option value="Award">Award</option>
<option value="Donation">Donation</option>
<option value="Event">Event</option>
</select>
</fieldset>
<fieldset class="checkbox">
<label class="" for="isActive">
<input type="checkbox" id="isActive" name="isActive" checked> Active</label>
</fieldset>
<input type="hidden" name="_csrf_token" value="{{ csrf_token("app_bundle_type_form_type") }}">
<button type="submit" class="btn btn-primary-outline pull-right">Submit</button>
</form>
Controller:
/**
* #Route("/admin/types/new", name="admin_types_new")
*/
public function newAction(Request $request)
{
$form = $this->createForm(TypeFormType::class);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
dump($form->getData());die;
}
return $this->render('admin/type/new.html.twig');
}
Can anyone tell me what I am doing wrong?
There is better (and working) approach to form rendering in Symfony:
In your controller:
/**
* #Route("/admin/types/new", name="admin_types_new")
*/
public function newAction(Request $request)
{
$form = $this->createForm(TypeFormType::class);
// ...
return $this->render('admin/type/new.html.twig', array('form' => $form->createView());
}
In your template:
{{ form_start(form, {'action': path('admin_types_new'), 'method': 'POST'}) }}
{{ form_widget(form) }}
<input type="submit" />
{{ form_end(form) }}
Please try this because it is usually a better approach: you don't have to care whether your html which you put by hand is correct and all ids and attributes are present or if csrf is generated properly. All is done by Symfony in this case, you just need to modify underlying FormType class and twig template to shape fields of your form.
More on the topic:
http://symfony.com/doc/current/book/forms.html
http://symfony.com/doc/current/reference/forms/twig_reference.html
http://symfony.com/doc/current/cookbook/form/form_customization.html
If anyone is interested in my fix:
<input type="hidden" name="{{ form._token.vars.full_name }}" value="{{ form._token.vars.value }}" />
It seems that you need name your token field as '_token'
I've got the following code to create a form in symfony2.
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('anne_stage_delete', array('id' => $id)))
->setMethod('DELETE')
->add('delete', 'submit')
->getForm()
;
}
But I can't find out how to add/change the name attribute. When I look in the rendered html the form name is form.
Make the form name in twig
<form action="{{ path('yourpath') }}" method="post" name="your_name-form">
{{ form_widget(form) }}
</form>
Or
You can use createNamedBuilder
$form = $this->get('form.factory')->createNamedBuilder('your-custom-name', 'form', null, array(
'constraints' => $collectionConstraint,
))
->add('delete', 'submit')
->getForm();
I'm trying to do a simple form. The bind between the controller and the view is done. But I can't receive the form data when the user submit.
public function addAction()
{
$router = $this->get('router');
$request = $this->get('request');
$ret = 'not set';
$title = 'not set';
if ($request->getMethod() == 'POST') {
$pictures = $request->files->get('pictures');
$title = $request->request->get('title');
$ret = $this->get('my_project_blog.post_service')
->create($title, $subtitle, $description, $pictures);
}
return $this->render('MyProjectBlogBundle:Default:add.html.twig', array('err' => $ret, 'title' => $title));
}
Now the add.twig.html
<form enctype="multipart/form-data" action="{{ path('my_project_blog_add') }}" method="POST" id="contactform">
<fieldset id="contact_form">
<label for="title">
<input type="text" name="title" id="name" placeholder="Enter A Title">
</label>
<label for="file">
<input name="pictures[]" type='file' multiple='multiple' ></input>
</label>
<input type="submit" class="submit btn btn-default btn-black" id="submit" value="Submit">
</fieldset>
</form>
The result before submit :
Pictures: not set.
Title: not set
After submit :
Pictures: Error pictures count == 0.
Title:
Is there any particular reason, why you are not using Symfony form component?
Not sure how it's possible, but maybe you got wrong request service from container. You should use Request Stack service or add $request as parameter of you action. Just tested following code and everything works correctly.
public function addAction(Request $request)
{
if ($request->getMethod() == 'POST') {
$title = $request->request->get('title');
$files = $request->files->all();
}
}
As xurshid29 mentioned in comment, symfony gives you the opportunity to define forms easier and handle response easier.
// In controller
public function addAction(Request $request)
{
$form = $this->createFormBuilder()
->add('title')
->add('pictures', 'file', [
'multiple' => true, // Since symfony 2.5
])
->add('Submit', 'submit')
->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
// Process data from $form->getData()
}
return $this->render('MyProjectBlogBundle:Default:add.html.twig', [
'form' => $form->createView()
]);
}
// In view
{% block content %}
{{ form(form) }}
{% endblock %}
I have some troubles with my Symfony Form.
In my first controller, I render a form like this:
$annonce = new Annonce();
$formBuilder = $this->createFormBuilder($annonce);
$formBuilder
->add('title', 'text')
->add('valider', 'submit');
$form = $formBuilder->getForm();
$request = $this->get('request');
if ($request->getMethod() == 'POST') {
$form->bind($request);
$response = $this->forward('ProjectMainBundle:Commande:new', array(
'annonce' => $form["title"]
));
return $response;
}
And I print the form in the view like this:
<form method="post" {{ form_enctype(form) }}>
{{ form_row(form.title, {'attr': {'value': entity.mytext }}) }}
<input type="submit" class="btn btn-primary" />
</form>
That's give:
<form method="post">
<div>
<label class="required" for="form_title">Title</label>
<input id="form_title" type="text" value="11" required="required" name="form[title]">
</div>
<input class="btn btn-primary" type="submit">
</form>
So when I submit it, I got the warning
"An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class Symfony\Component\Form\Form could not be converted to string"
I simply want to redirect to the controller "newAction" (that's work), but with the value of the input of my form !
<input id="form_title" type="text" value="11" required="required" name="form[title]">
It seems to I return the form object with
$response = $this->forward('ProjectMainBundle:Commande:new', array(
'annonce' => $form["title"]
));
But how return just the value of the input of the form ?
Big thanks for help
Try calling $annonce->getTitle() instead of using $form["title"].
After calling "$form->bind($request)" your $annonce object should have the title entered in the form.
Using Symfony2.3.4.
I'm trying to create a form without using a type, it is actually a very small form, only two selects loading their options from the database, so far it works, what I can not do is to get the form data(in the controller) when it is submitted. I tried to follow the instruction here but I can't get it right.
Here is my code so far:
Controller:
function to pass the data to the form:
public function selectAction($id, $id_actpost){
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ActPostBundle:Edition')->find($id);
$students = $em->getRepository('PersonBundle:Students')->findAll();
$students2 = $em->getRepository('PersonBundle:ForeignStudents')->findAll();
if (!$entity) {
throw $this->createNotFoundException('Unable to find Edicion entity.');
}
return $this->render('ActPostBundle:Edition:select.html.twig', array(
'entity' => $entity,
'id_actpost' => $id_actpost,
'students' => $students,
'foreignstudents' => $students2,
));
}
html fragment regarding the form itself:
<form class="form-horizontal sf_admin_form_area"
action="{{ path('edition_update_selected',
{ 'id': entity.id, 'id_actpost': id_actpost }) }}"
method="post" enctype="multipart/form-data">
<div style="margin-left: 80px" class="row-fluid">
<div class="span12">
<select name="students" multiple="multiple">
{% for s in students %}
<option {%if s in entity.students%}selected="selected"{%endif%}>
{{s}}</option>
{%endfor%}
</select>
</div>
</div>
<div class="row-fluid">
<select name="students2" multiple="multiple">
{% for s in students2 %}
<option {%if s in entity.foreignstudents%}selected="selected"
{%endif%}>{{s}}</option>
{%endfor%}
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="glyphicon-refresh"></i> {{'Update' | trans}}</button>
<a class="btn" href="{{ path('edition', {'id_actpost' : id_actpost }) }}">
<i class="glyphicon-ban-circle"></i> {{'Cancel' | trans }}
</a>
</div>
</form>
and here is what I read from the link posted at the beginning:
function to get the submitted data and update the database, although the database part can stay ignored until I manage to get the data from the form:
public function update_selectedAction(Request $request, $id, $id_actpost) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ActPostBundle:Edition')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Edicion entity.');
}
$defaultData = array('message' => 'Type here');
$editForm = $this->createFormBuilder($defaultData)
->add('students','choice')
->add('students2', 'choice')
->getForm();
$editForm->handleRequest($request);
I would like to know if what I read is actually what I need, because although I think it is I might be wrong, so any insights regarding this matter or even any other way to do it will be really appreciated.
You should use symfony's form builder to build the form in your update_selectedAction() like
public function update_selectedAction(Request $request, $id, $id_actpost)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ActPostBundle:Edition')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Edicion entity.');
}
$defaultData = array('message' => 'Type here');
$form = $this->createFormBuilder($defaultData)
->add('students', 'entity',array('class' => 'PersonBundle:Students',
'property' => 'students','expanded'=>false,'multiple'=>false))
->add('students2', 'entity',array('class' => 'PersonBundle:ForeignStudents',
'property' => 'foreignstudents','expanded'=>false,'multiple'=>false))
->add('submit','submit')
->getForm();
if ($request->getMethod() == "POST") {
$form->submit($request);
if ($form->isValid()) {
$postData = current($request->request->all());
var_dump($postData); /* All post data is here */
/* echo $postData['students']; */
/* echo $postData['students2']; */
/*
* do you update stuff here
* */
}
}
return $this->render('ActPostBundle:Edition:select.html.twig', array('form'=>$form->createView()));
}
In your twig i.e ActPostBundle:Edition:select.html.twig render your form
{{ form(form) }}
Edit from comments
In your twig file render your form like
{{ form_errors(form) }}
{{ form_row(form.students) }}
{{ form_row(form.students2) }}
{{ form_row (form._token) }}
<input type="submit"> /* your submit button */
Edit from comments 2
IF you want to put the text in value attribute of selectbox you can use choice field type
$students = $em->getRepository('PersonBundle:Students')->findAll();
$students2 = $em->getRepository('PersonBundle:ForeignStudents')->findAll();
$studentsArray=array();
$students2Array=array();
foreach($students as $s){
$studentsArray[$s->getStudents()]=$s->getStudents();
}
foreach($students2 as $s){
$students2Array[$s->getForeignstudents()]=$s->getForeignstudents();
/* here array key part will be the value of selectbox like $students2Array['your val to get in post data'] */
}
$form = $this->createFormBuilder($defaultData)
->add('students', 'choice',array('choices' => $studentsArray,'expanded'=>false,'multiple'=>false))
->add('students2', 'choice',array('choices' => $students2Array,'expanded'=>false,'multiple'=>false))
->add('submit','submit')
->getForm();