diff --git a/CHANGES.rst b/CHANGES.rst index edfc3faa..e00fef95 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -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 diff --git a/examples/bootstrap4/app.py b/examples/bootstrap4/app.py index 68a14021..37c46685 100644 --- a/examples/bootstrap4/app.py +++ b/examples/bootstrap4/app.py @@ -32,12 +32,12 @@ 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() @@ -45,7 +45,7 @@ class ExampleForm(FlaskForm): 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() diff --git a/examples/bootstrap5/app.py b/examples/bootstrap5/app.py index 96aec6f6..b7422632 100644 --- a/examples/bootstrap5/app.py +++ b/examples/bootstrap5/app.py @@ -32,12 +32,12 @@ 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() @@ -45,7 +45,7 @@ class ExampleForm(FlaskForm): 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() diff --git a/flask_bootstrap/templates/bootstrap4/form.html b/flask_bootstrap/templates/bootstrap4/form.html index 8295aedb..5e3f1e1b 100644 --- a/flask_bootstrap/templates/bootstrap4/form.html +++ b/flask_bootstrap/templates/bootstrap4/form.html @@ -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 }} @@ -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 }} @@ -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 }} diff --git a/flask_bootstrap/templates/bootstrap5/form.html b/flask_bootstrap/templates/bootstrap5/form.html index feba1310..fce44d26 100644 --- a/flask_bootstrap/templates/bootstrap5/form.html +++ b/flask_bootstrap/templates/bootstrap5/form.html @@ -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 }}