3

I have a component which renders Input type='select': (I am using reactstrap)

import React, {Component} from 'react'
import {
    Form,
    FormGroup,
    Input,
    Button,
    Col,
} from 'reactstrap'
import {
    withRouter,
} from 'react-router'
import Context from '../../../../../provider'

class NewPost extends Component {
    constructor(props) {
        super(props)
        this.state = {
            subreddits: [],
            subreddit_selected: '',
            subreddit_id: 0,
            ...
        }
        this.handleSubredditSelect = this.handleSubredditSelect.bind(this)
    }

    componentDidMount() {
        fetch('/api/reddit/r/')
        .then(data => data.json())
        .then(json => {
            this.setState({
                subreddits: json,
                ...
            })
        })
    }

    handleSubredditSelect(event) {
        console.log('selected id: ',event.target.id)
        this.setState({
            subreddit_selected: event.target.value,
            subreddit_id: event.target.id,
        }, () => 
            this.props.history.push(`/${this.state.subreddit_selected}/new/`)
        )
    }

    ...

    render() {
        return (
            <Context.Consumer>
                {context => {
                    return (
                        <React.Fragment>
                            <Form
                                ...
                            >
                                <FormGroup row>
                                    <Col sm={7}>
                                        <Input 
                                            type="select"
                                            onChange={this.handleSubredditSelect}
                                            required
                                        > 
                                            <option key='0' disabled selected>Select an Option</option>
                                            {this.state.subreddits.map((subreddit) => {
                                                return (
                                                    <option key={subreddit.id} id={subreddit.id}>{'r/' + subreddit.name}</option>
                                                )
                                            })}
                                        </Input>
                                    </Col>
                                </FormGroup>
                                ...
                        </React.Fragment>
                        )
                    }}
                </Context.Consumer>
        )
    }
}

export default withRouter(NewPost)

So, I have a function handleSubredditSelect which does the following:

handleSubredditSelect(event) {  
    this.setState({
        subreddit_selected: event.target.value,
        subreddit_id: event.target.id,
    }, () => 
        this.props.history.push(`/${this.state.subreddit_selected}/new/`)
    )
}

In this function I am not getting any value for event.target.id.

I have tried event.target.key as well but that returned an empty string "".

I want to set subreddit_id in state to the selected option's ID

3 Answers 3

3

The selecting does not work because event.target in <select> element returns entire tree with options:

// result of event.target:
<select>
  <option id="id-1" value="some1">some1</option>
  <option id="id-2" value="some2">some2</option>
  <option id="id-3" value="some3">some3</option>
</select>

Instead the selected one.


For accessing the current option element from select you should rely on selectedIndex:

event.target[event.target.selectedIndex].id 

The code:

export default class SelectForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: "some1",
      id: "id-1"
    };
  }

  handleChange = event => {
    console.log("event", event.target, event.target.selectedIndex);

    this.setState({
      value: event.target.value,
      id: event.target[event.target.selectedIndex].id
    });
  };

  render() {
    return (
      <div>
        <select value={this.state.sex} onChange={this.handleChange}>
          <option id="id-1" value="some1">some1</option>
          <option id="id-2" value="some2">some2</option>
          <option id="id-3" value="some3">some3</option>
        </select>
        ID: {this.state.id}
      </div>
    );
  }
}

Edit 9l814zo9yr

Sign up to request clarification or add additional context in comments.

3 Comments

Ya console.log(event.target) returns the whole select. So, how to solve that. If I am not wrong, the code that you put also faces the same problem!
@SreekarMouli Yes, sorry but I was still coding on it in meantime, please check it now, it should be working :) use event.target[event.target.selectedIndex].id
So for accessing any other attributes, we just do event.target[event.target.selectedIndex].attribute
1

You can use selectedIndex attribute of select:

handleSubredditSelect(event) {  
    const selectedOption = event.target.childNodes[event.target.selectedIndex];
    this.setState({
        subreddit_selected: event.target.value,
        subreddit_id: selectedOption.id,
    }, () => 
        this.props.history.push(`/${this.state.subreddit_selected}/new/`)
    )
}

Here is the sandbox: https://codesandbox.io/s/n5679m5owj

Comments

0

AFAIK event.target.id should be working, doing the same in my project.

But should't it be

<Input 
type="select"
onChange={(e) => this.handleSubredditSelect}
required>`

? (No parantheses after the methodname)

2 Comments

I think it should be either onChange={this.handleSubredditChange} or onChange={(e)=>this.handleSubredditChange(e)}
ah yes sorry, messed it up :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.