简体   繁体   中英

Retrieve option.id instead of option.name in select input

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM