So I have a reusable form field as select input multiple and I am filling in the options from a redux store. This works just fine as expected. But if I submit the form I will get what I was calling option.name (a players name, for example "Patrick") instead of options.id (which is the unique players key in a database). So if I happen to have two Patricks playing I will have difficulties to tell them apart later on in the game logic. Is there a way to retrieve the id instead of the name from the select input instead?
Here is the Component SelectInputMultiple.js :
import React from 'react';
import PropTypes from 'prop-types';
function SelectInputMultiple(props) {
let wrapperClass = 'form-group';
if (props.error.length > 0) {
wrapperClass += ' has-error';
}
return (
<div className={wrapperClass}>
<label htmlFor={props.id}>{props.label}</label>
<div className="field">
<select
className="form-control"
id={props.id}
multiple
onChange={props.onChange}
name={props.name}
>
{/* ID displayed for debugging purposes */}
{props.options.map(option => (
<option key={option.id}>
{option.id}: {option.name}
{option.nickname && ` (${option.nickname})`}
</option>
))}
</select>
</div>
{props.error && <div className="alert alert-danger">{props.error}</div>}
</div>
);
}
SelectInputMultiple.propTypes = {
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
options: PropTypes.array,
error: PropTypes.string
};
SelectInputMultiple.defaultProps = {
error: ''
};
export default SelectInputMultiple;
And here is the "page" which loads the Component ( gameform.js ):
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import SelectInputMultiple from '../common/SelectInputMultiple';
import SelectInput from '../common/SelectInput';
import {
games,
x01Variants,
conditions,
cricketVariants,
atcVariants,
splitscoreVariants
} from './assets';
export default class GameForm extends Component {
constructor(props) {
super(props);
this.players = props;
this.handleMultipleChange = this.handleMultipleChange.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
state = {
selectedPlayers: [],
game: 'X01',
x01variant: '501',
inCondition: 'Straight',
outCondition: 'Double',
cricketVariant: 'Cut-Throat',
atcVariant: 'Normal',
splitscoreVariant: 'Steel Dart',
errors: {}
};
formIsValid() {
const _errors = {};
if (this.state.selectedPlayers.length === 0)
_errors.selectedPlayers = 'You need to select at least one player';
this.setState({
errors: _errors
});
return Object.keys(_errors).length === 0;
}
handleChange = e => {
{
e.target.name === 'game' && this.props.onGameChange(e.target.value);
}
this.setState({
[e.target.name]: e.target.value
});
};
handleMultipleChange = e => {
let _selectedPlayers = [...e.target.options]
.filter(o => o.selected)
.map(o => o.value);
this.setState(prevState => ({
selectedPlayers: { ...prevState.selectedPlayers, _selectedPlayers }
}));
};
handleSubmit = e => {
e.preventDefault();
if (!this.formIsValid()) return;
let _game = {
selectedPlayers: this.state.selectedPlayers,
game: this.state.game,
x01Variant: this.state.x01variant,
inCondition: this.state.inCondition,
outCondition: this.state.outCondition,
cricketVariant: this.state.cricketVariant,
atcVariant: this.state.atcVariant,
splitscoreVariant: this.state.splitscoreVariant
};
this.props.onSubmit(_game);
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<SelectInputMultiple
id="players"
label="Players"
name="players"
onChange={this.handleMultipleChange}
options={this.props.players}
error={this.state.errors.selectedPlayers}
/>
<SelectInput
id="game"
label="Game Type"
name="game"
onChange={this.handleChange}
options={games}
value={this.state.game}
error={this.state.errors.game}
/>
{this.state.game === 'X01' && (
<>
<SelectInput
id="x01Variant"
label="Variant"
name="x01Variant"
onChange={this.handleChange}
options={x01Variants}
value={this.state.x01variant}
error={this.state.errors.x01Variants}
/>
<SelectInput
id="inCondition"
label="In Condition"
name="inCondition"
onChange={this.handleChange}
options={conditions}
value={this.state.inCondition}
error={this.state.errors.condition}
/>
<SelectInput
id="outCondition"
label="Out Condition"
name="outCondition"
onChange={this.handleChange}
options={conditions}
value={this.state.outCondition}
error={this.state.errors.condition}
/>
</>
)}
{this.state.game === 'Cricket' && (
<>
<SelectInput
id="cricketVariant"
label="Variant"
name="cricketVariant"
onChange={this.handleChange}
options={cricketVariants}
value={this.state.cricketVariant}
error={this.state.errors.cricketVariant}
/>
</>
)}
{this.state.game === 'Around the Clock' && (
<>
<SelectInput
id="atcVariant"
label="Variant"
name="atcVariant"
onChange={this.handleChange}
options={atcVariants}
value={this.state.atcVariant}
error={this.state.errors.atcVariants}
/>
</>
)}
{this.state.game === 'Split-Score' && (
<>
<SelectInput
id="splitscoreVariant"
label="Variant"
name="splitscoreVariant"
onChange={this.handleChange}
options={splitscoreVariants}
value={this.state.splitscoreVariant}
error={this.state.errors.splitscoreVariants}
/>
</>
)}
<input type="submit" value="Start Game" className="btn btn-primary" />
</form>
);
}
}
GameForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
onGameChange: PropTypes.func.isRequired,
players: PropTypes.array
};
Thanks in advance for any guidance into the right direction.
you can add a value attribute to the option tag like this
<option key={option.id} value={option.id}>
and in the onChange
of the select tag you can get the value as shown below
handleChange = (e) => {
console.log(e.target.value)
// remaining logic
}
Sample working codesandbox
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.