Symfony2 Form Anchors - symfony

I have a number of forms on the one page under different tabs
After the form is processed, I would like to return to the same tab as the form was sent from.
Basically, I would like to modify the target_route to go to the current page with an Anchor at the end of the URL. (EG company/view/6#editdetails)
Could someone provide or link to an example that I can put in my controller or into twig?

The answer is simply:
$form = $this->createForm(new ContactType($contact), $contact, array(
'method' => 'POST',
'action' => '#editdetails'
));

You may also set this in the template itself as an attribute. See example:
{{ form_start(form, {attr: { novalidate: "novalidate", class: 'requiredStar', action: '#form' }}) }}

Related

Symfony render controller

want to display a form in a modal in the header. In order to make the form work I call the controller Homecontroller.
I called the controller with render controller in the branch but I got a blank page.
Thanks for your help.
header.html.Twig
<h1 class="fw-bold"></h1>
<p class="lead fw-bold"></p>
{{include ('fragments/modal_form.html.twig') }}
</main>
</div>
</div>
modal_form.html.twig
{{ render(controller(
'App\\Controller\\HomeController::index',{'form' : form.createForm()} )) }}
</div>
Controller :
* #Route("/", name="home")
*/
public function index(PostsRepository $postsRepository,TagRepository $tagRepository, Request $request ):Response
{
$listTag = $tagRepository->findAll();
$listPost = $postsRepository->findByPostPHp('php');
$posts = $postsRepository->findByExampleField($value = 6);
$partage = New Posts();
$form = $this->createForm(PartagePostType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$partage = $form->getData();
$this->entityManager->persist($partage);
$this->entityManager->flush();
$this->addFlash('success', 'Votre post a bien été partagé');
}
return $this->render('home/index.html.twig', [
'posts' => $posts,
'tag' => $listTag,
'listPost' => $listPost,
'form' => $form->createView(),
]);
}
I dont' really get how you are trying to render you form but it doesn't work that way, in your modal_form.html.twig you should use the {{ form_start() }} and {{ form_end() }} twig helpers. They take in parameters the created view of the form, i.e, the variable "form" in your case (created in your render with the createView() method).
It should look like that:
{{ form_start(form}}
{{ form_row(form.field) }}
<input type="submit" value="submit">
{{ form_end(form) }}
"field" is whatever name you defined in your FormType. Notice how I added raw HTML for the submit button, it is suggested by Symfony you add the send button that way, even though you can add it in your FormType.
You can learn more about form rendering here : How to Customize Form Rendering
And forms in general there : Forms
Last thing, if you want to use multiple forms with this modal, don't forget to change the name of the variable (also don't forget to add this variable in your controller when you render a template with a form in it, obviously)

Symfony - pass custom data from Form Builder to form theme

I would like to set a special div surrounding a bunch of my fields. For that I want to add something to the form builder that I could detect in my form_theme, and set the div when it's there.
I tried to add
->add('field', new myCustomType(), array('inherit_data' => true, "label" => false, "required" => false, 'attr' => array("test" => "aaa")))
to the form builder, setting an custom attr, it's actually rendered in the html as an attribute... But I'm unable to detect it in the form theme.
{{ block('widget_container_attributes') }}
Only gives the widget attributes, and
{{ block('row_container_attributes') }}
doesn't work. I actually have a hard time finding any source online about what variables are available in the blocks of the form theme and how to use them (it was already difficult to know how to call blocks).
I looked for some more information on the official site, here mostly but without any success...
Thanks ahead for any help !
If you put it in your form builder, then you might as well permanently set in your template. If there is some logic required to set the data, then that belongs in your controller anyway, so just put it there to start with.
Controller:
public function someAction()
{
// ....
return $this->render('some_twig_template.twig.html', array(
'attr' => array("test" => "aaa")
);
}
Then in your twig template
{{ dump(attr) }}
{{ dump(attr.test) }}
EDIT:
To render in your template every time, you can set a class on the rendered field directly:
{{ form_label(form.field, 'My label', { 'label_attr': {'class': 'js-hidden-row'} }) }}
{{ form_widget(form.field, { 'attr': {'class': 'js-hidden-row'} }) }}
Then in my javascript you can hide with some simple jQuery:
<script>
jQuery(document).ready(function() {
$('.js-hidden-row').hide();
});
</script>

Invalid CSRF using symfony2 form type

I'm creating 2 forms in one action and these forms are submitted by jquery ajax to other 2 actions. Now, problem is - only first form works. Edit form throws that csrf token is invalid. Why is that happening? My code:
Creating forms:
$project = new Project();
$addProjectForm = $this->createForm(new AddProjectType(), $project, [
'action' => $this->generateUrl('tfpt_portfolio_versionhistory_addproject'),
'method' => 'POST',
'attr' => ['id' => 'newProjectForm']
]);
$editProjectForm = $this->createForm(new EditProjectType(), $project, [
'action' => $this->generateUrl('tfpt_portfolio_versionhistory_editproject'),
'method' => 'POST',
'attr' => ['id' => 'editProjectForm']
]);
Handling submit edit form (but add form is pretty much identical):
$project = new Project();
$form = $this->createForm(new EditProjectType(), $project);
$form->handleRequest($request);
if($form->isValid()){
//handle form
}
}
The only diffrence between these 2 forms is that edit form have one more field - hidden id. Both are submitted by jquery like that:
var form = $("#editProjectForm")
if(form.valid()){
$("#loader").show();
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize()
}).done(function(data){
//result
}
});
And i display forms like that:
{{ form_start(editProjectForm) }}
{{ form_errors(editProjectForm) }}
{{ form_widget(editProjectForm.name) }}
{{ form_widget(editProjectForm.id) }}
{{ form_rest(editProjectForm) }}
{{ form_end(editProjectForm) }}
Can somebody point my mistake? Isn't it possible to embed 3 forms in one action? Or i have to generate CSRF other way?
#Edit: I updated symfony to the newest release and now it's working prefect. Seems like this version had a bug or i got some lack of vendors code. Anyway, problem resolved.
I think you have to create two tokens in the controller:
$token_add = $this->get('form.csrf_provider')->generateCsrfToken('add');
$token_edit = $this->get('form.csrf_provider')->generateCsrfToken('edit');
and put in the view in hidden field. And then validate in the controller action that proccess the form
# Here you can validate the 'add' or 'edit' token
if (!$this->get('form.csrf_provider')->isCsrfTokenValid('add', $token)) {
$respuesta = array('mensaje' => 'Oops! Invalid token.',
'token' => $token);
return new Response(json_encode($respuesta));
}

Why getMethod() returns "GET" instead of "POST"?

The goal is to submit a POST form with two radiobuttons (tipo) and a text field (numero) to make a query in my DB and show the data to the user.
I am trying to submit the form below, however when I submit the form, the request coming accross is a 'GET REQUEST'. The form is in "SupuestoConfig.html.twig":
<div id="cuadro">
<form id="configurador" action="{{ path('configsup') }}" method="POST">
<p class="titulo_configurador">Elija supuesto penal:</p>
{{ form_row(form.tipo) }}
{{ form_row(form.numero, { 'label' : ' ', 'attr' : { 'class' : 'rec3' }}) }}
{{ form_rest(form) }}
<input type="submit" name="cargar" value="Cargar" class="inputbt"/>
</form>
</div>
I render the previous form in "principal.html.twig":
{{ render(controller('PprsBundle:Default:SupuestoConfig'), {'strategy': 'inline'}) }}
My "Controller.php":
/**
* #Route("/pprs/principal/supuesto={numero_supuesto}", name="configsup")
* #Template("PprsBundle:Default:SupuestoConfig.html.twig")
*/
public function SupuestoConfigAction($numero_supuesto = null)
{
$form = $this->createFormBuilder(null)
->add('tipo', 'choice', array(
'choices' => array(
'aleatorio' => 'Aleatorio',
'pornumero' => 'Por número'),
'multiple' => false,
'expanded' => true,
'data' => 'aleatorio'
))
// This add may contains error
->add('numero', 'text', array('label' => ' ','disabled' => true))
->getForm();
$peticion = $this->getRequest();
echo ('<script type="text/javascript">alert ("'.$peticion->getMethod().'");</script>');// Returns 'GET'
if ($peticion->isMethod('POST')) {
// Symfony2.2
$form->bind($peticion);
**$datos = $form->getData();**
*//foreach(array_keys($datos) as $p) {
//echo ('<script type="text/javascript">alert ("'.$datos.'");</script>');
//}*
if ($form->isValid()) { ... }
In Controller.php, despite I´ve got a GET request (when I remove the line
->add('numero', 'text',..
I´ve got a POST request, why is that?), in getData I don´t get the text field.
Finally, my routing.yml:
pprs_principal:
pattern: /pprs/principal/supuesto={numero_supuesto}/
defaults: { _controller: PprsBundle:Default:principal, numero_supuesto: 1 }
_pprs_principal:
pattern: /pprs/principal/
defaults: { _controller: FrameworkBundle:Redirect:redirect, route: pprs_principal }
Sorry for my bad english, Thanks in advance
Edit:
1) Anybody knows why I obtain a GET request instead of a POST when I add the text field in my createFormBuilder?
2) Anybody knows why Don't I get the text field when I call getData?
Help me please...
Maybe this answer could help you out:
getRequest() returns "GET" when posting form
Basically, when rendering a form with a {% render %} tag, it actually creates "another" request... It doesn't pass in the locale, the method, etc.
I opened a bug about this, and it went as By Design:
https://github.com/symfony/symfony/issues/7551

How do I use TrSteelCkEditorBundle in Symfony2?

I am new in the world of sf2 and I am trying to learn it.
I installed TrSteelCkEditorBundle with composer and now I am trying to get the editor in a view.
My bundle is active in the AppKernel.
As a beginner my question is:
What do I have to do to make it works?
I put this code and paste the value in the render
$form = $this->createFormBuilder()
->add('title', 'text')
->add('content', 'ckeditor', array(
'transformers' => array(),
))
->getForm();
And in the twig view i have line 6:
{{ form_widget(form) }}
but i'm getting an error :
An exception has been thrown during the rendering of a template ("Catchable Fatal Error:
Argument 1 passed to Symfony\Component\Form\FormRenderer::searchAndRenderBlock()
must be an instance of Symfony\Component\Form\FormView,
instance of Symfony\Component\Form\Form given, called in
/Applications/mamp/htdocs/Sf2/app/cache/dev/twig/5c/eb/e10823d760716de7f56b39640e79.php
on line 29 and defined in
/Applications/mamp/htdocs/Sf2/vendor/symfony/symfony/src/Symfony/Component/Form/FormRenderer.php
line 131") in amTestBundle:Default:index.html.twig at line 6.
If someone had a clue to resolve that it'll help me a lot.
Thank you.
The {{ form_widget(form) }} doesn't work because your $form variable is the form itself. In order to get Twig to create the widgets for it, you have to send it to the Twig template with:
$form->createView()
Here is an example of when you return in your controllerAction:
return $this->render(
'AcmeFooBundle:Acme:template.html.twig',
array('form' => $form->createView()) //Here you see the createView()
);

Resources