feature #33954 Form theme: support Bootstrap 4 custom switches (romaricdrigon)

This PR was merged into the 4.4 branch.

Discussion
----------

Form theme: support Bootstrap 4 custom switches

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | /
| License       | MIT
| Doc PR        | https://github.com/symfony/symfony-docs/pull/12464

Hello,

At the moment, Symfony form theme supports [custom checkboxes](https://getbootstrap.com/docs/4.3/components/forms/#checkboxes) through an extra class in `label_attr`.
Bootstrap4 introduced also [custom switches](https://getbootstrap.com/docs/4.3/components/forms/#switches), which has exactly the same HTML markup, but use a different class. This PR slightly modify `bootstrap_4_layout` to handle it.

![image](https://user-images.githubusercontent.com/919405/66651725-0eaa3100-ec34-11e9-8b68-94324730ac80.png)

Some reasons why I think supporting those have its place in Symfony:
 - those are getting common in UI right now, it is a common use case
 - it is complementary to normal checkboxes, and works the same way: required attribute, validation error, and so on are supported immediately
 - implementing it yourself in your form theme is actually tricky, because of the way checkbox are handled (ie., `form_label` called inside `form_widget` with a `{ widget: parent() }`). You have to overwrite the whole fragment, otherwise you get an infinite recursion.

Finally, some screenshots and code examples.

Custom checkbox (as at the moment):
![image](https://user-images.githubusercontent.com/919405/66652982-41a1f400-ec37-11e9-813f-4b39087e89e7.png)
```php
    ->add('test', CheckboxType::class, [
        'label_attr' => [
            'class' => 'checkbox-custom',
        ],
    ])
```
Custom switch (proposed):
![image](https://user-images.githubusercontent.com/919405/66652902-1919fa00-ec37-11e9-98f3-9340b01b2335.png)
```php
    ->add('test', CheckboxType::class, [
        'label_attr' => [
            'class' => 'switch-custom',
        ],
    ])
```

Commits
-------

99f59e262f Supporting Bootstrap 4 custom switches
This commit is contained in:
Fabien Potencier 2019-11-03 12:57:04 +01:00
commit ef66ad3890
3 changed files with 8 additions and 2 deletions

View File

@ -10,6 +10,7 @@ CHANGELOG
* the `LintCommand` lints all the templates stored in all configured Twig paths if none argument is provided
* deprecated accepting STDIN implicitly when using the `lint:twig` command, use `lint:twig -` (append a dash) instead to make it explicit.
* added `--show-deprecations` option to the `lint:twig` command
* added support for Bootstrap4 switches, use `switch-custom` as `label_attr` in a `CheckboxType`
4.3.0
-----

View File

@ -166,6 +166,11 @@
<div class="custom-control custom-checkbox{{ 'checkbox-inline' in parent_label_class ? ' custom-control-inline' }}">
{{- form_label(form, null, { widget: parent() }) -}}
</div>
{%- elseif 'switch-custom' in parent_label_class -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%}
<div class="custom-control custom-switch{{ 'switch-inline' in parent_label_class ? ' custom-control-inline' }}">
{{- form_label(form, null, { widget: parent() }) -}}
</div>
{%- else -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
<div class="form-check{{ 'checkbox-inline' in parent_label_class ? ' form-check-inline' }}">
@ -238,7 +243,7 @@
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#}
{%- if widget is defined -%}
{% set is_parent_custom = parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class) %}
{% set is_custom = label_attr.class is defined and ('checkbox-custom' in label_attr.class or 'radio-custom' in label_attr.class) %}
{% set is_custom = label_attr.class is defined and ('checkbox-custom' in label_attr.class or 'radio-custom' in label_attr.class or 'switch-custom' in label_attr.class) %}
{%- if is_parent_custom or is_custom -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-control-label')|trim}) -%}
{%- else %}

View File

@ -172,7 +172,7 @@
{% block choice_label -%}
{# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #}
{%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%}
{%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': '', 'switch-custom': ''})|trim}) -%}
{{- block('form_label') -}}
{% endblock choice_label %}