landregistry / govuk-frontend-wtf Goto Github PK
View Code? Open in Web Editor NEWGOV.UK Frontend WTForms Widgets
Home Page: https://pypi.org/project/govuk-frontend-wtf/
License: MIT License
GOV.UK Frontend WTForms Widgets
Home Page: https://pypi.org/project/govuk-frontend-wtf/
License: MIT License
Describe the bug
A WTForm RadioField
(using a govuk-frontend-wtf GovRadioInput()
widget) with no field.description
renders an empty hint div.
This seems to be because map_gov_params
adds an empty hint/text string to the output params:
In turn, this is parsed by the govuk-frontend-jinja macro into an empty govukHint
component.
To Reproduce
Create a basic WTForm with a radio field.
from govuk_frontend_wtf.wtforms_widgets import GovRadioInput
from wtforms import Form, RadioField
class ExampleForm(Form):
example_radio_field = RadioField(
choices=[
("yes", "Yes"),
("no", "No"),
],
widget=GovRadioInput(),
)
Template:
{{ form.example_radio_field }}
Expected behaviour
Given the above example, I would expect no hint element to be outputted.
Actual behaviour
<div class="govuk-form-group">
<fieldset class="govuk-fieldset" aria-describedby="example_radio_field-hint">
<legend class="govuk-fieldset__legend">
Example Radio Field
</legend>
<!-- UNEXPECTED HINT ELEMENT -->
<div id="example_radio_field-hint" class="govuk-hint">
</div>
<div class="govuk-radios">
<div class="govuk-radios__item">
<input class="govuk-radios__input" id="example_radio_field" name="example_radio_field" type="radio" value="yes">
<label class="govuk-label govuk-radios__label" for="example_radio_field">
Yes
</label>
</div>
<div class="govuk-radios__item">
<input class="govuk-radios__input" id="example_radio_field-2" name="example_radio_field" type="radio" value="no">
<label class="govuk-label govuk-radios__label" for="example_radio_field-2">
No
</label>
</div>
</div>
</fieldset>
</div>
This additional hint
adds an additional 10px of vertical whitespace.
Desktop (please complete the following information):
Additional context
Seems related to 59e186e
Suggested fix is to check if field.description
exists, and only assign to the hint
param by default if it does.
GOV.UK Frontend should be upgraded from 5.1.0 to 5.4.0.
Describe the bug
The GovCheckboxInput
widget assumes that a fieldset is never used for a single checkbox. This can be useful for confirmation questions, e.g.:
Are these answers correct?
[x] I confirm that all answers are correct
To Reproduce
>>> from wtforms import BooleanField, Form
>>> from govuk_frontend_wtf.wtforms_widgets import GovCheckboxInput
>>> class MyForm(Form):
... boolean = BooleanField(widget=GovCheckboxInput())
>>> form = MyForm()
>>> form.boolean.widget.map_gov_params(form.boolean, params={"fieldset": {"legend": {"text": "mylegend"}}}, items=[])
{'name': 'boolean', 'items': [], 'hint': {'text': ''}}
Expected behavior
I would expected the supplied fieldset to be preserved:
{'name': 'boolean', 'items': [], 'hint': {'text': ''}, 'fieldset': {'legend': {'text': 'mylegend'}}}
This behaviour is due to GovCheckboxInput trying to remove the default fieldset added by its superclass, GovCheckboxesInput
.
Is your feature request related to a problem? Please describe.
When using the GovCharacterCount
you have to set the length limit in both the WTForm field validator and pass the maxlength
param to the template.
Describe the solution you'd like
Take the max length set in the validator and pass it as a default param to the template, so that developers don't have to set it twice, and risk missing or not changing one.
Describe alternatives you've considered
None other than the current approach
Additional context
The maxlength
param must always be equal to the length.max
validator.
There is currently no widget for the FormField
(https://wtforms.readthedocs.io/en/2.3.x/fields/#field-enclosures) enclosure to group form fields.
Adding one would allow you to define small, reusable FlaskForm
objects with a bunch of fields (kind of like a pattern). This should reduce duplicated code.
The initial code I produced to test this was:
from markupsafe import Markup
from wtforms.widgets.core import html_params
class GovukFieldsetWidget(object):
def __init__(self):
pass
def construct_subfield(self, subfield, field, options):
subfield_id = subfield.id.replace(field.id + field.separator, "")
subfield_options = options[subfield_id] if subfield_id in options else {}
return subfield.widget(subfield, params=subfield_options)
def __call__(self, field, **kwargs):
kwargs.setdefault("id", field.id)
options = kwargs["params"] if "params" in kwargs else {}
fieldset_options = {}
html = ["<div class='govuk-form-group'>"]
html.append("<fieldset class='govuk-fieldset' %s>" % (html_params(**fieldset_options)))
field_title = (
options["fieldset"]["legend"]["text"]
if "fieldset" in options and "legend" in options["fieldset"] and "text" in options["fieldset"]["legend"]
else field.label.text
if field.label
else field.name
if field.name
else ""
)
if field_title:
fieldset_classes = (
options["fieldset"]["legend"]["classes"]
if "fieldset" in options
and "legend" in options["fieldset"]
and "classes" in options["fieldset"]["legend"]
else ""
)
html.append("<legend class='govuk-fieldset__legend %s'>%s</legend>" % (fieldset_classes, field_title))
if hasattr(field, "task_order"):
for subfield_name in field.task_order:
subfield = field[subfield_name]
html.append(self.construct_subfield(subfield, field, options))
else:
for subfield in field:
html.append(self.construct_subfield(subfield, field, options))
html.append("</fieldset>")
html.append("</div>")
return Markup("".join(html))
You could then use the GovukFieldsetWidget
to create a group of fields as a single form where that "pattern" could be validated separately:
from flask_wtf import FlaskForm
from wtforms.fields import IntegerField, FormField, BooleanField
from GovukFieldsetWidget import GovukFieldsetWidget # see class above
from govuk_frontend_wtf.wtforms_widgets import GovCheckboxInput, GovTextInput
class ChargeAmount(FlaskForm):
class Meta:
csrf = False
task_order = ["charge_amount", "undisclosed_amount"]
charge_amount = IntegerField(
widget=GovTextInput(),
validators=[],
)
undisclosed_amount = BooleanField(widget=GovCheckboxInput())
pattern = FormField(
ChargeAmount,
widget=GovukFieldsetWidget(),
)
Describe the solution you'd like
Recreate the conditional reveal functionality available with nunjucks:
Describe the bug
The GovDateInput
widget renders the day and month fields with leading zeros, for example 02 03 2007
. This is contrary to what is recommended by the dates pattern which is to omit leading zeros.
To Reproduce
>>> from datetime import date
>>> from wtforms import DateField, Form
>>> from govuk_frontend_wtf.wtforms_widgets import GovDateInput
>>> class MyForm(Form):
... date = DateField(widget=GovDateInput())
>>> form = MyForm(data={"date": date(2007, 3, 2)})
>>> form.date.widget.map_gov_params(form.date, id="date")
{'id': 'date', 'name': 'date', 'label': {'text': 'Date'}, 'attributes': {}, 'hint': {'text': ''}, 'fieldset': {'legend': {'text': 'Date'}}, 'items': [{'label': 'Day', 'id': 'date-day', 'name': 'date', 'classes': 'govuk-input--width-2', 'value': '02'}, {'label': 'Month', 'id': 'date-month', 'name': 'date', 'classes': 'govuk-input--width-2', 'value': '03'}, {'label': 'Year', 'id': 'date-year', 'name': 'date', 'classes': 'govuk-input--width-4', 'value': '2007'}]}
Or formatted:
{
'id': 'date',
'name': 'date',
'label': {'text': 'Date'},
'attributes': {},
'hint': {'text': ''},
'fieldset': {'legend': {'text': 'Date'}},
'items': [
{'label': 'Day', 'id': 'date-day', 'name': 'date', 'classes': 'govuk-input--width-2', 'value': '02'},
{'label': 'Month', 'id': 'date-month', 'name': 'date', 'classes': 'govuk-input--width-2', 'value': '03'},
{'label': 'Year', 'id': 'date-year', 'name': 'date', 'classes': 'govuk-input--width-4', 'value': '2007'},
],
}
Expected behavior
I would expect the day and month field values not to have leading zeros:
{
...
'items': [
{'label': 'Day', 'id': 'date-day', 'name': 'date', 'classes': 'govuk-input--width-2', 'value': '2'},
{'label': 'Month', 'id': 'date-month', 'name': 'date', 'classes': 'govuk-input--width-2', 'value': '3'},
{'label': 'Year', 'id': 'date-year', 'name': 'date', 'classes': 'govuk-input--width-4', 'value': '2007'},
],
}
This behaviour is due to the format used in GovDateInput: %d %m %Y
. To omit leading zeros we can use %-d %-m %Y
, although this is platform dependent.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.