Symfony 6 : Customize a form with radio buttons - symfony

I have a form and want to customize it with symfony :
<input type="radio" name="type" value="auto" onClick="getMarques('auto')" id="check1">
<label class="s-submitCheckLabel" for="check1"><span class="m-circle"></span></label>
<label class="s-submitCheck" for="check1">Auto</label>
I have tried this:
{% for child in formAnnonce.category %}
{{ form_widget(child, {'attr' : {'class': 'form-check-input'}, {'name': 'type'}, {'id': 'check1'} }) }}
{{ form_label(child)}}
{{ form_help(child) }}
{{ form_errors(child) }}
{% endfor %}

{% for child in formAnnonce.category %}
{{ form_widget(child, {'attr': {'onclick': 'getMarques("' ~ child.vars.value~'")'}})}}
<label class="s-submitCheckLabel" for="{{ child.vars.id }}"><span class="m-circle"> </span></label>
<label class="s-submitCheck" for="{{ child.vars.id }}">{{ child.vars.label </label>
{% endfor %}

Related

Unexpected token "name" of value "if" ("end of statement block" expected)

I tried to upgrade Symfony to 4.4.17 and I got the above error for the line:
{% for lang, group in lang_groups if lang == from %}
This is the code. I have no idea how to fix this.
<div class="input-style">
<input type="text" name="query" value="{{ query|default('') }}" />
</div>
<div class="select-style">
<select name="lang_from">
{% for lang, group in lang_groups %}
<option value="{{ lang }}"{% if from == lang %} selected{% endif %}>{{ group.label }}</option>
{% endfor %}
</select>
</div>
⇄
{% for lang, group in lang_groups if lang == from %}
<div class="select-style lang-group" data-lang="{{ lang }}">
<select name="{{ lang }}">
{% for lang_to, data in group.to %}
<option value="{{ lang_to }}"{% if to|default('') == lang_to %} selected{% endif %}>{{ data.label }}</option>
{% endfor %}
</select>
</div>
{% endfor %}
You have to put the if statement out of your for...in
So instead of this
{% for lang, group in lang_groups if lang == from %}
<div class="select-style lang-group" data-lang="{{ lang }}">
<select name="{{ lang }}">
{% for lang_to, data in group.to %}
<option value="{{ lang_to }}"{% if to|default('') == lang_to %} selected{% endif %}>{{ data.label }}</option>
{% endfor %}
</select>
</div>
{% endfor %}
If I understood what you are trying to do, you should do something like this:
{% for lang, group in lang_groups %}
{% if lang == from %}
<div class="select-style lang-group" data-lang="{{ lang }}">
<select name="{{ lang }}">
{% for lang_to, data in group.to %}
<option value="{{ lang_to }}"{% if to|default('') == lang_to %} selected{% endif %}>{{ data.label }}</option>
{% endfor %}
</select>
</div>
{% endif %}
{% endfor %}

FOSUserBundle: Why register uses the symfony forms whilst login renders it via html?

As I was stydying the FOSUserBundle I noticed that the register form uses the form_widget and Symfony's form template as seen in register_content.html.twig:
{% trans_default_domain 'FOSUserBundle' %}
{{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register'}}) }}
{{ form_widget(form) }}
<div>
<input type="submit" value="{{ 'registration.submit'|trans }}" />
</div>
{{ form_end(form) }}
While the form fort login does not even bother to use the symfony's form template as seen in logn_content.html.twig:
{% trans_default_domain 'FOSUserBundle' %}
{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="{{ path("fos_user_security_check") }}" method="post">
{% if csrf_token %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
{% endif %}
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" required="required" />
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" name="_password" required="required" />
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
<input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}" />
</form>
And I have the burning desire to learn why there is this differrence between the implementations of theese forms.
One possible reason can be that Symfony uses a different action that checks the credentials and thus Symfony does not use form validation and processing (data stored in an entity) the way that it does when using the formbuilder. So in this case you should use the formbuilder only to render the HTML which makes it a bit slower than rendering the HTML directly.
The formbuilder becomes a handy tool when you need to render forms that need validation and/or csrf protection or when you use an entity as formdata. But the use of Symfony's formbuilder is not mandatory and not always required. For example a formfield with only some Javascript actions that will not lead to a new (POST-)request and therefore never being processed on server-side does not need to use Symfony's formbuilder.

Shopify Custom Text box according to product collection

Im trying to do a conditional where if a product is in collection "personal" it will show a text box. I have this in the product.liquid page but it does't seem to be working.
{% if collection.title == 'personal' %}
<div>
<p><input type="text" id="letter" placeholder="Enter up to 6 Letters" name="properties[letter]" /></p>
</div>
{% endif %}
Try this:
{% for collection in product.collections %}
{% if collection.handle == 'personal' %}
<div>
<p><input type="text" id="letter" placeholder="Enter up to 6 Letters" name="properties[letter]" /></p>
</div>
{% endif %}
{% endfor %}
See the Shopify docs for product.collections.

Is it possible to wrap a form_widget with a form_label in Twig?

To integrate this in Twig:
<label class="control-label" for="lastname">Last Name:</label>
<div class="controls">
<input type="text" id="firstname" name="firstname">
<span class="help-block">{{ form_errors(form.firstname) }}</span>
</div>
I used the following code snippet:
{{ form_label(form.firstname, null, {'label_attr': {'class': 'control-label'}}) }}
<div class="controls">
{{ form_widget(form.firstname) }}
<span class="help-block">{{ form_errors(form.firstname) }}</span>
</div>
And everything worked fine.
But my question is ...
Is it possible to wrap a form_widget with a form_label in Twig? The final result should then be similar to:
<label class="radio" for="dn">
<input type="radio" id="dn" name="spotlight" value="1"> Test 1
</label>
<label class="radio" for="gn">
<input type="radio" id="gn" name="spotlight" value="1"> Test 2
</label>
<span class="help-block">Errors</span>
Can I use anything else than form_label and form_widget to achive the same result?
You can change the display of the form_row() output in only one file:
{% form_theme form _self %}
{% block form_row %}
<div class="form_row">
{% if label is not sameas(false) %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %}
{% endif %}
{% if required %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{% endif %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}
{% endif %}
{{ form_widget(form) }}
{% if label is not sameas(false) %}
</label>
{% endif %}
{{ form_errors(form) }}
</div>
{% endblock form_row %}
And display your field:
{{ form_row(form.firstname) }}
The <label> is now opening before the field and closing after the field.
I took the original code from default theme and use the cookbook entry Form Theming in Twig > Method 1: Inside the same Template as the Form.
If you want to apply your idea to all of your fields, consider using form customization in order to change the display of {{ form_row(....) }} in all your bundle.

Include FOSUser login form into homepage

I have a question about including login form of FOSUserBundle in other layout.
In some way, I want to have two login form :
One login form, without extends, that I can include everywhere, for example here in my homepage
One login form who extends my basic layout, display for example when you call /login
I try something but I have this error :
An exception has been thrown during the rendering of a template ("No route found for "GET Security:LoginBisAction"") in rSWelcomeBundle:Homepage:index.html.twig at line 15.
I have two bundles : one WelcomeBundle and one UserBundle which extends FOSUserBundle.
In rs/WelcomeBundle I have my homepage, and I include the login form in the right block :
{% extends "rsWelcomeBundle::layout.html.twig" %}
{% block title "Page d'accueil" %}
{% block body %}
<div class="span6">
<div class="well">
<h2>Présentation du site</h2>
<p>Rejoignez nous, parce que ceci cela...etc ! </p>
<p>Je m'inscris !</p>
</div>
</div>
<div class="span6">
<div class="well">
{% render 'FOSUserBundle:Security:LoginBisAction' %}
</div>
</div>
{% endblock %}
In rs/UserBundle, at root, in rsUserBundle.php I extends FOSUserBundle :
<?php
namespace rs\UserBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class rsUserBundle extends Bundle
{
public function getParent()
{
return 'FOSUserBundle';
}
}
In rs/UserBundle/Ressources/views/layout.html.twig :
{% extends "rsWelcomeBundle::layout.html.twig" %}
{% block body %}
<div class="span4 offset4">
<div class="well">
{% for key, message in app.session.flashbag.all() %}
<div class="alert alert-{{ key }}">
{{ message|trans({}, 'FOSUserBundle') }}
</div>
{% endfor %}
{% block fos_user_content %}
{% endblock fos_user_content %}
</div>
</div>
{% endblock %}
In rs/UserBundle/Ressources/views/Security/login.html.twig :
{% extends "FOSUserBundle::layout.html.twig" %}
{% block fos_user_content %}
{% if error %}
<div>{{ error|trans({}, 'FOSUserBundle') }}</div>
{% endif %}
{% include "UserBundle:Security:login_content.html.twig" %}
{% endblock fos_user_content %}
In rs/UserBundle/Ressources/views/Security/login_content.html.twig :
<form action="{{ path("fos_user_security_check") }}" method="post">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
<label for="username">{{ 'security.login.username'|trans({}, 'FOSUserBundle') }}</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" />
<label for="password">{{ 'security.login.password'|trans({}, 'FOSUserBundle') }}</label>
<input type="password" id="password" name="_password" />
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
<label for="remember_me">{{ 'security.login.remember_me'|trans({}, 'FOSUserBundle') }}</label>
<input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans({}, 'FOSUserBundle') }}" />
</form>
And in rs/UserBundle/Controller/ I have only one file UserController.php :
<?php
namespace rs\UserBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use FOS\UserBundle\Controller\SecurityController as SecurityController;
use rs\UserBundle\Entity\User;
/**
* Description of UserController
*
*/
class UserController extends SecurityController {
public function LoginBisAction()
{
$csrfToken = $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate');
return $this->container->get('templating')->renderResponse('FOSUserBundle:Security:login_content.html.twig', array(
'last_username' => null,
'error' => null,
'csrf_token' => $csrfToken
));
}
}
What's wrong, did I have to create a route somewhere ?
Why my loginAction is not found when I go to my homepage ?
Why I have this error :
An exception has been thrown during the rendering of a template ("No route found for "GET Security:LoginBisAction"") in rSWelcomeBundle:Homepage:index.html.twig at line 15.
Thanks a lot !
As in error message: "No route found for "GET Security:LoginBisAction"". So you are call not existed route (exactly not existed controller action). Please notice that there are no LoginBisAction for raw Security FOSUser bundle. Try to call your extended controller action:
{% render 'rsUserBundle:User:LoginBisAction' %}

Resources