Taras Yaremkiv
Taras Yaremkiv

Reputation: 3600

How to get an input value using "refs" in react-bootstrap form?

I'm trying to create a form that appears in modal. So when user input a value, that value is stored in local storage. Here's a picture that help's you to understand what I mean:
enter image description here Here is the code of the form:

function FieldGroup({id, label, help, ...props}) {
    return (
        <ReactBootstrap.FormGroup controlId={id}>
            <ReactBootstrap.ControlLabel>{label}</ReactBootstrap.ControlLabel>
            <ReactBootstrap.FormControl {...props} />
            {help && <ReactBootstrap.HelpBlock>{help}</ReactBootstrap.HelpBlock>}
        </ReactBootstrap.FormGroup>
    );
}

const formInstance = (
    <form>
        <FieldGroup
            id="formControlsText"
            type="text"
            label="Text"
            placeholder="Recipe Name"
            inputRef={ref => { this.input = ref; }}
        />
        <ReactBootstrap.FormGroup controlId="formControlsTextarea">
            <ReactBootstrap.ControlLabel>Ingredients</ReactBootstrap.ControlLabel>
            <ReactBootstrap.FormControl componentClass="textarea" placeholder="Enter Ingredients" />
        </ReactBootstrap.FormGroup>
    </form>
);  

As I've read in bootstrap React tutorial, I should add
<FormControl inputRef={ref => { this.input = ref; }} /> to the FormControl props. But after adding it I get an error when modal form is invoked:

`enter image description here

Upvotes: 26

Views: 51125

Answers (7)

zato
zato

Reputation: 117

I think I found how to get the ref from React-Bootstrap <Form/>.

 import React, {createRef} from 'react'  

    interface definedProps {} 
    interface definedState {
                  myRef: Object //I didn't found the more accurate type
              } 
    export default class SomeClass extends React.Component<definedProps,definedState> {
        state = {
            myRef: React.createRef<Form<any>>() //That's it!
        }

    const handleClose = () => {
        console.log('this.state.myRef: ', this.state.myRef); //Here we can take data from Form
        debugger; //todo: remove
    }

        render() {

            return (
                <div>
                     <Form ref={this.state.myRef}> { /*Here we're connecting the form's ref to State*/}
                        <Form.Group controlId='formName'>
                            <Form.Control
                                type='text'
                                placeholder='Enter Name'
                            />
                        </Form.Group>
                          ...
                        <Button
                            variant='primary'
                            onClick={handleClose}
                            >
                            Save Changes
                        </Button>
                        </Form>
                </div>
            )
        }
    }

Upvotes: 0

Steve x slapps.fr
Steve x slapps.fr

Reputation: 1244

This worked for me, using https://reactjs.org/docs/refs-and-the-dom.html

 constructor(props) {
        super(props);
        this.email = React.createRef();
    }

submit() {
        var email = this.email.current.value;
        console.log(email);
}
render() {
   return (
            <Form>
            <Form.Control type="email" placeholder="Your email" ref={this.email} />
            <Button variant="primary" onClick={()=>this.submit()}>Send</Button>
            </Form>
           );
}

Upvotes: 3

Yakup Ad
Yakup Ad

Reputation: 1651

Hello this solution worked for me!

<Form
  noValidate
  validated={validated}
  onSubmit={(e) => this.handleSubmit(e)}
  style={{ width: '100%' }}
>
  <Form.Group controlId="formBasicEmail">
   <Form.Label>Email address</Form.Label>
   <Form.Control type="email" placeholder="Enter email" inputRef={(ref) => { this.email = ref }} required />
   <Form.Text className="text-muted"> Well never share your email with anyone else.
   </Form.Text>
  </Form.Group>
</Form>

handleSubmit(event) {
    console.log(event.target.elements.formBasicPassword.value)
}

Upvotes: 0

M.Tae
M.Tae

Reputation: 1467

I have same problem with you, and this is my solution

const FieldGroup = ({id, label, help, inputRef, ...props}) =>
  <FormGroup controlId={id}>
    <ControlLabel>{label}</ControlLabel>
    <FormControl {...props} inputRef={inputRef}/>
    {help && <HelpBlock>{help}</HelpBlock>}
  </FormGroup>

and my form

<form>
    <FieldGroup
        id="bookName"
        type="text"
        label="Name"
        placeholder="Enter name..."
        inputRef = {(input) => this.inputName = input }
     />
    <FieldGroup
        id="bookAuthor"
        label="Author"
        type="text"
        placeholder="author 's name..."
        inputRef={(input) => this.inputAuthor = input}
     />
</form>

then you can get book 's name and author 's name value by:

this.inputName.value and this.inputAuthor.value

Upvotes: 10

Eugene Kulakov
Eugene Kulakov

Reputation: 441

I just made this issue. My code:

<FormControl
    componentClass="input"
    placeholder="Enter recipe title"
    inputRef={(ref) => {this.input = ref}}
    defaultValue={title}/>
</FormGroup>

And then you can get the value from <FormControl> in some handler like this:

console.log(this.input.value);

Details can be found in my repo: https://github.com/kerf007/recipebook

Upvotes: 34

Kaloyan Kosev
Kaloyan Kosev

Reputation: 13067

This issue (or more like a change in the way it works) is related to React-Bootstrap. The way you're doing it won't work anymore.

The <FormControl> component directly renders the or other specified component. If you need to access the value of an uncontrolled <FormControl>, attach a ref to it as you would with an uncontrolled input, then call ReactDOM.findDOMNode(ref) to get the DOM node. You can then interact with that node as you would with any other uncontrolled input.

Here's an example:

var React = require('react');
var ReactDOM = require('react-dom');
var FormControl = require('react-bootstrap').FormControl;

React.createClass({
  render: function() {
    return (<FormControl ref="formControl" />);
  },
  getFormControlNode: function() {
    // Get the underlying <input> DOM element
    return ReactDOM.findDOMNode(this.refs.formControl);
  }
});

As soon as you get the DOM element, you will be able to retrieve the value: this.getFormControlNode().value or do anything else that you want.

PS: Here's a related github issue on this topic.

Upvotes: 6

BryceSi
BryceSi

Reputation: 39

I think what it suggests to use is the ref callback attribute, so just change inputRef to ref.

FYI: https://facebook.github.io/react/docs/refs-and-the-dom.html

Upvotes: 2

Related Questions