Skip to content

[Form] Add Bootstrap 4 style for field FileType #26502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from

Conversation

zzenmate
Copy link

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #26464
License MIT
Doc PR symfony/symfony-docs#...

@zzenmate zzenmate changed the title [WIP] [Form] Add Bootstrap 4 style for field FileType [Form] Add Bootstrap 4 style for field FileType Mar 13, 2018
@@ -257,6 +267,14 @@
</{{ element|default('div') }}>
{%- endblock form_row %}

{% block file_row -%}
<{{ element|default('div') }} class="form-group custom-file">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to docs and the provided example, form-group class is not needed.

{% block file_row -%}
<{{ element|default('div') }} class="form-group custom-file">
{{- form_label(form) -}}
{{- form_widget(form) -}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The label should be after widget

@nicolas-grekas nicolas-grekas added this to the 4.1 milestone Mar 14, 2018
@zzenmate
Copy link
Author

I added the most basic block for file_label and file_widget for overriding form-control-label, form-control-file and using custom-file-input, custom-file-label.

@@ -182,7 +182,7 @@

{% block file_widget -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-file-input')|trim}) -%}
{{- block('form_widget_simple') }}
{{ block("form_widget_simple", "form_div_layout.html.twig") }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double quotes

@@ -182,7 +182,7 @@

{% block file_widget -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-file-input')|trim}) -%}
{{- block('form_widget_simple') }}
{{ block("form_widget_simple", "form_div_layout.html.twig") }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you remove the "No leading/trailing whitespace"?
Also double quotes should be single quotes

@@ -252,7 +252,7 @@

{% block file_label -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-file-label')|trim}) -%}
{{- block('form_label') -}}
{{ block("form_label", "form_div_layout.html.twig") }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, leading/trailing whitespace and double quotes

Copy link
Member

@javiereguiluz javiereguiluz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good to me, but @Nyholm and @mpiot have more experience with this Bootstrap form theme and could review it too. Thanks!

@@ -180,6 +180,11 @@
</div>
{%- endblock choice_widget_expanded %}

{% block file_widget -%}
Copy link
Contributor

@mpiot mpiot Mar 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the form_simple_widget there is a test on the type of form, if it's a file, it change the class. Adapt it is a better idea than do this block, no ?

{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control' ~ (type|default('') == 'file' ? '-file' : ''))|trim}) -%}

Do it:

{%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? 'custom-file-input' : 'form-control'))|trim}) -%}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@mpiot
Copy link
Contributor

mpiot commented Mar 16, 2018

We try to put errors in the label to respect a standard for blind people, but I think it's difficult in this case.. Because the label is directly in the field. I look if there is a way to do it.

@@ -257,6 +267,14 @@
</{{ element|default('div') }}>
{%- endblock form_row %}

{% block file_row -%}
<{{ element|default('div') }} class="custom-file">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In your case the element is the div, maybe use

directly in place of element ? And you should add a <div class="input-group mb-3"> or a simple form-group or at least the mb-3 to add a margin after the row.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't custom-file-label add a margin-bottom? (.5rem to be exactly)

Copy link
Contributor

@mpiot mpiot Mar 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've try and it's collapsed. In the bootstrap doc, they encapsulate the custom-file-label in an other div with a mb-3 to add the margin bottom, because they use input-group class to add many buttons. In our case, we can use the form-group that add the mb-3 (maybe colloration when fail ?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add a div with class "form-group" around this.

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. I just tested this and it looks okey. I added a few comments.

@@ -257,6 +267,14 @@
</{{ element|default('div') }}>
{%- endblock form_row %}

{% block file_row -%}
<{{ element|default('div') }} class="custom-file">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add a div with class "form-group" around this.

@@ -180,6 +180,11 @@
</div>
{%- endblock choice_widget_expanded %}

{% block file_widget -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-file-input')|trim}) -%}
{{- block('form_widget_simple', 'form_div_layout.html.twig') -}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should remove 'form_div_layout.html.twig'. Or maybe Im missing something. Why did you add it here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use form_div_layout.html.twig from form_widget_simple for overriding form_widget_simple from bootstrap_4_layout.html.twig.
Because we don't need merge .form-control-file with .custom-file-input.
I think we will need use only one class. And it will be .custom-file-input.
In documention used only .custom-file-input
Or am I wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... Okey. Why are we adding form-control-file. Is that ever needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://getbootstrap.com/docs/4.0/components/input-group/#custom-file-input
In this example, we also not used form-control-file or form-control-label.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excuse my ignorance. But in what scenario/input do we need form-control-file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block can be removed if you apply the solution specified before: edit the form_simple_widget. Your solution remove the way to use the previous possibilities to display file input, the only way become the custom way.

Then, just edit the part where we set the .form-control-file in place of .form-control, I've write the code to replace on the top. You just need to edit a line in the block form_simple_widget and remove this block.

I regive you the line of code:

In the form_simple_widget block there is:

{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control' ~ (type|default('') == 'file' ? '-file' : ''))|trim}) -%}

Replace by this line:

{%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? 'custom-file-input' : 'form-control'))|trim}) -%}

Then, if the type is a file the attr become custom-file-input in place of form-control. The code is already ok, you just have to adapt it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need form-control-file for adding: "display: block; width: 100%;".
But, I am don't know if we need to use it in this case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the demo they write it:

<div class="input-group mb-3">
  <div class="custom-file">
    <input type="file" class="custom-file-input" id="inputGroupFile02">
    <label class="custom-file-label" for="inputGroupFile02">Choose file</label>
  </div>
</div>

The input just have the class custom-file-input, this is what do the line:

{%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? 'custom-file-input' : 'form-control'))|trim}) -%}

@@ -180,6 +180,11 @@
</div>
{%- endblock choice_widget_expanded %}

{% block file_widget -%}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -245,6 +250,11 @@
{%- endif -%}
{%- endblock checkbox_radio_label %}

{% block file_label -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-file-label')|trim}) -%}
{{- block('form_label', 'form_div_layout.html.twig') -}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you use form_div_layout.html.twig to avoid errors in the label?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I wrote on top, we don't need to merge 2 class: "custom-file-label" and "form-control-label".
Or am I wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im not sure. Ill check later tonight

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case is it not better to replace (replace filter) an existing class in place of do a double override on the block ? Because if we extend a file, that extend a file, each file override a block, and finally we re-override the block again, it's more difficult to understand what we do, no ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. But, How to get input type in form_label for write logic with if.
I mean something like that:

{% if type == 'file' %} custom-file-label {% else %} form-control-label {% endif %}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in the block form_label, you can add this:

{% elseif type is defined and type == 'file' %}
    {%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' custom-file-label')|trim}) -%}

To obtain:

{%- if compound is defined and compound -%}
    {%- set element = 'legend' -%}
    {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%}
{% elseif type is defined and type == 'file' %}
    {%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' custom-file-label')|trim}) -%}
{%- else -%}
    {%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
{%- endif -%}

Then, you can remove your the block file_label. Keep the type is defined test, because it appears that it is not always defined.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, and then you need to change something fo errors, because by using our form_label, you have the errors displayed in it.

I've try, and if you remove the error handling in your file_row, error are displayed semi-correctly... But I think it's ok.

In this case, you can both: use your file_row, or add a check on type == file in the form_row. I think it's more readable with your way, but we re-write code, for it, do as you wish :-) But you need to remove the form_error from the file_row since you use our form_label to avoid error duplication.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mpiot Thank you for your help.

@zzenmate
Copy link
Author

status: needs review

@Nyholm
Copy link
Member

Nyholm commented Mar 20, 2018

There are still some work. Please see #26502 (comment)

@@ -180,6 +180,11 @@
</div>
{%- endblock choice_widget_expanded %}

{% block file_widget -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-file-input')|trim}) -%}
{{- block('form_widget_simple', 'form_div_layout.html.twig') -}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block can be removed if you apply the solution specified before: edit the form_simple_widget. Your solution remove the way to use the previous possibilities to display file input, the only way become the custom way.

Then, just edit the part where we set the .form-control-file in place of .form-control, I've write the code to replace on the top. You just need to edit a line in the block form_simple_widget and remove this block.

I regive you the line of code:

In the form_simple_widget block there is:

{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control' ~ (type|default('') == 'file' ? '-file' : ''))|trim}) -%}

Replace by this line:

{%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? 'custom-file-input' : 'form-control'))|trim}) -%}

Then, if the type is a file the attr become custom-file-input in place of form-control. The code is already ok, you just have to adapt it.

@@ -245,6 +250,11 @@
{%- endif -%}
{%- endblock checkbox_radio_label %}

{% block file_label -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-file-label')|trim}) -%}
{{- block('form_label', 'form_div_layout.html.twig') -}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case is it not better to replace (replace filter) an existing class in place of do a double override on the block ? Because if we extend a file, that extend a file, each file override a block, and finally we re-override the block again, it's more difficult to understand what we do, no ?

@@ -257,6 +267,16 @@
</{{ element|default('div') }}>
{%- endblock form_row %}

{% block file_row -%}
<{{ element|default('div') }} class="form-group">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case the element can't be another thing than a div element, maybe it's better to directly write div in place of use the element var ? It works like it, it's just a question/suggestion. ;-)

@zzenmate
Copy link
Author

status: needs review

Copy link
Contributor

@mpiot mpiot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems all is ok, thanks for your help :-)

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good. Just a super minor

@@ -117,7 +117,7 @@

{% block form_widget_simple -%}
{% if type is not defined or type != 'hidden' %}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control' ~ (type|default('') == 'file' ? '-file' : ''))|trim}) -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? ' custom-file-input' : ' form-control'))|trim}) -%}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need a space here.

“ file”

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A space ? It's a test on the type of the form, why add a space before ? It can't match if we add it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you are correct. It is the value that should have space and they do.

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this PR.

im 👍

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong button :/

Im 👍

@fabpot
Copy link
Member

fabpot commented Mar 27, 2018

Thank you @zzenmate.

@fabpot fabpot closed this Mar 27, 2018
fabpot added a commit that referenced this pull request Mar 27, 2018
This PR was squashed before being merged into the 4.1-dev branch (closes #26502).

Discussion
----------

[Form] Add Bootstrap 4 style for field FileType

| Q             | A
| ------------- | ---
| Branch?       | master<!-- see below -->
| Bug fix?      | no
| New feature?  | yes <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | #26464   <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | symfony/symfony-docs#... <!-- required for new features -->

<!--
Write a short README entry for your feature/bugfix here (replace this comment block.)
This will help people understand your PR and can be used as a start of the Doc PR.
Additionally:
 - Bug fixes must be submitted against the lowest branch where they apply
   (lowest branches are regularly merged to upper ones so they get the fixes too).
 - Features and deprecations must be submitted against the master branch.
-->

Commits
-------

df57718 [Form] Add Bootstrap 4 style for field FileType
@zzenmate zzenmate deleted the bootstrap-file branch March 27, 2018 07:33
@fabpot fabpot mentioned this pull request May 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants