React - Pass form data into a function - reactjs

I am new to React and I have a dashboard to display all users. I created a new feature to add a new user on the dashboard. Currently there is only one field to fill out which is the email.
Dashboard.js
<form id="new-user-form">
<fieldset>
<label>
<p>Email</p>
<input type="email" name="new-user" id="new-user" required />
</label>
</fieldset>
<button
type="button"
form="new-user-form"
onClick={this.onFormSubmit}
>
Add
</button>
</form>
and the method onFormSubmit function
onFormSubmit(event) {
var new_email = document.getElementById("new-user").value;
var today =
new Date().getFullYear() +
"-" +
("0" + (new Date().getMonth() + 1)).slice(-2) +
"-" +
("0" + new Date().getDate()).slice(-2);
let new_users = {
email: new_email,
registration: today,
status: "disabled",
};
this.setState((prevState) => ({
users: [...prevState.users, new_users],
}));
What I currently have works but there is no data-validation, I can add a user with an empty form because the new_email variable is taking document.getElementById("new-user").value which can be empty and should rather be the form data.
If you wanna see my full code for dashboard.js
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
users: [
{
email: "pierre-alexandre#gmail.com",
registration: "2020-10-25",
status: "active",
},
{
email: "antoine373#gmail.com",
registration: "2018-10-22",
status: "active",
},
{
email: "sofia.leduc#gmail.com",
registration: "2020-01-03",
status: "disabled",
},
],
searchEmail: "",
};
this.onFormSubmit = this.onFormSubmit.bind(this);
}
onFormSubmit(event) {
var new_email = document.getElementById("new-user").value;
var today =
new Date().getFullYear() +
"-" +
("0" + (new Date().getMonth() + 1)).slice(-2) +
"-" +
("0" + new Date().getDate()).slice(-2);
let new_users = {
email: new_email,
registration: today,
status: "disabled",
};
this.setState((prevState) => ({
users: [...prevState.users, new_users],
}));
}
handleLogout = () => {
fire.auth().signOut();
};
handleInput = (e) => {
this.setState({ searchEmail: e.target.value });
};
render() {
let filteredUsers = this.state.users.filter((user) => {
return user.email
.toLowerCase()
.includes(this.state.searchEmail.toLowerCase());
});
return (
<div>
<h2>Welcome</h2>
<button onClick={this.handleLogout}>Logout</button>
<div className="users-dashboard-container">
<div className="users-dashboard">
<div className="top-navigation">
<div className="search-navigation">
<img
src={process.env.PUBLIC_URL + "images/search.png"}
alt="logo"
/>
<SearchBox handleInput={this.handleInput} />
</div>
<div className="add-user">
<a>Add user</a>
</div>
</div>
<div class="dashboard-content">
<table>
<tr>
<th>Email</th>
<th>Registration Date</th>
<th>Status</th>
<th>Other</th>
</tr>
<UserList filteredUsers={filteredUsers} />
</table>
</div>
</div>
</div>
<div>
<div className="wrapper">
<h1>Add a User</h1>
<form id="new-user-form">
<fieldset>
<label>
<p>Email</p>
<input type="email" name="new-user" id="new-user" required />
</label>
</fieldset>
<button
type="button"
form="new-user-form"
onClick={this.onFormSubmit}
>
Add
</button>
</form>
</div>
</div>
</div>
);
}
}
export default Dashboard;

You can try like below.
handleChange = e => { // You can use this function to handle all inputs with name as state property
this.setState({ [e.target.name]: e.target.value }) // name will be `email`
}
formSubmit = () => {
if (!this.state.email) {
// Do email validations here
alert('Enter Email')
return
}
const today =
new Date().getFullYear() +
"-" +
("0" + (new Date().getMonth() + 1)).slice(-2) +
"-" +
("0" + new Date().getDate()).slice(-2);
const email = this.state.email
const new_user = {
email,
registration: today,
status: "disabled",
};
this.setState((prevState) => ({
users: [...prevState.users, new_user],
email: '' // Resets email once added into dashboard
}));
}
<div className="wrapper">
<h1>Add a User</h1>
<label>
<p>Email</p>(
<input
type="email"
name="email" // <- this will be used add state key
value={email}
onChange={handleChange} />
</label>
<button onClick={this.onFormSubmit}>
Add
</button>
</div>

One simple way is to disable the submit button if state.searchEmail is empty.
import React, { Component } from "react";
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
searchEmail: ""
};
this.onFormSubmit = this.onFormSubmit.bind(this);
this.handleInput = this.handleInput.bind(this);
}
onFormSubmit() {
let new_user = {
email: this.state.searchEmail
};
console.log(new_user);
}
handleInput(e) {
this.setState({ searchEmail: e.target.value });
};
render() {
return (
<form>
<label>
Email
<input
onChange={this.handleInput}
value={this.state.searchEmail}
type="email"
required
/>
</label>
<button
onClick={this.onFormSubmit}
disabled={this.state.searchEmail === ""}
>
Add
</button>
</form>
);
}
}
export default Dashboard;
You could take this approach further and move the validation into a function where you check state.searchEmail against a regex.
import React, { Component } from "react";
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
searchEmail: ""
};
}
onFormSubmit = (e) => {
e.preventDefault();
let new_user = {
email: this.state.searchEmail
};
console.log(new_user);
this.setState({ searchEmail: "" });
};
handleInput = (e) => {
this.setState({ searchEmail: e.target.value });
};
formIsInvalid = () => {
return (
this.state.searchEmail === "" ||
!this.state.searchEmail.match(/^[\w-.]+#([\w-]+\.)+[\w-]{2,4}$/)
);
};
render() {
return (
<form action="" onSubmit={this.onFormSubmit}>
<label>
Email
<input
onChange={this.handleInput}
value={this.state.searchEmail}
type="email"
required
/>
</label>
<button disabled={this.formIsInvalid()}>Add</button>
</form>
);
}
}
export default Dashboard;

Related

How Can I get first element from API array

I am learning React and API. Here I am fetching data from API.I am trying to do on click button one user should appear. Or on click of user name all other user info should appear. I want to display one element from API array.If click on button new user should show. How to get only one user or one user info. Botton I added input box which can shoe only one value. I am stuck here.
import React from 'react';
import './App.css';
class Home extends React.Component {
constructor(props) {
super(props)
this.state = {
items: [],
error: '',
email:'',
phone:'',
companyName:''
}
this.handleInputChange = this.handleInputChange.bind(this);
this.showUserEmail = this.showUserEmail.bind(this);
}
handleInputChange(event){
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSelectUserName = (event) => {
console.log(event.target.value);
const myUser = (event.target.value);
this.setState({ name: event.target.value });
const selectedUser= event.target.value;
}
showUserEmail=(e)=>{
console.log("you are clicking name" );
this.setState({
})
}
componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((result) => {
console.log(result);
console.warn(result);
this.setState({ items: result });
});
}
render() {
const { items } = this.state
return (
<div>
<button className="btn"> Show new User</button>
<div className="new-user" onChange={event => this. handleSelectNewUser(event)}>
{this.state.items.map(items => (
<span key={items.name} value={items.name}>
{items.name} <p></p></span>))}
</div>
<p className="para-text"> Data from API</p>
<div className="user-info">
{
items.length ?
items.map(items => <div key ={ items.id }>
<div className="user-details"> {items.name} </div>
<div className="user-details">{items.phone}</div>
<div className="user-details">{items.company.name}</div>
<div className="user-details">{items.username}</div>
<div className="user-details">{items.email}</div>
<div className="user-details">{items.website}</div>
</div>) : null
}
</div>
<h2>Find User By Username</h2>
<div className="input-box">
<select onChange={event => this.handleSelectUserName(event)}>
{this.state.items.map(items => (
<option key={items.name} value={items.name}>
{items.username}
</option>
))}
</select>
{/* Auto select */}
<div className=" Show-User-Auto">
<div className="input-box">
<input type="text"
placeholder=" Auto Select"
required="required"
onChange={event => this.handleInputChange(event)}
value={this.state.name} />
</div>
</div>
</div>
</div>
);
}
}
export default Home;
You have to maintain a state which contains userId , then you can condition render it like below code
import React from "react";
class Users extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
error: "",
email: "",
phone: "",
companyName: "",
userId: "",
orgList: []
};
this.handleInputChange = this.handleInputChange.bind(this);
this.showUserEmail = this.showUserEmail.bind(this);
}
handleSetUserId = (userId) => {
if (userId === this.state.userId) {
this.setState({ userId: "" });
} else {
this.setState({ userId });
}
};
handleInputChange(event) {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSelectUserName = (event) => {
console.log(event.target.value);
const myUserId = event.target.value;
if (myUserId) {
console.log(this.state.orgList, "this.state.orgList");
let selectedUser = this.state.orgList.filter((item) => {
return item.id == Number(myUserId);
});
console.log(selectedUser, "selectedUser");
this.setState({ items: selectedUser });
}
};
showUserEmail = (e) => {
console.log("you are clicking name");
this.setState({});
};
componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((result) => {
console.log(result);
console.warn(result);
this.setState({ items: result, orgList: result });
});
}
handleFetchAllUsers=()=>{
this.setState({items:this.state.orgList})
}
render() {
const { items } = this.state;
return (
<div>
<button className="btn" onClick={()=>this.handleFetchAllUsers()}> Show All User</button>
<div
className="new-user"
onChange={(event) => this.handleSelectNewUser(event)}
>
{this.state.items.map((items) => (
<span key={items.name}>
<br />
<span onClick={() => this.handleSetUserId(items.id)}>
{items.name}
<br />
</span>
{items.id === this.state.userId && (
<p>
<br />
<div className="user-details">{items.phone}</div>
<div className="user-details">{items.company.name}</div>
<div className="user-details">{items.username}</div>
<div className="user-details">{items.email}</div>
<div className="user-details">{items.website}</div>
</p>
)}
</span>
))}
</div>
<p className="para-text"> Data from API</p>
<h2>Find User By Username</h2>
<div className="input-box">
<select onChange={(event) => this.handleSelectUserName(event)}>
{this.state.orgList.map((items) => (
<option key={items.name} value={items.id}>
{items.username}
</option>
))}
</select>
{/* Auto select */}
<div className=" Show-User-Auto">
<div className="input-box">
<input
type="text"
placeholder=" Auto Select"
required="required"
onChange={(event) => this.handleInputChange(event)}
value={this.state.name}
/>
</div>
</div>
</div>
</div>
);
}
}
export default Users;
I have implemented the same in codesandbox you can use for ref

I can't loop this array without getting an error (React)

I am learning React and I have just learned to get input values. I tried to write a code to practice. I had an error I can't solve. I tried everything:
I tried to put the array map in another function
I tried to use a return (but React isn't pure js so it didn't work)
I tried to move the map outside the functions but I need to map the Array each time I press the Add button
I tried to override the persons variables with the array map
Can someone help me? Thanks in advance.
P.S. Sorry for my terrible english
here it is:
import './App.css';
import React from 'react'
class App extends React.Component {
state = {
name: '',
surname: '',
age: '',
};
persons = []
getName = (e) => {
this.setState({name: e.target.value})
}
getSurname = (e) => {
this.setState({surname: e.target.value})
}
getAge = (e) => {
this.setState({age: e.target.value})
}
handleSubmit = (e) => {
e.preventDefault()
const name = this.state.name
const surname = this.state.surname
const age = this.state.age
this.persons.push(name + ' ' + surname + ', ' + age)
const persons_list = this.persons.map((person) =>
<li>{person}</li>
);
}
render () {
return (
<div className='container'>
<h1 className='title'>React Database</h1>
<form action="">
<input type="text" placeholder='Name' className='name' onChange={this.getName} />
<input type="text" placeholder="Surname" className='surname' onChange={this.getSurname} />
<input type="text" placeholder="Age" className='age' onChange={this.getAge} />
<button className='add_btn' onClick={this.handleSubmit}>Add</button>
<button className='delete_btn' onClick={this.persons.pop()}>Delete</button>
</form>
<ul>{this.persons_list}</ul> // the error is here: I can't use a variable inside a function
</div>
);
}
}
export default App
Move persons_list inside the render function. You have the list as part of the handleSubmit function.
handleSubmit = (e) => {
e.preventDefault()
const name = this.state.name
const surname = this.state.surname
const age = this.state.age
this.persons.push(name + ' ' + surname + ', ' + age)
const persons_list = this.persons.map((person) =>
<li>{person}</li>
);
}
//try something like this
import React, { Component } from "react";
import { render } from "react-dom";
class App extends Component {
state = {
name: "",
surname: "",
age: "",
porsons: [],
};
persons = [];
getName = (e) => {
this.setState({ name: e.target.value });
};
getSurname = (e) => {
this.setState({ surname: e.target.value });
};
getAge = (e) => {
this.setState({ age: e.target.value });
};
handleSubmit = (e) => {
e.preventDefault();
const name = this.state.name;
const surname = this.state.surname;
const age = this.state.age;
this.persons.push(name + " " + surname + ", " + age);
this.setState({ persons: this.persons });
};
render() {
console.log("App started");
return (
<div className="container">
<h1 className="title">React Database</h1>
<form action="">
<input
type="text"
placeholder="Name"
className="name"
onChange={this.getName}
/>
<input
type="text"
placeholder="Surname"
className="surname"
onChange={this.getSurname}
/>
<input
type="text"
placeholder="Age"
className="age"
onChange={this.getAge}
/>
<button className="add_btn" onClick={this.handleSubmit}>
Add
</button>
<button className="delete_btn" onClick={this.persons.pop()}>
Delete
</button>
</form>
<ul>
{(this.state.persons || []).map((person) => (
<li>{person}</li>
))}
</ul>
</div>
);
}
}
render(<App />, document.querySelector("#app"));
You should learn about scope. The persons_list variable you are using in handleSubmit is only visible to handleSubmit, you should move it outside the function, or instead do the following
render () {
return (
<div className='container'>
<h1 className='title'>React Database</h1>
<form action="">
<input type="text" placeholder='Name' className='name' onChange={this.getName} />
<input type="text" placeholder="Surname" className='surname' onChange={this.getSurname} />
<input type="text" placeholder="Age" className='age' onChange={this.getAge} />
<button className='add_btn' onClick={this.handleSubmit}>Add</button>
<button className='delete_btn' onClick={this.persons.pop()}>Delete</button>
</form>
<ul>{this.persons.map((person) => <li>{person}</li>)}</ul> // the error is here: I can't use a variable inside a function
</div>
);
}

Checkbox validation using React JS

I am currently working on a form having checkboxes which has to be validated using react JS. I need it to show an error saying 'Please select atleast 2 checkbox' if less than 2 checkboxes are checked. I've tried using the if condition but its not working. I have referred a lot of of websites but couldn't come up with a proper solution. Please do help me.
MY CODE:
class App extends React.Component {
state = {
checkbox: "",
checkboxValid: false,
errorMsg: {},
};
validateForm = () => {
const { checkboxValid } = this.state;
this.setState({
formValid: checkboxValid,
});
};
updateCheckbox = (checkbox) => {
this.setState({ checkbox }, this.validateCheckbox);
};
validateCheckbox = () => {
const { checkbox } = this.state;
let checkboxValid = true;
let errorMsg = { ...this.state.errorMsg };
if (checkbox.checked < 2) {
checkboxValid = false;
errorMsg.checkbox = "Please select atleast 2 checkbox";
}
this.setState({ checkboxValid, errorMsg }, this.validateForm);
};
render() {
return (
<div>
<label htmlFor="checkbox">checkbox</label>
<ValidationMessage
valid={this.state.checkboxValid}
message={this.state.errorMsg.checkbox}
/>
<input
type="checkbox"
onChange={(e) => this.updateCheckbox(e.target.value)}
/>
Sports
<br></br>
<input
type="checkbox"
onChange={(e) => this.updateCheckbox(e.target.value)}
/>
Business
<br></br>
<input
type="checkbox"
onChange={(e) => this.updateCheckbox(e.target.value)}
/>
Health
<br></br>
<input
type="checkbox"
onChange={(e) => this.updateCheckbox(e.target.value)}
/>
Society
<br></br>
<div>
<button
className="button"
type="submit"
disabled={!this.state.formValid}
>
Submit
</button>
</div>
</div>
);
}
}
Define count in the state and update it based on the checkbox selection,
state = {
checkbox: "",
checkboxValid: false,
errorMsg: {},
selectedCheckBox: 0
};
Update Logic:-
updateCheckbox = ({ name, checked }) => {
this.setState(
(prev) => ({
checkbox: checked,
selectedCheckBox: checked
? prev.selectedCheckBox + 1
: prev.selectedCheckBox - 1
}),
this.validateCheckbox
);
};
Use the selectedCheckBox count in the state for validation
Completed Code:-
import React from "react";
import "./styles.css";
export default class App extends React.Component {
state = {
checkbox: "",
checkboxValid: false,
errorMsg: {},
selectedCheckBox: 0
};
validateForm = () => {
const { checkboxValid } = this.state;
this.setState({
formValid: checkboxValid
});
};
updateCheckbox = ({ name, checked }) => {
this.setState(
(prev) => ({
checkbox: checked,
selectedCheckBox: checked
? prev.selectedCheckBox + 1
: prev.selectedCheckBox - 1
}),
this.validateCheckbox
);
};
validateCheckbox = () => {
const { checkbox } = this.state;
let checkboxValid = true;
let errorMsg = { ...this.state.errorMsg };
if (this.state.selectedCheckBox < 2) {
checkboxValid = false;
errorMsg.checkbox = "Please select atleast 2 checkbox";
}
this.setState({ checkboxValid, errorMsg }, this.validateForm);
};
render() {
return (
<div>
<label htmlFor="checkbox">checkbox</label>
{/* <ValidationMessage
valid={this.state.checkboxValid}
message={this.state.errorMsg.checkbox}
/> */}
<input
type="checkbox"
name="business"
onChange={(e) => this.updateCheckbox(e.target)}
/>
Sports
<br></br>
<input
type="checkbox"
name="health"
onChange={(e) => this.updateCheckbox(e.target)}
/>
Business
<br></br>
<input
type="checkbox"
name="society"
onChange={(e) => this.updateCheckbox(e.target)}
/>
Health
<br></br>
<input
type="checkbox"
onChange={(e) => this.updateCheckbox(e.target)}
/>
Society
<br></br>
<div>
<button
className="button"
type="submit"
disabled={!this.state.formValid}
>
Submit
</button>
<br />
<b style={{ fontSize: "30px" }}>{this.state.selectedCheckBox}</b>
</div>
</div>
);
}
}
Working Demo - https://codesandbox.io/s/frosty-colden-8hdm4?file=/src/App.js:0-2160
One way to solve this is by having a different state for each checkbox. Set a name for each checkbox so that it can be access by e.target.name
Notice that the name of the input is the same as the state.
state = {
checkbox1: false,
checkbox2: false,
checkboxValid: false,
};
updateCheckbox = (e) => {
this.setState({ e.target.name: e.target.checked });
};
if(this.state.checkbox1 && this.state.checkbox2) {
//both are checked!
}
change input to
<input
name="checkbox1"
type="checkbox"
onChange={this.updateCheckbox}
checked={this.state.checkbox1}
/>

I need to pass a URL from a class component to another

here is my QR component :
import React, { Component } from "react";
class QR extends React.Component {
constructor(props) {
super(props);
}
render() {
const { catImageUrl } = this.props;
const qrUrl = `https://qrtag.net/api/qr_12.svg?url=${catImageUrl}`;
if (!catImageUrl) return <p>Oops, something went wrong!</p>;
return <img className="QR" src={qrUrl} alt="qrtag" />;
}
}
export default QR;
I need to pass the const qrURL to the next component Form.js to use it in ajax call to get its data and pass it to the next api request to send it to an email
class Form extends React.Component{
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: '',
}
}
const{qrUrl}=this.props;
FetchQRURL = () => {
fetch(`${qrUrl}`)
.then((response) => response.json())
.then((data) => {
this.setState({
message: data,
});
})
.catch((error) => console.log(error));
};
handleSubmit(e){
e.preventDefault();
axios({
method: "POST",
url:"http://localhost:3002/send",
data: this.state
}).then((response)=>{
if (response.data.status === 'success'){
alert("Message Sent.");
this.resetForm()
}else if(response.data.status === 'fail'){
alert("Message failed to send.")
}
})
}
resetForm(){
this.setState({name: '', email: '', message: ''})
}
render() {
return(
<div className="App">
<form id="contact-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
<div className="form-group">
<label htmlFor="name">Name</label>
<input type="text" className="form-control" id="name" value={this.state.name} onChange={this.onNameChange.bind(this)} />
</div>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Email address</label>
<input type="email" className="form-control" id="email" aria-describedby="emailHelp" value={this.state.email} onChange={this.onEmailChange.bind(this)} />
</div>
<div className="form-group">
<label htmlFor="message">Message</label>
<textarea className="form-control" rows="5" id="message" value={this.state.message} onChange={this.onMessageChange.bind(this)} />
</div>
<button type="submit" className="btn btn-primary" onClick="">Submit</button>
</form>
</div>
);
}
onNameChange(event) {
this.setState({name: event.target.value})
}
onEmailChange(event) {
this.setState({email: event.target.value})
}
onMessageChange(event) {
this.setState({message: event.target.value})
}
}
export default Form;
you can see I tried to pass it as props but it doesn't work
here I tried to pass it as props(in my app.js)
import React, { Component } from "react";
import RandomCat from "./RandomCat.js";
import QR from "./QR.js";
import Form from "./form.js";
class BooksApp extends Component {
state = {
showCatImage: false,
showQrCode: false,
catImageUrl: "",
};
handleFetchRandomImage = () => {
fetch("https://aws.random.cat/meow")
.then((response) => response.json())
.then((data) => {
this.setState({
catImageUrl: data.file,
showCatImage: true,
});
})
.catch((error) => console.log(error));
};
handleShowQrCode = () => {
this.setState({ showQrCode: true });
};
render() {
const { showCatImage, showQrCode, catImageUrl,qrUrl } = this.state;
return (
<div className="app">
<div className="first">
{/* The time below shows cat image if showCatImage === true and returns nothing if false */}
{showCatImage && <RandomCat catImageUrl={catImageUrl} />}
<button className="catButton" onClick={this.handleFetchRandomImage}>
Generate Cat
</button>
</div>
<div className="second">
{showQrCode && <QR catImageUrl={catImageUrl} qrUrl={qrUrl}/>}
<button className="QRButton" onClick={this.handleShowQrCode}>
Geanerate QR
</button>
</div>
<div>
<Form qrUrl={qrUrl}/>
</div>
</div>
);
}
}
export default BooksApp;
any idea how can I pass it to the Form.js?
You have to pull the constant qrUrl to the parent component which is BooksApp in your case.
Set it to the state and pass it down as props.
state = {
showCatImage: false,
showQrCode: false,
catImageUrl: "",
qrUrl: ""
};
handleFetchRandomImage = () => {
fetch("https://aws.random.cat/meow")
.then((response) => response.json())
.then((data) => {
this.setState({
catImageUrl: data.file,
showCatImage: true,
qrUrl: `https://qrtag.net/api/qr_12.svg?url=${data.file}` // Set it here
});
})
.catch((error) => console.log(error));
};
handleShowQrCode = () => {
this.setState({ showQrCode: true });
};
render() {
const { showCatImage, showQrCode, catImageUrl, qrUrl } = this.state;
return (
<div className="app">
<div className="first">
{/* The time below shows cat image if showCatImage === true and returns nothing if false */}
{showCatImage && <RandomCat catImageUrl={catImageUrl} />}
<button className="catButton" onClick={this.handleFetchRandomImage}>
Generate Cat
</button>
</div>
<div className="second">
{showQrCode && <QR catImageUrl={catImageUrl} qrUrl={qrUrl}/>}
<button className="QRButton" onClick={this.handleShowQrCode}>
Geanerate QR
</button>
</div>
<div>
<Form qrUrl={qrUrl}/>
</div>
</div>
);
}
}
export default BooksApp;
The just use it with this.props.qrUrl in your other components.

Grabbing React form field values for submission

Given a React form, I'm having trouble getting the value from the selected radio button, and text box if other is selected. I should be able to pass the fields into the send() for the post, but not sure how to grab them.
class CancelSurvey extends React.Component {
constructor (props) {
super(props)
this.state = {
reasons: [],
reason: {}
}
this.processData = this.processData.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.otherSelected = this.state.reason === "otheroption";
}
componentDidMount () {
this.fetchContent(this.processData)
}
/**
* Fetch reasons
*/
fetchContent (cb) {
superagent
.get('/api/user/survey')
.then(cb)
}
/**
* Set state after reasons have been fetched
* #param data
*/
processData (data) {
this.setState({
reasons: data.body
})
}
handleSubmit (e) {
e.preventDefault()
let reason = this.state.reason
if (reason === 'otheroption') {
reason = this.state.otherreason
}
console.log(reason)
superagent
.post('/api/user/survey')
.send({
optionId: this.state.reason.reason_id,
optionText: this.state.reason.client_reason,
otherReasonText: this.state.otherreason
})
.then(function (res) {
console.log('Survey Sent!')
})
}
/**
* render
*/
render (props) {
const content = this.props.config.contentStrings
const reason = this.state.reasons.map((reason, i) => {
return (
<div className='fieldset__item' key={i}>
<label>{reason.client_reason}</label>
<input type='radio'
id={reason.reason_id}
value={reason.client_reason}
name='reason'
checked={this.state.reason.reason_id === reason.reason_id}
onChange={() => this.setState({reason})} />
</div>
)
})
return (
<div className='survey'>
<h2 className='heading md'>{content.memberCancel.exitSurvey.heading}</h2>
<p className='subpara'>{content.memberCancel.exitSurvey.subHeading}</p>
<form id='exit-survey' onSubmit={this.handleSubmit}>
<fieldset className='fieldset'>
{ reason }
<label>Other reason not included above:</label>
<input type='radio'
id='otheroption'
name='reason'
value={this.state.reason.otherreason}
onChange={() => this.setState({reason:{reason_id: 70, client_reason: 'other'}})} />
<input className='valid'
type='text'
id='otheroption'
name='othertext'
placeholder={content.memberCancel.exitSurvey.reasonPlaceholder}
onChange={(event) => this.setState({otherreason: event.target.value})} />
</fieldset>
<div className='footer-links'>
<button className='btn btn--primary btn--lg' onClick={this.handleSubmit}>{content.memberCancel.exitSurvey.button}</button>
</div>
</form>
</div>
)
}
}
export default CancelSurvey
Your variables aren't correct. I've update them to what I think is correct.
handleSubmit (e) {
e.preventDefault()
superagent
.post('/api/user/survey')
.send({
optionId: this.state.reason.reason_id,
optionText: this.state.reason.client_reason,
otherReasonText: this.state.reason.otherreason
})
.then(function (res) {
console.log('Survey Sent!')
})
.catch(function (err) {
console.log('Survey submission went wrong...')
})
}
/**
* render
*/
render (props) {
const content = this.props.config.contentStrings
const reason = this.state.reasons.map((reason, i) => {
return (
<div className='fieldset__item' key={i}>
<label>{reason.client_reason}</label>
<input
type='radio'
id={reason.reason_id}
name='reason'
checked={this.state.reason.reason_id === reason.reason_id}
value={reason.client_reason}
onChange={() => this.setState({reason})} />
</div>
)
})
return (
<div className='survey'>
<h2 className='heading md'>{content.memberCancel.exitSurvey.heading}</h2>
<p className='subpara'>{content.memberCancel.exitSurvey.subHeading}</p>
<form id='exit-survey' onSubmit={this.handleSubmit}>
<fieldset className='fieldset'>
{ reason }
<label>Other reason not included above:</label>
<input type='radio'
id='otheroption'
name='otheroption'
value={this.state.reason.otherreason}
checked={this.state.reason.reason_id === 0}
onChange={() => this.setState({ reason: {reason_id: 0, client_reason: ""} })} />
<input className='valid'
type='text'
id='othertext'
name='othertext'
value={this.state.reason.otherreason}
placeholder={content.memberCancel.exitSurvey.reasonPlaceholder}
onChange={(event) => this.setState({ reason: {reason_id: 0, client_reason: "", otherreason: event.target.value} })} />
</fieldset>
<div className='footer-links'>
<button className='btn btn--primary btn--lg' onClick={this.handleSubmit}>{content.memberCancel.exitSurvey.button}</button>
</div>
</form>
</div>
);
}

Resources