Skip to content

Commit

Permalink
Merge pull request #194 from greyli/range-field-b5
Browse files Browse the repository at this point in the history
  • Loading branch information
greyli authored Jan 12, 2022
2 parents 16f84b8 + 0e0811e commit aaf17ec
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Release date: -
parameter for ``render_form``, ``render_field``, and ``render_form_row``.
- Add ``BOOTSTRAP_FORM_INLINE_CLASSES`` config for Bootstrap 5, defaults to ``row row-cols-lg-auto g-3 align-items-center``.
Also add a ``form_inline_classes`` parameter for ``render_form``.
- Add support for WTForms range fields (``DecimalRangeField`` and ``IntegerRangeField``).


1.8.0
Expand Down
8 changes: 4 additions & 4 deletions examples/bootstrap4/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ class ExampleForm(FlaskForm):
"""An example form that contains all the supported bootstrap style form fields."""
date = DateField(description="We'll never share your email with anyone else.") # add help text with `description`
datetime = DateTimeField(render_kw={'placeholder': 'this is a placeholder'}) # add HTML attribute with `render_kw`
datetimelocal = DateTimeLocalField()
datetime_local = DateTimeLocalField()
time = TimeField()
floating = FloatField()
integer = IntegerField()
decimalslider = DecimalRangeField()
integerslider = IntegerRangeField(render_kw={'min': '0', 'max': '4'})
decimal_slider = DecimalRangeField()
integer_slider = IntegerRangeField(render_kw={'min': '0', 'max': '4'})
email = EmailField()
url = URLField()
search = SearchField()
telephone = TelField()
image = FileField(render_kw={'class': 'my-class'}, validators=[Regexp('.+\.jpg$')]) # add your class
option = RadioField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
select = SelectField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
selectmulti = SelectMultipleField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
select_multiple = SelectMultipleField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
bio = TextAreaField()
title = StringField()
secret = PasswordField()
Expand Down
8 changes: 4 additions & 4 deletions examples/bootstrap5/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ class ExampleForm(FlaskForm):
"""An example form that contains all the supported bootstrap style form fields."""
date = DateField(description="We'll never share your email with anyone else.") # add help text with `description`
datetime = DateTimeField(render_kw={'placeholder': 'this is a placeholder'}) # add HTML attribute with `render_kw`
datetimelocal = DateTimeLocalField()
datetime_local = DateTimeLocalField()
time = TimeField()
floating = FloatField()
integer = IntegerField()
decimalslider = DecimalRangeField()
integerslider = IntegerRangeField(render_kw={'min': '0', 'max': '4'})
decimal_slider = DecimalRangeField()
integer_slider = IntegerRangeField(render_kw={'min': '0', 'max': '4'})
email = EmailField()
url = URLField()
search = SearchField()
telephone = TelField()
image = FileField(render_kw={'class': 'my-class'}, validators=[Regexp('.+\.jpg$')]) # add your class
option = RadioField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
select = SelectField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
selectmulti = SelectMultipleField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
select_multiple = SelectMultipleField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
bio = TextAreaField()
title = StringField()
secret = PasswordField()
Expand Down
18 changes: 18 additions & 0 deletions flask_bootstrap/templates/bootstrap4/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@
{% else %}
{{ field(class="form-control-file%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- elif field.type in ['DecimalRangeField', 'IntegerRangeField'] -%}
{% if field.errors %}
{{ field(class="form-control-range is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-control-range%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{% else %}
{% if field.errors %}
{{ field(class="form-control mb-2 mr-sm-2 mb-sm-0 is-invalid%s" % extra_classes, **kwargs)|safe }}
Expand All @@ -172,6 +178,12 @@
{% else %}
{{ field(class="form-control-file%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- elif field.type in ['DecimalRangeField', 'IntegerRangeField'] -%}
{% if field.errors %}
{{ field(class="form-control-range is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-control-range%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{% else %}
{% if field.errors %}
{{ field(class="form-control is-invalid%s" % extra_classes, **kwargs)|safe }}
Expand Down Expand Up @@ -199,6 +211,12 @@
{% else %}
{{ field(class="form-control-file%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- elif field.type in ['DecimalRangeField', 'IntegerRangeField'] -%}
{% if field.errors %}
{{ field(class="form-control-range is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-control-range%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{% else %}
{% if field.errors %}
{{ field(class="form-control is-invalid%s" % extra_classes, **kwargs)|safe }}
Expand Down
44 changes: 34 additions & 10 deletions flask_bootstrap/templates/bootstrap5/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -146,19 +146,35 @@
{%- if field.flags.required %} required{% endif -%}">
{%- if form_type == "inline" %}
{{ field.label(class="visually-hidden")|safe }}
{% if field.errors %}
{{ field(class="form-control mb-2 mr-sm-2 mb-sm-0 is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-control mb-2 mr-sm-2 mb-sm-0%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- if field.type in ['DecimalRangeField', 'IntegerRangeField'] %}
{% if field.errors %}
{{ field(class="form-range is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-range%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- else -%}
{% if field.errors %}
{{ field(class="form-control mb-2 mr-sm-2 mb-sm-0 is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-control mb-2 mr-sm-2 mb-sm-0%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- endif %}
{% elif form_type == "horizontal" %}
{{ field.label(class="col-form-label" + (" col-%s-%s" % horizontal_columns[0:2]))|safe }}
<div class="col-{{ horizontal_columns[0] }}-{{ horizontal_columns[2] }}">
{%- if field.type in ['DecimalRangeField', 'IntegerRangeField'] %}
{% if field.errors %}
{{ field(class="form-range is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-range%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- else -%}
{% if field.errors %}
{{ field(class="form-control is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-control%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- endif %}
</div>
{%- if field.errors %}
{%- for error in field.errors %}
Expand All @@ -173,11 +189,19 @@
{%- endif %}
{%- else -%}
{{ field.label(class="form-label")|safe }}
{% if field.errors %}
{{ field(class="form-control is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-control%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- if field.type in ['DecimalRangeField', 'IntegerRangeField'] %}
{% if field.errors %}
{{ field(class="form-range is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-range%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- else -%}
{% if field.errors %}
{{ field(class="form-control is-invalid%s" % extra_classes, **kwargs)|safe }}
{% else %}
{{ field(class="form-control%s" % extra_classes, **kwargs)|safe }}
{% endif %}
{%- endif %}
{%- if field.errors %}
{%- for error in field.errors %}
<div class="invalid-feedback" style="display: block;">{{ error }}</div>
Expand Down
27 changes: 25 additions & 2 deletions tests/test_bootstrap4/test_render_form.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from flask import current_app, render_template_string
from flask_wtf import FlaskForm
from wtforms import BooleanField, FileField, MultipleFileField,\
PasswordField, RadioField, StringField, SubmitField
PasswordField, RadioField, StringField, SubmitField, IntegerRangeField,\
DecimalRangeField
from wtforms.validators import DataRequired
from flask_bootstrap import SwitchField

Expand Down Expand Up @@ -42,7 +43,7 @@ def description():


# test render SwitchField
def test_switchfield(app, client):
def test_switch_field(app, client):

class TestForm(FlaskForm):
remember = SwitchField('Remember me', description='Just check this')
Expand All @@ -62,6 +63,28 @@ def test_switch():
assert '<small class="form-text text-muted">Just check this</small>' in data


# test render IntegerRangeField and DecimalRangeField
def test_range_fields(app, client):

class TestForm(FlaskForm):
decimal_slider = DecimalRangeField()
integer_slider = IntegerRangeField(render_kw={'min': '0', 'max': '4'})

@app.route('/range')
def test_range():
form = TestForm()
return render_template_string('''
{% from 'bootstrap4/form.html' import render_form %}
{{ render_form(form) }}
''', form=form)

response = client.get('/range')
data = response.get_data(as_text=True)
assert 'Decimal Slider' in data
assert 'Integer Slider' in data
assert 'form-control-range' in data


# test WTForm fields for render_form and render_field
def test_render_form_enctype(app, client):
class SingleUploadForm(FlaskForm):
Expand Down
25 changes: 24 additions & 1 deletion tests/test_bootstrap5/test_render_form.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from flask import render_template_string
from flask_wtf import FlaskForm
from flask_bootstrap import SwitchField
from wtforms import IntegerRangeField, DecimalRangeField


def test_switchfield(app, client):
def test_switch_field(app, client):

class TestForm(FlaskForm):
remember = SwitchField('Remember me', description='Just check this')
Expand All @@ -25,6 +26,28 @@ def test_switch():
assert '<small class="form-text text-muted">Just check this</small>' in data


# test render IntegerRangeField and DecimalRangeField
def test_range_fields(app, client):

class TestForm(FlaskForm):
decimal_slider = DecimalRangeField()
integer_slider = IntegerRangeField(render_kw={'min': '0', 'max': '4'})

@app.route('/range')
def test_range():
form = TestForm()
return render_template_string('''
{% from 'bootstrap5/form.html' import render_form %}
{{ render_form(form) }}
''', form=form)

response = client.get('/range')
data = response.get_data(as_text=True)
assert 'Decimal Slider' in data
assert 'Integer Slider' in data
assert 'form-range' in data


def test_form_group_class(app, client, hello_form):
@app.route('/default')
def test_default():
Expand Down

0 comments on commit aaf17ec

Please sign in to comment.