I am using React-Bootstrap and I want to get the values of an input form so that I can save them to Firebase. Before using React-Bootstrap, I was able to grab the value of an input and the text area by using ref, but now I am not able to do that after using
FormGroups`. Upon submitting the form, I am unable to grab the values from the input and the text area.
I've seen previous post concerning this problem, but it seems none these solutions actually work.
I am new to React. Can someone please explain to me how to grab form values from using Formgroups?
import React from 'react'
import ReactDOM from 'react-dom'
import {withRouter} from 'react-router'
import './NewListPage.css'
import Header from './Header'
import ListItem from './ListItem'
import database from '../database'
import Form from './Form'
import {
Button,
FormGroup,
FormControl,
Feedback,
ControlLabel
} from 'react-bootstrap';
class NewListPage extends React.Component {
// bring props into constructor
constructor(props) {
// bring props into super
super(props)
//create list uuid this needs to be A better uuid genereator in the future
const listId = Math.floor((Math.random() * 10000) + 1)
this.state = {
wishList: {
items: []
},
wishListItems: []
}
this.addListItem = this.addListItem.bind(this) //bind the add list item function to this component
this.removeListItem = this.removeListItem.bind(this) //needed to bind update order to root class
this.saveListItem = this.saveListItem.bind(this) //bind to root class
}
addListItem(e) { //add another item to the array
e.preventDefault()
// never change state directly, make a copy instead
const wishList = Object.assign({}, this.state.wishList)
//push a new item to items object
wishList.items.push({title: 'title', description: 'description'})
this.setState({
//update the state
wishList
})
}
// remove items from array
removeListItem(index) {
// never change state directly, make a copy instead
const wishList = Object.assign({}, this.state.wishList)
//remove item object from items array using its index
wishList.items.splice([index], 1)
this.setState({
//update the state from the new array
wishList
})
}
// save list item into dB
saveListItem(event) {
// upon submit, prevent whole page from refreshing
event.preventDefault()
// never change state directly, make a copy instead
const wishList = Object.assign({}, this.state.wishList)
// grab the title
wishList.title = this.refs.title.value
// grab the description
wishList.description = this.refs.description.value
// for each item in the list grab its properties
wishList.items.map((item, index) => {
// grab descritions and title from generated form
item.description = this.refs.list.children[index].children.itemdescription.value
item.title = this.refs.list.children[index].children.itemtitle.value
})
// push the wishlist to firebase (need to add code to handle errors.)
// we use push so that firebase will generate its own uuid
database.push('wishLists', {
data: wishList
// if it saves then resolve this promise and push the uuid to users/uid/wishLists
}).then(newList => {
database.push(`users/${this.props.currentUser.uid}/wishLists`, {
// newList.key contains the firebase uuid from the previous push
data: newList.key
// if this also saves then redirect
}).then(finished => {
//redirect to dashboard
this.props.history.push('/')
})
})
}
render() {
return (
<div>
<h1>Create a New Wishlist</h1>
<div className="ListForm">
<Row>
<Col sm={3}/>
<Col sm={6}>
<form onSubmit={this.saveListItem.bind(this)}>
<FormGroup>
<ControlLabel>Wishlist Title</ControlLabel>
<br/>
<FormControl type="text" name="title" ref="title" required="true" placeholder="Enter text"/>
<FormControl.Feedback/>
<br/>
<FormGroup controlId="formControlsTextarea">
<ControlLabel>Wishlist Description Optional</ControlLabel>
<FormControl componentClass="textarea" placeholder="textarea" name="description" ref="description"/>
</FormGroup>
<br/>
<div className="ListItems" ref="list">
{this.state.wishList.items.map((item, index) => {
return <ListItem removeListItem={this.removeListItem} myIndex={index} key={index}/>
})}
</div>
<Button bsStyle="primary" type="button" onClick={this.addListItem}>ADD ITEM</Button><br/><br/>
<input type="submit" value="Save List" ref="save"/>
</FormGroup>
</form>
</Col>
</Row>
</div>
</div>
)
}
}
// export with router
export default withRouter(NewListPage)
Here is the error message from the window console log.
It's because your ref
is no longer an <input>
DOM node, but a React Bootstrap <FormControl>
instance.
Use form.elements
instead to get a hold of the form's inputs by their name
:
let form = event.target
wishlist.title = form.elements.title.value
wishlist.description = form.elements.description.value
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With