Skip to content
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

Improve a11y in form example #1917

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ffea9af
Improve a11y in form example
MewenLeHo Mar 22, 2023
39562f9
Fix js
MewenLeHo Mar 22, 2023
c52754c
Fix prefer-template
MewenLeHo Mar 22, 2023
e0084f7
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Mar 27, 2023
754860b
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Mar 27, 2023
be325a6
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Mar 27, 2023
4f61888
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Mar 29, 2023
36fd5a9
Js improvement
MewenLeHo Mar 29, 2023
577a726
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Mar 29, 2023
92eaed6
Add role alert
MewenLeHo Mar 29, 2023
1f025f6
Fix markup
MewenLeHo Mar 30, 2023
27befc7
Improve Js performance
MewenLeHo Mar 31, 2023
b1f35e5
Fix
MewenLeHo Apr 3, 2023
fcc5cb2
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Apr 3, 2023
bb490e3
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Apr 5, 2023
3c76a78
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Apr 12, 2023
6d2aed1
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Apr 26, 2023
79a338b
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo May 10, 2023
4543bc8
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo May 22, 2023
728cde9
Merge branch 'main' into main-mlh-update-a11y-form-example
MewenLeHo Aug 7, 2023
40037e2
Merge branch 'main' into main-mlh-update-a11y-form-example
louismaximepiton Jan 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions site/content/docs/5.3/examples/form/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@
// Focus on first error
const invalidItems = form.querySelectorAll(':invalid')
invalidItems[0].focus()
// Add the id of the corresponding invalid message to each invalid field
invalidItems.forEach(element => {
const linkedLabel = element.getAttribute('aria-labelledby')
const closestInvalidFeedback = element.closest('.mb-3').querySelector('.invalid-feedback').getAttribute('id')
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const closestInvalidFeedback = element.closest('.mb-3').querySelector('.invalid-feedback').getAttribute('id')
const closestInvalidFeedback = element.parentElement.querySelectorAll('.invalid-feedback')

My point above but just recalling it here, We should have a way to display several feedbacks if needed.

Copy link
Contributor Author

@MewenLeHo MewenLeHo Apr 3, 2023

Choose a reason for hiding this comment

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

What happen when a field has multiple invalid feeddbacks will be discussed in the next specs meeting.

const valuesArray = [linkedLabel, closestInvalidFeedback].join(' ')
louismaximepiton marked this conversation as resolved.
Show resolved Hide resolved
element.setAttribute('aria-labelledby', valuesArray)
})
// Remove the id of the corresponding invalid message to each valid field
const validItems = form.querySelectorAll(':valid:not([type=\'submit\'])')
louismaximepiton marked this conversation as resolved.
Show resolved Hide resolved
validItems.forEach(element => {
const closestLabel = element.closest('.mb-3').querySelector('.form-label').getAttribute('id')
louismaximepiton marked this conversation as resolved.
Show resolved Hide resolved
element.setAttribute('aria-labelledby', closestLabel)
})
}

form.classList.add('was-validated')
Expand Down
36 changes: 18 additions & 18 deletions site/content/docs/5.3/examples/form/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ <h1 class="display-1">Become a reseller</h1>
</div>
<div class="col-sm-4 col-md-6 mb-3">
<label for="selectTitle" id="selectTitleLabel" class="form-label is-required">Title</label>
<select class="form-select" id="selectTitle" aria-labelledby="selectTitleLabel selectTitleFeedback" autocomplete="sex" required>
<select class="form-select" id="selectTitle" aria-labelledby="selectTitleLabel" autocomplete="sex" required>
<option selected disabled value="" aria-hidden="true">Select a title</option>
<option value="1">Miss</option>
<option value="2">Mr.</option>
Expand All @@ -105,44 +105,44 @@ <h1 class="display-1">Become a reseller</h1>
<div class="valid-feedback">
Looks good!
</div>
<div id="selectTitleFeedback" class="invalid-feedback">
<div id="selectTitleFeedback" class="invalid-feedback" role="alert">
Please select a valid title.
</div>
</div>
<div class="col-12">
<div class="mb-3">
<label for="firstName" id="firstNameLabel" class="form-label is-required">First name</label>
<input type="text" class="form-control" id="firstName" aria-labelledby="firstNameLabel firstNameFeedback" autocomplete="given-name" required>
<input type="text" class="form-control" id="firstName" aria-labelledby="firstNameLabel" autocomplete="given-name" required>
<div class="valid-feedback">
Looks good!
</div>
<div id="firstNameFeedback" class="invalid-feedback">
<div id="firstNameFeedback" class="invalid-feedback" role="alert">
Please enter a valid first name.
</div>
</div>
<div class="mb-3">
<label for="lastName" id="lastNameLabel" class="form-label is-required">Last name</label>
<input type="text" class="form-control" id="lastName" aria-labelledby="lastNameLabel lastNameFeedback" autocomplete="family-name" required>
<input type="text" class="form-control" id="lastName" aria-labelledby="lastNameLabel" autocomplete="family-name" required>
<div class="valid-feedback">
Looks good!
</div>
<div id="lastNameFeedback" class="invalid-feedback">
<div id="lastNameFeedback" class="invalid-feedback" role="alert">
Please enter a valid last name.
</div>
</div>
<div class="mb-3">
<label for="email" id="emailLabel" class="form-label is-required">Email</label>
<input type="email" class="form-control" id="email" aria-labelledby="emailLabel emailFeedback" autocomplete="email" required>
<input type="email" class="form-control" id="email" aria-labelledby="emailLabel" autocomplete="email" required>
<div class="valid-feedback">
Looks good!
</div>
<div id="emailFeedback" class="invalid-feedback">
<div id="emailFeedback" class="invalid-feedback" role="alert">
Please provide a valid email.
</div>
</div>
<div class="mb-3">
<label for="country" id="countryLabel" class="form-label is-required">Country</label>
<select class="form-select" id="country" aria-labelledby="countryLabel countryFeedback" autocomplete="country-name" required>
<select class="form-select" id="country" aria-labelledby="countryLabel" autocomplete="country-name" required>
<option selected disabled value="" aria-hidden="true">Select a country</option>
<option value="1">Australia</option>
<option value="2">Canada</option>
Expand All @@ -152,23 +152,23 @@ <h1 class="display-1">Become a reseller</h1>
<div class="valid-feedback">
Looks good!
</div>
<div id="countryFeedback" class="invalid-feedback">
<div id="countryFeedback" class="invalid-feedback" role="alert">
Please select a valid country.
</div>
</div>
<div class="mb-3">
<label for="company" id="companyLabel" class="form-label is-required">Name of company</label>
<input type="text" class="form-control" id="company" aria-labelledby="companyLabel companyFeedback" required>
<input type="text" class="form-control" id="company" aria-labelledby="companyLabel" required>
<div class="valid-feedback">
Looks good!
</div>
<div id="companyFeedback" class="invalid-feedback">
<div id="companyFeedback" class="invalid-feedback" role="alert">
Please enter a valid company name.
</div>
</div>
<div class="mb-3">
<label for="business" id="businessLabel" class="form-label is-required">Business type</label>
<select class="form-select" id="business" aria-labelledby="businessLabel businessFeedback" required>
<select class="form-select" id="business" aria-labelledby="businessLabel" required>
<option selected disabled value="" aria-hidden="true">Select a type</option>
<option value="1">Corporation</option>
<option value="2">Limited liability company</option>
Expand All @@ -178,17 +178,17 @@ <h1 class="display-1">Become a reseller</h1>
<div class="valid-feedback">
Looks good!
</div>
<div id="businessFeedback" class="invalid-feedback">
<div id="businessFeedback" class="invalid-feedback" role="alert">
Please select a valid business type.
</div>
</div>
<div class="mb-3">
<label for="website" id="websiteLabel" class="form-label">Website</label>
<input type="text" class="form-control" id="website" aria-labelledby="websiteLabel websiteFeedback">
<input type="text" class="form-control" id="website" aria-labelledby="websiteLabel">
<div class="valid-feedback">
Looks good!
</div>
<div id="websiteFeedback" class="invalid-feedback">
<div id="websiteFeedback" class="invalid-feedback" role="alert">
Please enter a valid website.
</div>
</div>
Expand All @@ -197,11 +197,11 @@ <h1 class="display-1">Become a reseller</h1>
<button type="button" class="form-helper" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Help for text area">
<span class="visually-hidden">Helper for text area</span>
</button>
<textarea class="form-control" id="message" rows="5" placeholder="Describe your business and your motivation in becoming an Orange reseller" aria-labelledby="messageLabel messageFeedback" required></textarea>
<textarea class="form-control" id="message" rows="5" placeholder="Describe your business and your motivation in becoming an Orange reseller" aria-labelledby="messageLabel" required></textarea>
<div class="valid-feedback">
Looks good!
</div>
<div id="messageFeedback" class="invalid-feedback">
<div id="messageFeedback" class="invalid-feedback" role="alert">
Copy link
Member

Choose a reason for hiding this comment

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

We should add the role="alert" in the doc as well as in the migration guide.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's one of the point Vincent and I want to bring to the next specs meeting.
But it will probably be on Bootstrap's side first.

Copy link
Member

Choose a reason for hiding this comment

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

Ah yes you're right, Bs first for documentation!

Please enter a valid message.
</div>
</div>
Expand Down