Symfony render controller - symfony

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)

Related

Add to Symfony form action

I've created a page with tabs (using bootstrap), and all tabs have their own form. And they all work well. My problem is when I get a form error, I want to open the tab that the error is on.
My current controller code:
public function add(Request $request, EntityManagerInterface $em): Response {
$this->denyAccessUnlessGranted('ROLE_USER');
$entityAdd = new \App\Entity\add();
$form = $this->createForm(\App\Form\Add::class, $entityAdd);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
Function in AddFormType.php
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add(...)
->add(...)
->add(...)
->getForm()
;
}
I'm not creating the form myself, I'm using symfony form components but I'm not sure how to modify the form method to add the form hash (eg. /add#list-tab1) to the form method.
{{ form_start(AddForm) }}
{{ form_row(AddForm.name1) }}
{{ form_row(AddForm.name2) }}
{{ form_row(AddForm.save) }}
{{ form_end(AddForm) }}
You can pass the hash with the third parameter of createForm method :
$form = $this->createForm(
\App\Form\Add::class,
$entityAdd,
['action' => '#list-tab1']
);
Then, you can use the setAction() method and retrieve the option in the buildForm() method in your AddFormType.php file:
$builder
->setAction($options['action'])
->add(...)
Note: Using only the hash in the setAction() method (and not the full route), is only working if the form is submitted to the current route.
You'll have to replace #list-tab1 with the real tab id.
You can pass the action directly in the parameters of form_start(), in the Twig template:
{{ form_start(form, { action: '/add#list-tab1' }) }}
See the Symfony doc about this field option.

How to render specific form elements Drupal 8

I am using Drupal 8 and would like to customize how form elements are being displayed. Specifically, I don't like how uneditable, populated textfields are displayed as plain text. I would have it being displayed as an editable textfield (or have the text look like it is in an uneditable textfield). I have looked at various hook functions to try and achieve this but nothing seems to work.
I figure the best way to go about this is if I can render the form fields individually myself and then create a twig file that displays the individual fields as I would like them to be displayed. Here is what I would like the twig field to look like:
<div class="from">
{{ form.mail }}
</div>
<div class="message">
{{ form.message }}
</div>
<div class="actions">
{{ form.actions }}
</div>
In your .module file
function your_module_theme($existing, $type, $theme, $path) {
return [
'custom_theme' => [
'variables' => [
'form' => NULL
],
'render element' => 'form',
]
];
}
In your CustomForm.php file
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
[...your fields ...]
return $form
}
In your custom module templates directory
custom-theme.html.twig
{{ form.your_field }}

Render a choice field without form

I often need to render very simple imputs in some of my templates.
I'd like to take advantage of the twig macros & form blocks to render certain HTML inputs without involving the whole Symfony forms machinery.
For example from the controller:
$templateContext = array(
'my_input' = new FormField('my_input', 'choice', array(
'choices' => array('value1', 'value2', 'my_value'),
'value' => 'my_value',
));
);
In the template:
<div>{{ form_widget(my_input) }}</div>
would render:
<div>
<select name="my_input">
<option>value1</option>
<option>value2</option>
<option selected="selected">my_value</option>
</select>
</div>
Is there a simple way to do that ?
Eventually I would also like to be able to reuse these fields elsewhere (like we can reuse form types)
There are many ways to go about this. The easiest would be to write the plain HTML into your twig template.
<form method="post">
<div>
<select name="my_input">
<option>value1</option>
<option>value2</option>
<option selected="selected">my_value</option>
</select>
</div>
</form>
And then in your controller read the values back.
$request = $this->getRequest();
if($request->getMethod() == 'POST'){
$data = $request->get('my_input')
//Do whatever you want with $data
}
If you want you re-use the html, you can build it somewhere in your PHP and pass it into Twig whenever you need it; or you can place it in a separate twig template and read that with the {include ''} command in twig.
Here is what I finally ended up with:
Class MyInput {
public static values = array(
'value1',
'value2',
'my_value',
);
}
class MyInputType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'choices' => MyInput::$value,
));
}
public function getParent() { return 'choice'; }
public function getName() { return 'my_input_type'; }
}
Field type used from the controller (after having registered it as a service)
public function MyAction(Request $request)
{
$form = $this->createForm('my_input_type');
$form->handleRequest($request);
$templateContext['myForm'] = $form->createView();
// ...
}
Input rendered into the template
<div>{{ form(myForm) }}</div>
To conclude: I've not been able to render an input without the form machinery, but the actual form remains rather simple.
I found my own solution for it since i need to create subforms from existing forms.
create totally empty twig template,
add in it only {{form(form)}}
render this template render()->getContent()
do a preg replace on the result (i do it in js) formView = formView.replace(/<(.*?)form(.*?)>/, '');
Yes yes - i know that regex is not perfect so before someone says it - i say it on my own, change it for youself as it catches "form-group" classes etc as well.
This is just a showcase of my solution

How to reload part of twig with ajax

I need to reload part of my html.twig:
in controller:
$entity = $em->getRepository('PublishDemandsBundle:Demands')->find($id);
In twig:
{% for n in entity %} {{ n.Id }} {% endfor %}.
i need how to reload $entity with ajax.Can someone help me and thanks.
You can do this with jQuery. I think the best way to do this (I think) is to have a method in your controller that do nothing but a findAll() on your Demands repo :
public function demandsAction()
{
$entity = $em->getRepository('PublishDemandsBundle:Demands')->findAll();
return $this->render('PublishDemandsBundle:Demands:liste.html.twig', array(
'entity' => $entity
));
}
Make sure this Action can be called by a route, let's say /ajax/demands/
Then, in your twig template, just do :
<div id="demands">
{{ render(controller("PublishDemandsBundle:MainController:demands")) }}
</div>
reload
With a bit of jQuery :
$('#reload').click(function() {
$.get("/ajax/demands", function( data ) {
$('#demands').html( data );
});
I haven't tested this yet, and it might be adapted to your case, but again, I would do it this way.

symfony 2 - twig - How view more (20) fields with use "prototype"?

I want view 20 same fields (name: matchday) with use "prototype".
I have a code like this:
Form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('matchday', 'collection', array(
'allow_add' => true,
'type' => new MatchdayType(),
))
...
}
and View (Twig):
<form action="{{ path('meet_create') }}" method="post" {{ form_enctype(form) }}>
{% for i in 1..20 %}
{{ form_widget(form.matchday.vars.prototype) }}
{% endfor %}
<p>
<button type="submit">Create</button>
</p>
</form>
but I don' know how use iteration in this code with "prototype" .
thanks
The prototype is only a model that you can use to create new fields in the form's collection, but it's not really a field per say. If you want to display 20 empty fields from the beginning, you have basically two choices:
add 20 empty 'matchday' objects in the form object in your controller before creating the form
use Javascript (jQuery) to add the fields in the view on the client side
The first solution would give something like this:
$meet = new Meet();
for ($i=0; $i < 20; $i++) {
$matchday = new MatchDay();
$meet->getMatchdays->add($matchday);
}
$form = $this->createForm(new MeetType(), $meet);
For the second solution, you have a good example in the Symfony Cookbook about form collection: http://symfony.com/doc/current/cookbook/form/form_collections.html

Resources