Open lydell opened 5 years ago
wondering for the same exact issue, how do we use the "for" attribute with the "Field" component?
First issue I hit when I came to final-form. Is there a way to "auto-id" and set the "for" to be that?
What I did was useMemo
with an empty array so it never recalculates the id - https://stackoverflow.com/q/55309140/1828637
I don't like it. I hoped that the form lib would take care of this for us.
import React, { useMemo } from 'react';
import { Form, Field } from 'react-final-form';
import { uniqueId } from 'lodash';
function TaskForm() {
const id = useMemo(() => uniqueId('_form'), []);
const getFor = name => name + id;
return (
<>
<h3>Create a task</h3>
<Form onSubmit={onSubmit}>
{({ handleSubmit, pristine, invalid, ...rest }) => {(
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor={getFor('firstName')}>First Name</label>
<Field name="firstName" id={getFor('firstName')} component="input" placeholder="First Name" />
</div>
<button type="submit" disabled={pristine || invalid}>Submit</button>
</form>
)}}
</Form>
</>
);
}
If possible in your case, I find it the easiest to nest the input inside the <label>
element – no need for IDs.
@lydell Oh wow thank you very much. Is this a standard approach? I never knew about it.
Gosh, bootstrap styles are expecting my label be separate. :(
Yes, it's standard.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label
To associate the
<label>
with an<input>
element, you need to give the<input>
an id attribute. The<label>
then needs a for attribute whose value is the same as the input's id.Alternatively, you can nest the
<input>
directly inside the<label>
, in which case thefor
andid
attributes are not needed because the association is implicit
In the example in the readme, as well as some (all?) codesandbox examples (such as https://codesandbox.io/s/yk1zx56y5j), use markup like this:
But that doesn't connect the label to the field. Most notably, it's not possible to click the label text to focus the field. And I guess screen readers won't announce what the fields are for.
To connect a label to a field, you can either use IDs:
Or nesting (might require slightly changing styles):
People often copy-paste from examples, so I think it would be nice if they don’t include this mistake.
Thanks!
(This is probably a good first issue for aspiring contributors.)