Reputation: 115
I have created a React component using redux-form and am looking to autoFocus on the first field. The fields are created by looping through an object and creating a field for each item in that object. When I use autoFocus in the JSX is autoFocuses on the last field in the form (which makes sense).
Does anyone know how I can autoFocus on the first field in the form?
Here is my component:
import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
class BalanceForm extends Component {
constructor(props) {
super(props);
this.submitForm = this.submitForm.bind(this);
this.cancel = this.cancel.bind(this);
}
cancel() {
//not relevant
}
submitForm(e, values) {
//not relevant
}
render() {
return (
<div>
{this.props.balanceFormVisible &&
<div className="modal-background">
<div className="modal">
<form onSubmit={this.submitForm}>
{Object.keys(this.props.accounts).map((key) => {
return (
this.props.accounts[key].visible &&
<div key={this.props.accounts[key].name}>
<label className="form-label" htmlFor={this.props.accounts[key].name}>
{this.props.accounts[key].display}
</label>
<Field
name={this.props.accounts[key].name}
component="input"
type="number"
placeholder=""
autoFocus
/>
</div>
)
})}
<button type="submit">Submit</button>
<button onClick={ this.cancel } className="cancelbtn" >Cancel</button>
</form>
</div>
</div>
}
</div>
);
}
}
BalanceForm = reduxForm({form: 'balance'})(BalanceForm)
export default BalanceForm;
Thanks in advance :)
Upvotes: 5
Views: 4420
Reputation: 33
I ran into an issue where autoFocus
wasn't properly passing down from Field to the underlying component. Had to explicitly pass autoFocus
in the props
prop for Field.
Upvotes: 0
Reputation: 41
Some of these either didn't compile or are a bit verbose. This worked for me:
{Object.keys(item)
.map((key, i) =>
<div className={`form-row ${key}`} key={key}>
<label>{key}</label>
<input value={item[key]}
type='text'
onChange={e => {
this._updateValue(key, e.target.value);
}}
autoFocus={i === 0}
/>
</div>
)}
Upvotes: 2
Reputation: 570
Alternatively, if you hook in to ComponentDidMount, you can ask the DOM to focus the first existing field within the form.
Add a ref to the form
<form onSubmit={this.submitForm} ref='form'>
Use the ref to focus the element after mounting
componentDidMount() {
const firstInput = this.refs.form.querySelector('input')[0];
firstInput && firstInput.focus();
}
Upvotes: 1
Reputation: 115
Solution to this was to conditionally render the form field. Thanks to Alexander Borodin for the inspiration...
{Object.keys(this.props.accounts).map((key, i) => {
console.log(key, i)
return (
this.props.accounts[key].visible &&
<div key={this.props.accounts[key].name}>
<label className="form-label" htmlFor={this.props.accounts[key].name}>
{this.props.accounts[key].display}
</label>
{(i === 0) ? (
<Field
name={this.props.accounts[key].name}
component="input"
type="number"
placeholder=""
autoFocus
/>
) : (
<Field
name={this.props.accounts[key].name}
component="input"
type="number"
placeholder=""
/>
)}
</div>
)
})}
Upvotes: 3
Reputation: 2034
Try this:
{Object.keys(this.props.accounts).map((key, i) => {
return (
this.props.accounts[key].visible &&
<div key={this.props.accounts[key].name}>
<label className="form-label" htmlFor={this.props.accounts[key].name}>
{this.props.accounts[key].display}
</label>
<Field
name={this.props.accounts[key].name}
component="input"
type="number"
placeholder=""
{ (i === 0) ? 'autoFocus': ''}
/>
</div>
)
})}
Upvotes: 0