dfe-digital / govuk-formbuilder Goto Github PK
View Code? Open in Web Editor NEWA form builder for Ruby on Rails that’s compatible with the GOV.UK Design System.
Home Page: https://govuk-form-builder.netlify.app
License: MIT License
A form builder for Ruby on Rails that’s compatible with the GOV.UK Design System.
Home Page: https://govuk-form-builder.netlify.app
License: MIT License
In our service we have alot of pages which use a heading caption to give the user a better idea of which training provider they are actioning on behalf of. See GOV.UK Design System examples https://design-system.service.gov.uk/styles/typography/#headings-with-captions
Currently inputs/radios and I suspect checkboxes do no support captions or custom html inside the legend/label text. What also raises a concern is that the caption may or may not be considered part of the page heading. If it is considered as part of the heading then the span should sit inside the heading element.
If you were to consider error styling then it should also include the caption within the error group
eg:
This functionality hasn't been finalised yet so nothing will be merged until the next version of the design system has been released
It looks like prefixes and suffixes are landing in the next version of the design system.
The approach wraps the input in a div.govuk-input__wrapper
and places a span
containing the suffix/prefix accordingly:
<div class="govuk-form-group">
<label class="govuk-label" for="input-with-prefix-attribute">
Amount
</label>
<div class="govuk-input__wrapper">
<span class="govuk-input__prefix" aria-hidden="true">£</span>
<input class="govuk-input" id="input-with-prefix-attribute" name="amount" type="number">
</div>
</div>
The call should probably look something like this:
= f.govuk_number_field(:price_per_kg, label: { text: 'Price per kilogram' }, prefix_text: '£', suffix_text: 'per kg')
prefix_text
and suffix_text
keyword argument to Traits::Input
Traits::Input#input
so that
input
fieldDo we need to allow for custom attributes on the prefix and suffix in addition to the input? My gut feeling is that it's over-complicating matters for the most part. This approach can easily be extended to take prefix
and suffix
hashes if we later decide to go that route.
Now form builder configuration #73 and localisation #69 are merged into the version 1.1.0 branch, allowing for custom localisation scopes can be added should be fairly straightforward.
Currently the scope is hardcoded to:
['helpers', context, @object_name, @attribute_name].join('.')
Which expects a locales file in the following format:
helpers:
label:
person:
name: Who goes there?
cv: Tell us about your employment history
favourite_colour: What is your favourite colour?
photo: Upload a recent passport photo
fieldset:
person:
favourite_colour: To which colours are you most partial?
born_on: What is your date of birth?
projects: What do you do all day at work?
hint:
person:
name: Enter your full name including middle names, nicknames and aliases
favourite_colour: |-
Yes, there are plenty of options but please pick the one you enjoy most
cv: Where did you work? What did you do?
photo: Make sure your face is clear and you are looking at the camera
born_on: Check your birth certificate or passport
projects: If you cannot remember check with your teammates or manager
It would appear that the final two elements in the array @object_name
, and @attribute_name
would need to remain the same, but switching the beginning (in our case, helpers
and context
) should be possible.
There is an existing project that would benefit from this functionality, see this PR.
I think a quick-start guide could be useful who just want to get up and running. The Yard docs are very in-depth but without screenshots and plenty of examples they're not the most digestible format.
The MoJ form builder has a really great Rails form builder examples visual guide.
My screencast may be of use, but it's not really the right format; being unable to copy and paste examples and easily scroll through to the more-interesting parts is frustrating.
publishing-docs
to master
In a recent commit (28ffa91) I made a change that injects a novalidate
into forms created with #form_for
and #form_with
. This seems a bit heavyhanded and I'm not really happy with it.
It would seem that simply adding a formnovalidate
attribute to the submit would have the same effect.
This looks like a much easier and less-intrusive approach. Judging by the docs they seem to have the same effect, but some testing/experimentation is probably required first.
The form builder currently makes several choices on things like default label sizes, legend sizes, tags and the localisation schema (#68). There should be an option to override them so that the builder can be made to work better with a variety of projects.
Ideally the config should look something like this:
GOVUKDesignSystemFormBuilder.configure do |config|
config.default_label_size = 'm'
config.default_legend_size = 'l'
config.default_legend_tag = 'h3'
config.default_localisation_schema = %i(activerecord attributes)
config.default_submit_button_text = 'Make it so'
end
There's a bug when errors are present on fields where the label's for
attribute points at the input's non-error id rather than its with-error id. This should just be a case of adding the link_errors: true
param:
diff --git a/lib/govuk_design_system_formbuilder/elements/label.rb b/lib/govuk_design_system_formbuilder/elements/label.rb
index 15cf575..e18036f 100644
--- a/lib/govuk_design_system_formbuilder/elements/label.rb
+++ b/lib/govuk_design_system_formbuilder/elements/label.rb
@@ -29,7 +29,7 @@ module GOVUKDesignSystemFormBuilder
@attribute_name,
@text,
value: @value,
- for: field_id,
+ for: field_id(link_errors: true),
class: %w(govuk-label).push(@size_class, @weight_class, @radio_class, @checkbox_class).compact
)
end
The error summary links currently target the error message in the relevant form group. This will take the user to the right part of the page but doesn't totally comply with the GOV.UK Design System guidance and should be improved.
The suggested approach is to simply move the error_id
from the error message itself:
And place it on the relevant element. This will vary per helper:
input
elementtextarea
select
elementinput[type='checkbox']
in that groupinput[type='radio']
in that groupinput[type='file']
I'm not sure if it's possible to set the ID for individual items using Rails' built-in helpers, radios and checkboxes might make this fiddly 😞
Until this project has been legitimised and is hosted somewhere that's covered by the licence, the GOV.UK crown and Transport New font shouldn't be used.
The file upload helper is missing form the form builder.
It appears that according to the official docs, the file upload helper does not allow for hints, however they do appear in many of the backlog examples.
I would suggest that we allow them, they are really useful for specifying file types, size limits etc.
For some reason when the .travis.yml
file's Ruby version is set to 2.6.4
, linting fails.
Here's the start of the output:
Note that in the path it's referencing 2.6.0
instead of 2.6.4
(...bundle/ruby/2.6.0/gems/...
), this could be a sign something's not quite right!
$ bundle exec govuk-lint-ruby lib spec
No such file or directory @ rb_sysopen - /tmp/tmp-rubocop-all.yml20190908-16656-hircue
/home/travis/build/DFE-Digital/govuk_design_system_formbuilder/vendor/bundle/ruby/2.6.0/gems/rubocop-0.35.1/lib/rubocop/config_loader.rb:138:in `read'
/home/travis/build/DFE-Digital/govuk_design_system_formbuilder/vendor/bundle/ruby/2.6.0/gems/rubocop-0.35.1/lib/rubocop/config_loader.rb:138:in `load_yaml_configuration'
...
The command "bundle exec govuk-lint-ruby lib spec" exited with 1.
Perhaps this is just because 2.6.4
is only a week or so old, this could sort itself out with time 🤷🏽♂️
It's not clear why this has happened but it looks like this is related - now the guidance text (eg. 'You can enter up to 300 characters') must be added initially rather than automatically by JavaScript
Hi,
The GOV.UK design system says error messages should be placed after the text and above the input e.g.
However when using injected content that includes paragraphs and form elements the error message appears above them.
Note: the current code works for most situations, as fixed by #110 . But in the situation described above, the preferred error placement is not possible. Is there any way it could be updated to allow this? Hope I've described this accurately.
Including an H1 in a legend by default is not semantically correct.
When writing:
legend: { text: "Legend text" }
The following HTML is output, defaulting to using an H1 tag:
<legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
<h1 class="govuk-fieldset__heading">Legend text</h1>
</legend>
When using the official Nunjucks macro:
fieldset: {
legend: {
text: "Legend text"
}
}
The default HTML does not include an H1:
<legend class="govuk-fieldset__legend">
Legend text
</legend>
Headings only get included with the isPageHeading
flag:
Hello,
Not really sure if this is something we are doing wrong but when trying to reveal content (in this case a text area) linked to an inline radio button, the alignment looks odd.
Example (nothing selected):
Example, YES option selected (this is the option revealing the text area):
How we think it should look (please note this screenshot is when using the "old" elements form builder):
Perhaps this is a limitation of the expected new design system markup, and maybe we can't use inline radios if there is revealing content, although it would be great if possible, as it is very common to have "yes-no" questions with normally the Yes revealing a text box or text area for more details, and inline looks more pleasant in these cases.
Please let me know if you need more details. Again, this is not urgent, we are starting to use the gem and we might find some limitations we might need to workaround.
Thank you!
@tvararu kindly pointed out that the links in the guide aren't using govuk-link
so they aren't correctly displayed.
I’m trying to implement an address pattern using multiple text inputs, as described in the design system. This requires the following HTML:
<div class="govuk-form-group">
<label class="govuk-label" for="address-line-1">
Building and street <span class="govuk-visually-hidden">line 1 of 2</span>
</label>
<input class="govuk-input" id="address-line-1" name="address-line-1" type="text" autocomplete="address-line1">
</div>
Looking through the docs, I thought I could achieve this with the following:
<%= f.govuk_text_field :address_line1, autocomplete: 'address-line1', label: -> do %>
Building and street <span class="govuk-visually-hidden">line 1 of 2</span>
<% end %>
However it appears that this replaces all the content of this helper, both the label
and the text input
, whereas the documentation suggests this should only replace the content of the label
element. Am I misinterpreting the documentation, or is this a bug? /cc @tvararu
Hello,
After updating to the latest version, we've seen under certain circumstances some extraneous spaces added to the govuk-button input class, like this:
class="govuk-button " // (5 extra spaces)
Or this (when an additional class is provided):
class="govuk-button govuk-button--secondary " // (2 and 3 extra spaces)
Note this is the "raw" output from the builder. When inspecting the rendered html markup, 2 or more spaces are collapsed into 1 space, so in both examples there will just be one extra space appended to the end of the class attribute.
We think this was introduced in the recent refactoring PR as, in particular for Elements::Submit
(maybe others?) a #compact
in a collection was removed.
It is not the end of the world but as we have some tests that expect the exact markup to be generated to detect regressions, this was surfaced.
When specifying hint: { text: nil }
as per the docs, the hint text should not be rendered, but instead it falls back to the translation 'helpers.hint.{form}.{attribute_name}'
. The current workaround is to ensure the translation isn't present
The Rails helper options_for_select takes a second argument which specifies which collection item is selected, allowing us to dynamically and automatically set it depending on e.g. the user's previous selection, saving them time.
I can't see a way to achieve the same outcome using GovUK Design System Formbuilder. This means that migrating our form to GovUK Design System Formbuilder would be a regression in user experience. Does a way exist to achieve this?
The recent addition of autocomplete
attributes for date inputs marked date_of_birth: true
doesn't appear to be working and it's unclear why.
The spec isn't massively clear, but suggests that all that is required is to set day, month or year autocompletion is to set bday-day
, bday-month
and bday-year
on the inputs respectively.
This doesn't appear to work in Firefox or Chrome.
On closer reading it seems that the bday-(day|month|year)
parts are nested within bday
, so the autocomplete
should contain both keys.
The following markup appears to work for me:
<div>
<label for="dob-day">Day</label>
<input id="dob-day" name="day" autocomplete="bday bday-day">
</div>
<div>
<label for="dob-month">Month</label>
<input id="dob-month" name="month" autocomplete="bday bday-month">
</div>
<div>
<label for="dob-year">Year</label>
<input id="dob-year" name="year" autocomplete="bday bday-year">
</div>
bday
.This combination was reported as broken in the Design System by @rjlynch in DFE-Digital/govuk_elements_form_builder#29
If this is the case and the two classes aren't meant to be used in conjunction, it's probably worth at least showing a warning, or maybe blowing up with an error.
As mentioned in the comments on #153 it could be useful to allow setting classes on the <div class="govuk-form-group">
element that wraps most form controls (everything except govuk_submit
since #105).
This should work consistently across all the builder methods that construct a form group. The most straightforward approach would be to simply add a form_group_classes:
keyword arg and ensure it's passed into FormGroup
's constructor appropriately.
We could also go a stage further and take a hash (like label:
or legend:
).
This is the first time the feature has been requested, and there are definitely workarounds if you just want to style a form group in a particular way.
The require
statements at the top of govuk_design_system_form_builder.rb
are getting a little out of hand and could be replaced with something a bit smarter.
Having had a quick go at loading via Dir.glob
, it appears that the file order is more important than it should be, and there may need to be some adjustments made to the inputs
classes.
Currently the line s.add_dependency "rails", "~> 6.0.0", ">= 5.2.3"
is requiring Rails 6.0 even though the gem supports 5.2.3+.
"~> 6.0.0"
@edwardhorsford raised a good point here DFE-Digital/register-trainee-teachers#58 (comment) that form.govuk_submit
method should output a <button>
instead of <input type="submit"...>
.
There is a benefit of using the button as you can also use html inside the button which could be set using a block. by default a button inside a form should submit the form by default
As mentioned in #177, when the label
argument is passed a block instead of a proc it overwrites the entire element.
Taking a block isn't (and can't easily be) supported but the current behaviour is plain unhelpful. It's an easy mistake to make, there should be a helpful error message here instead.
label
, hint
, caption
or legend
render
, calling helpers, etc)The collection radio buttons helper covers almost all of the GOV.UK Design System spec (the only exception being the divider functionality). The fieldset approach was lifted from the govuk_elements_form_builder gem
to allow for additional HTML to be added around the radio buttons, like hints.
As our version of #collection_radio_buttons
supports hints natively and adding divider functionality would be quite straightforward, I would suggest removing the fieldset variant and extending the collection method to cover the missing functionality
#govuk_radio_buttons_fieldset
and associated tests#govuk_collection_radio_buttons
so it supports a divider_text:
param and inserts it in the penultimate spotBranding, which was added in v1.2.0
, originally had a documentation page in the guide (added in 379f42b) that detailed its use.
Branding was added specifically to support an NHS COVID19 project. Unfortunately, the NHS Design System (forked from GOV.UK) has changed the way JavaScript plugins are initialised and the following functionality doesn't work:
#govuk_text_area
character and word counts#govuk_check_box
conditional content#govuk_radio_button
conditional contentIt has recently come to my attention that there is also a Slovakian fork which appears to be much closer to GOV.UK.
The branding feature should be publicised and the documentation improved. There's no reason not to share common tools.
Hi @peteryates,
Following on from the merge of the govuk_password_field I was just wondering if you were intending to bump the gem. Minor version seems appropriate.
regards
Example with right position of error message:
Example using the gem and an injected paragraph:
The workaround at the moment is, in these cases, to not use the fieldset legend to include the header, but instead to render the header (and any content in between this and the radios) separately, and then set the legend to visually hidden.
Or, in this case in particular, to change the little paragraph to hint text. But in other scenarios, this might not work out well. Example:
Currently rails
is a requirement but the form builder only requires a small subset of it:
$ ag --only-matching --no-group --no-filename '(Active|Action)\w+' | sort | uniq
ActionController
ActionView
ActiveModel
ActiveSupport
Investigate slimming down the requirements so only the necessary parts of Rails are included in the gemspec
Currently all of the helpers require that the text that's passed in to form labels, hints and legends is supplied inline. Many projects prefer to store the text in the locales files and use Rails' i18n to populate the relevant strings.
There's a working implementation in the GOV.UK elements form builder that can be used for inspiration.
text_method:
and :hint_method
which probably already do everything that's required 🤔label: { text: I18n.t('my.favourite.type.of.pasta') }
perhaps label: { t: 'my.favourite.type.of.pasta' }
? 🤷🏽♂️Related to: DFE-Digital/apply-for-teacher-training#3237 (comment)
We've built a couple of forms that look like this:
<%= form_with model: @user do |f| %>
<%= f.govuk_check_box :admin, true %>
<%= f.govuk_submit 'Save' %>
<% end %>
A form like this will submit params[:user][:admin] == "true"
- a string, not a boolean.
Then, when you assign this value like @user.admin = params[:user][:admin]
and render the form again, your checkbox will be unchecked, because it compares "true"
to true
.
<%= form_with model: User.new(admin: "true") do |f| %>
<%= f.govuk_check_box :admin, true %>
<%= f.govuk_submit 'Save' %>
<% end %>
Setting the govuk_check_box
value to any other value will work - even nil
because the value
will be "on"
.
<%= form_with model: User.new(admin: "on") do |f| %>
<%= f.govuk_check_box :admin, nil %>
<%= f.govuk_submit 'Save' %>
<% end %>
I think we could compare the stringified version of the value
to make this work out of the box? Otherwise, would raising an error be good?
The behaviour of legends and labels differs in that
In every case except for standalone fieldsets the fieldset (and the legend) will be associated with a attribute. Perhaps it would make more sense to use it rather than just omitting the legend.
= form_with(model: widget) do |form|
= form.govuk_text_field :name,
caption: { text: %(Name caption), size: %(m) }
= form.govuk_date_field :created_at,
caption: { text: %(Created on caption), size: %(m) }
The label's caption appears alone, the legend's isn't rendered at all
= form_with(model: widget) do |form|
= form.govuk_text_field :name,
label: { tag: %(h3), size: %(l) },
caption: { text: %(Name caption), size: %(m) }
= form.govuk_date_field :created_at,
legend: { text: %(Created on), size: %(l) },
caption: { text: %(Created on caption), size: %(m) }
Both the label and legend captions are visible
Is the current behaviour unpredictable? Is it correct? Feedback welcome. Thanks @rjlynch for reporting this.
Investigate and find out which the DfE's favoured CI provider is and integrate. It used to be Travis but I'm not sure what's recommended now. The CI should run both the lint and the specs.
Don't forget to add the green badges to the README.md
!
Hello! Our service has date fields that look like this:
It would be nice if the date field component allowed this pattern.
Currently we still use it but we hide the day field using display: none
in CSS. This has the downside of breaking the link from the error summary (because it points to the day field).
Currently, when max_chars
or max_words
is specified, the total allowed number is always displayed. When used in conjunction with threshold
(which displays a warning when the limit is approached), the total is pushed down a line
It probably makes more sense to either hide the total altogether when threshold
is specified or separately allow it to be manually toggled. Or both.
aria-describedby
are in placeA recent bug #178 that caused content to be rendered multiple times should have been caught in tests but wasn't. It happens when using a templating layer, like in Rails, but not when using the library directly via Ruby.
It might be worth creating a smaller set of tests that render template files using Slim or ERB and ensure the content is as it seems.
See the docs for #govuk_error_summary
, the incorrect @todo
tag contains text beginning with
Currently the summary anchors link to the inline error messages
This has been incorrect for some time and should be removed
If there is an error that can't be attributed to a specific field, the link for the error will be of the form #object-base-field-error
, for which there is no element with that id on the page. In this case I think the form should add this id to the first input field in the form, or to the form itself.
Currently it appears that when creating a single check box the hidden field that should be rendered automatically by the Rails #check_box
helper we're wrapping isn't present in the output.
I'm not sure why this happens, if there's a good reason it's not (and not just a misconfiguration bug) then it's probably a good idea to add the hidden field in this library when multiple: false
.
Currently this is kind of mitigated by a note in the guide, but that can definitely be improved 😅
= f.govuk_check_box(:awesome, true, multiple: false, label: -> { 'Awesome?' })
<div class="govuk-checkboxes__item">
<input id="person-awesome-true-field" class="govuk-checkboxes__input" type="checkbox" value="true" checked="checked" name="person[awesome]">
<label for="person-awesome-true-field" class="govuk-label govuk-checkboxes__label">Awesome?</label>
</div>
Version 3.6.0 of the frontend has been released. Based on the release notes it doesn't look like the form builder needs any new behaviour.
One area that might need addressing is that now the guidance now specifies that number inputs should use inputmode
and pattern
instead of type="number"
. However, that can already be achieved using the govuk_text_field
and supplying the extra params manually.
Open to suggestion on this, but for the time being I think I'll leave it as is.
It's clear that when people are using #govuk_radio_buttons_fieldset
and #govuk_check_boxes_fieldset
often the link_errors
argument is forgotten for the first radio button or check box.
It is important because it makes the linking from #govuk_error_summary
work.
Due to the nature of the builder, no element is 'aware' of its container(s) or sibling elements so creating a warning when link_elements
is omitted might be difficult. Other than making it more obvious in the documentation, I'm not sure what can be done.
link_errors
is supplied to a fieldsetHi @peteryates, this is great stuff and was looking to implement in a product I am working on over in MoJ.
One problem is you cannot use it against a plain ruby class due to the lack of errors
on the object. I am just looking to create a basic search form with options.
I could monkey patch this or create a dummy errors
method to patch this app-side but think it could be beneficial generally. I have a branch that I have it working in (with tests) but cannot push it - receive a 403
.
As per GOV.UK Design System, it would be nice to support the service start button in the FormBuilder.
I will find some time to work on this soon hopefully, but anybody feel free to make a start in the meantime.
Should the docs include a legend HTML tag here, or should the code be inserting one automatically?
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.