State Value Not Being Set from Default Value on Form Submission - reactjs

I have a form where two of my input fields have a defaultValue set to prop values. On form submission I am passing the values from other inputs that are set to state properties, but I am not sure how to capture the defaultValue if the values from those two input fields remain unchanged. Is there a method that follows best practices to capture the defaultValue if the value never changes?
import React from 'react';
import { API_ROOT } from '../../../../config/api-config';
//Annotation - Footer - Email Annotation Modal
export default class EmailAnnotationForm extends React.Component {
constructor(props) {
super(props);
this.state = {
csrf: '',
subject: '',
emails: '',
comment: ''
}
this.handleInputChange = this.handleInputChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
console.log(event);
this.setState({
[name]: value
});
console.log(target)
console.log(name)
console.log(value)
console.log(JSON.stringify(this.state));
}
handleFormSubmit(event) {
console.log("handleFormSubmit")
const body = {
csrf: this.state.csrf,
subject: this.state.subject,
emails: this.state.emails,
comment: this.state.comment
};
event.preventDefault();
var route = `${API_ROOT}` + '/api/annotation/' + this.props.annotationId + '/share/email';
fetch(route,
{
method: 'POST',
body: JSON.stringify(body),
compress: false,
headers: {
'X-CSRF-Token': this.state.csrf,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => {
return res.json();
})
.then(data => {
console.log(data)
handleClearForm()
this.setState({'flash': 'success'});
})
.catch(err => {
console.log(err);
this.setState({'flash': 'error'});
});
}
handleClearForm() {
console.log("handleClearForm")
this.setState({
csrf: '',
subject: '',
emails: '',
comment: ''
})
}
render() {
return (
<div className="annotation-footer__share-form-email">
<form action={"/api/annotation/" + this.props.annotationId + "/share/email"} method="post" onSubmit={this.handleFormSubmit} name="annotationEmailShare" id="share-email-form">
<input type="hidden" name="_csrf" defaultValue={this.props.csrf ? this.props.csrf : ""}/>
<div className="input-group annotation-footer__share-form-email-inputs">
<p><b>Subject:</b></p>
<input type="text" name="subject" className="form-control" defaultValue={this.props.title} onChange={this.handleInputChange}/><br />
</div>
<div className="input-group annotation-footer__share-form-email-inputs">
<p><b>Emails (Comma separate each eamil address):</b></p>
<input type="text" name="emails" className="form-control" onChange={this.handleInputChange}/><br />
</div>
<div className="input-group annotation-footer__share-form-email-inputs">
<p><b>Additional Comment:</b></p>
<textarea name="comment" rows="4" className="form-control" onChange={this.handleInputChange}>{this.state.comment}</textarea><br />
</div>
<button type="submit">Send Email</button>
</form>
</div>
)
}
}
Inputs with DefaultProps:
<input type="hidden" name="_csrf" defaultValue={this.props.csrf ? this.props.csrf : ""}/>
<input type="text" name="subject" className="form-control" defaultValue={this.props.title} onChange={this.handleInputChange}/>
Submitted Value (csrf and subject are not appearing with defaultValues):
{"csrf":"","subject":"","emails":"test#gmail.com","comment":"dsfsdfadsfs"}

Related

Why is React menu pick not maintaining selection?

I am trying to figure out why the menu pick for a note's Folder Name is not getting selected in the code below. I'm using the tags around the folder options. The user can select the Folder Name for the note being created from the UI, but the UI doesn't maintain the selection. As a result, the note is not getting saved to any of the folders.
import React, { Component } from 'react'
import NotesContext from './notesContext'
import './addNote.css'
class AddNote extends Component {
static contextType = NotesContext
constructor(props) {
super(props);
this.state = {
name: '',
value: '',
id: '',
folderId: '',
content: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
console.log("handleChange value: " + event.target.value);
console.log("handleChange name: " + event.target.name)
this.setState(
{[event.target.name]: event.target.value}
);
}
handleSubmit(event) {
console.log("this.context: " + JSON.stringify(this.context))
event.preventDefault();
let requestOptions = {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": this.state.name,
"id": this.state.id,
"folderId": this.state.folderId,
"modified": new Date().toISOString(),
"content": this.state.content
})
};
fetch("http://localhost:9090/notes/", requestOptions)
.then(response => response.json())
.then(result => {
console.log("result:" + JSON.stringify(result));
this.context.addNote(
result.name,
result.id,
result.folderId,
result.modified,
result.content
);
this.props.history.push("/");
})
.catch(error => console.log('error', error));
}
render() {
let notesContext = this.context
return (
<form
className="AddNote"
onSubmit={e => this.handleSubmit(e)}
>
<h1>Create a note</h1>
<label>
Note Name:{' '}
<input
type="text"
value={this.state.name}
className="NameInput"
name="name"
id="name"
onChange={(e) => this.handleChange(e)}
/>
</label>
<label>
Content:{' '}
<textarea
className="ContentInput"
name="content"
id="content"
onChange={e => this.handleChange(e)}
/>
</label>
<label>
Folder:{' '}
<select
value={this.state.folderId} onChange={ (e) => this.handleChange(e)}>
{notesContext.folders.map(folder => {
return(
<option
value={folder.name}
name={folder.name}
key={folder.id}>{folder.name}
</option>
)
})}
</select>
</label>
<input
type="submit"
value="Submit"
className="SubmitButton"
/>
</form>
);
}
}
export default AddNote;
I have a partial Answer at this point. I split up the handleChange method for setting the note and folder. This is now allowing me to create the note in the selected folder -- only if I select a new folder, not the folder selected by default. So I still need to fix that part.
import React, { Component } from 'react'
import NotesContext from './notesContext'
import './addNote.css'
class AddNote extends Component {
static contextType = NotesContext
constructor(props) {
super(props);
this.state = {
name: 'Cows',
id: '',
folderId: '',
content: "",
value: '',
}
this.handleChangeOfNote = this.handleChangeOfNote.bind(this);
this.handleChangeOfFolder = this.handleChangeOfFolder.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChangeOfNote(event) {
//console.log("handleChange value: " + event.target.value);
//console.log("handleChange name: " + event.target.name);
this.setState(
{[event.target.name]: event.target.value}
);
}
handleChangeOfFolder(event) {
this.setState(
{folderId: event.target.value}
);
}
handleSubmit(event) {
event.preventDefault();
let requestOptions = {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": this.state.name,
"id": this.state.id,
"folderId": this.state.folderId,
"modified": new Date().toISOString(),
"content": this.state.content
})
};
fetch("http://localhost:9090/notes/", requestOptions)
.then(response => response.json())
.then(result => {
console.log("result:" + JSON.stringify(result));
this.context.addNote(
result.name,
result.id,
result.folderId,
result.modified,
result.content
);
this.props.history.push("/");
})
.catch(error => console.log('error', error));
}
render() {
let notesContext = this.context
return (
<form
className="AddNote"
onSubmit={e => this.handleSubmit(e)}
>
<h1>Create a note</h1>
<label>
Note Name:{' '}
<input
type="text"
value={this.state.name}
className="NameInput"
name="name"
id="name"
onChange={(e) => this.handleChangeOfNote(e)}
/>
</label>
<label>
Content:{' '}
<textarea
className="ContentInput"
name="content"
id="content"
onChange={e => this.handleChangeOfNote(e)}
/>
</label>
<label>
Folder:{' '}
<select
value={this.state.folderId} onChange={(e) => this.handleChangeOfFolder(e)}>
{notesContext.folders.map(folder => {
return(
<option
value={folder.id}
name={folder.name}
key={folder.id}>{folder.name}
</option>
)
})}
</select>
</label>
<input
type="submit"
value="Submit"
className="SubmitButton"
/>
</form>
);
}
}
export default AddNote;
To fix the problem with the default folder getting set, for now I just set the folderId in state, so that it would be there by default.
constructor(props) {
super(props);
this.state = {
name: '',
id: '',
folderId: 'b0715efe-ffaf-11e8-8eb2-f2801f1b9fd1',
content: "",
value: '',
}

Extra undefined value in this.state

i am trying to post a form in reactjs, and i suspect it doesnt write to DB because i get strange undefined in my state, which looks like:
form looks like this
but in console i get:
this
my code on front is :
constructor(props) {
super(props);
this.state = { name: '', gender: '', email: '' };
}
handleChange= (event) => {
this.setState({
[event.target.name]: event.target.value,
[event.target.gender]: event.target.value,
[event.target.email]: event.target.value,
// [event.target.phone]: event.target.value,
});
}
handleSubmit = (event) => {
console.log(JSON.stringify(this.state));
alert('A form was submitted: ' + this.state);
fetch('http://localhost:3000/api/game/contacts', {
method: 'POST',
body: JSON.stringify(this.state)
}).then(function(response) {
return response.json();
});
event.preventDefault();
}
render() {
const { user } = this.props.auth;
console.log(this.state);
return(
<div>
<form onSubmit={this.handleSubmit}>
<label>
Name:</label>
<input type="text" value={this.state.value} name="name" onChange={this.handleChange} />
<label>
Gender:</label>
<input type="text" value={this.state.value} name="gender" onChange={this.handleChange} />
<label>
Email:</label>
<input type="text" value={this.state.value} name="email" onChange={this.handleChange} />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
Dashboard.propTypes = {
auth: PropTypes.object.isRequired
};
const mapStateToProps = ( state ) => ({
auth: state.auth
});
export default connect( mapStateToProps )( Dashboard );
must be super simple, but i googled for 2 hours, and could not see issue. Thanks for you time

I can't type in input text using reactjs

i can't change text when typing in input text !
This is my fontend code :
constructor(props) {
super(props);
this.state = {
items: [],
acc_email: '',
acc_nom: '',
acc_prenom: '',
acc_tel: '',
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
the value of input comes from DB using fetch :
componentDidMount(){
const token = localStorage.getItem('toktok');
fetch(`${API}/api/account`,{
method: 'GET',
headers :{
'authorization': `Bearer ${token}`,
}
})
.then(results => {
return results.json();
})
.then(data => {
this.setState({ items: data.result });
console.log("account: ",data.result);
// localStorage.setItem('mymy', "fiss");
// console.log(items);
// console.log(items.length);
})
.catch(err => {
console.log("erroooor : ",err);
});
}
i don't know what's wrong in this function :
handleInputChange = e => {
const name = e.target.name;
const value = e.target.value;
this.setState({[name]: value});
this.setState({ [e.target.name]: e.target.value });
}
and finally, this's the render() that conains all inputs:
<div key={items._id}>
<input type="text" value={items.email} name="acc_email" onChange={this.handleInputChange} />
<input type="text" value={items.nom} name="acc_nom" onChange={this.handleInputChange} />
<input type="text" value={items.prenom} name="acc_prenom" onChange={this.handleInputChange} />
<input type="text" value={items.tel} name="acc_tel" onChange={this.handleInputChange} />
<a className="admin-btn-update" href={`/updateaccount/${items._id}`}>Modifier</a>
</div>
change value to defaultValue as follows.
<input type="text" defaultValue={items.email} name="acc_email" onChange={this.handleInputChange} />
You are explicitly setting the values of the inputs to be items.email, items.nom.. which makes them controlled inputs, which basically means that it's the component responsibility to control what happens to those inputs.
Since you already implemented the part that updates the component state, all you need to do is to make the inputs values reflect this state:
<input type="text" value={this.state.acc_email} name="acc_email" onChange={this.handleInputChange} />
<input type="text" value={this.state.acc_nom} name="acc_nom" onChange={this.handleInputChange} />
<input type="text" value={this.state.acc_prenom} name="acc_prenom" onChange={this.handleInputChange} />
<input type="text" value={this.state.acc_tel} name="acc_tel" onChange={this.handleInputChange} />

React signup page syntax error at return of render function

i have a react sign up page that returns an error at the return of the render method. It shows a syntax error whenever i run the code on the browser. The code is meant to pass data to a server endpoint.I have looked all over and can't find the cause of the error. I would like to know the probable cause of this problem and the line of action or code to correct this error
`import React, { Component } from 'react';
class Register extends Component {
constructor(props) {
super(props);
this.state = {
name:'',
town: '',
long: '',
lat: ''
}
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
onSubmit = (e) => {
e.preventDefault();
const Register = {
name: this.state.name,
town: this.state.town,
long: this.state.long,
lat: this.state.lat
}
}
}
fetch ('https://localhost3000/users/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'name',
city: 'city',
long: 'long',
lat: 'lat'
})
})
.then(function(response){
return response.json();
})
.then(function(Register){
console.log(Register)
});
*render() {
return ( *
<div>
<form className="form-style">
<label>
Name:<br/>
<input name='name' value={this.state.name}
placeholder="Enter Your Farm Name"
onChange={e => this.handleChange(e)}/>
</label><br/>
<label>
Town:<br/>
<input name='town' value={this.state.town}
placeholder="Enter town where farm is located"
onChange={e => this.handleChange(e)}/>
</label><br/>
<label>
Longitude:<br/>
<input name='long' value={this.state.long}
placeholder="Enter Your Farm Longitude"
onChange={e => this.handleChange(e)}/><br/>
Latitude:<br/>
<input name='lat' value={this.state.lat}
placeholder="Enter Your Farm Latitude"
onChange={e => this.handleChange(e)}/>
</label><br/>
<Link><a href="https://www.latlong.net/" target="_blank">
Get Longitude and Latitude of current location here</a></Link><br/>
<button onClick={e => this.handleSubmit(e)}
disabled={!this.state.name}
disabled={!this.state.long}
disabled={!this.state.lat}
disabled={!this.state.town}>
Register</button>
</form>
</div>
)
};
export default Register ;`
You have a misplaced } in your code right after you define the onSubmit function. This closed off your component and made the rest of your code invalid. You're also trying to call fetch inside your component without it being inside any lifecycle-method, function or event. This will lead to a syntax error.
Try this instead :)
import React from "react"
import { Link } from "react-router-dom"
class Register extends React.Component {
constructor(props) {
super(props)
this.state = {
name:'',
town: '',
long: '',
lat: ''
}
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
componentDidMount(){
fetch ('https://localhost3000/users/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'name',
city: 'city',
long: 'long',
lat: 'lat'
})
})
.then(function(response){
return response.json();
})
.then(function(Register){
console.log(Register)
})
}
onSubmit = (e) => {
e.preventDefault()
const Register = {
name: this.state.name,
town: this.state.town,
long: this.state.long,
lat: this.state.lat
}
}
render(){
return (
<div>
<form className="form-style">
<label>
Name:<br/>
<input name='name' value={this.state.name}
placeholder="Enter Your Farm Name"
onChange={e => this.handleChange(e)}/>
</label><br/>
<label>
Town:<br/>
<input name='town' value={this.state.town}
placeholder="Enter town where farm is located"
onChange={e => this.handleChange(e)}/>
</label><br/>
<label>
Longitude:<br/>
<input name='long' value={this.state.long}
placeholder="Enter Your Farm Longitude"
onChange={e => this.handleChange(e)}/><br/>
Latitude:<br/>
<input name='lat' value={this.state.lat}
placeholder="Enter Your Farm Latitude"
onChange={e => this.handleChange(e)}/>
</label><br/>
<Link><a href="https://www.latlong.net/" target="_blank">
Get Longitude and Latitude of current location here</a></Link><br/>
<button onClick={e => this.handleSubmit(e)}
disabled={!this.state.name}
disabled={!this.state.long}
disabled={!this.state.lat}
disabled={!this.state.town}>
Register</button>
</form>
</div>
)
}
}
export default Register

Why isn't my React Form sending?

I've used this tutorial offline and I have this:
import React from 'react';
import '../Normalize.css';
import '../App.css';
import $ from 'jquery';
class ReactFormLabel extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<label htmlFor={this.props.htmlFor}>{this.props.title}</label>
)
}
}
class ReactForm extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
subject: '',
message: ''
}
}
handleChange = (e) => {
let newState = {};
newState[e.target.name] = e.target.value;
this.setState(newState);
};
handleSubmit = (e, message) => {
e.preventDefault();
let formData = {
formSender: this.state.name,
formEmail: this.state.email,
formSubject: this.state.subject,
formMessage: this.state.message
}
if (formData.formSender.length < 1 || formData.formEmail.length < 1 || formData.formSubject.length < 1 || formData.formMessage.length < 1) {
return false;
}
$.ajax({
url: '/some/url',
dataType: 'json',
type: 'POST',
data: formData,
success: function(data) {
if (window.confirm('Thank you for your message. Can I erase the form?'))
{
document.querySelector('.form-input').val('');
}
},
error: function(xhr, status, err) {
console.error(status, err.toString());
alert('There was some problem with sending your message.');
}
});
this.setState({
firstName: '',
lastName: '',
email: '',
subject: '',
message: ''
});
};
render() {
return(
<form className='react-form' onSubmit={this.handleSubmit}>
<fieldset className='form-group'>
<ReactFormLabel htmlFor='formName' title='Full Name:' />
<input id='formName' className='form-input' name='name' type='text' required onChange={this.handleChange} value={this.state.name} />
</fieldset>
<fieldset className='form-group'>
<ReactFormLabel htmlFor='formEmail' title='Email:' />
<input id='formEmail' className='form-input' name='email' type='email' required onChange={this.handleChange} value={this.state.email} />
</fieldset>
<fieldset className='form-group'>
<ReactFormLabel htmlFor='formSubject' title='Subject:'/>
<input id='formSubject' className='form-input' name='subject' type='text' required onChange={this.handleChange} value={this.state.subject} />
</fieldset>
<fieldset className='form-group'>
<ReactFormLabel htmlFor='formMessage' title='Message:' />
<textarea id='formMessage' className='form-textarea' name='message' required onChange={this.handleChange}></textarea>
</fieldset>
<div className='form-group'>
<input id='formButton' className='btn' type='submit' placeholder='Send message' />
</div>
</form>
)
}
};
export default ReactForm;
I think it has something to do with this section:
$.ajax({
url: '/some/url',
dataType: 'json',
type: 'POST',
data: formData,
success: function(data) {
if (window.confirm('Thank you for your message. Can I erase the form?'))
{
document.querySelector('.form-input').val('');
}
With the URL but I'm not too sure where to send it to? Is there something very simple I am overlooking here? It renders fine, it validates fine, it's just not sending. I followed this tutorial: https://blog.alexdevero.com/insanely-easy-simple-react-form-tutorial/
Thanks!
You must bind your functions to the component like so:
class ReactForm extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
subject: '',
message: ''
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
Also, here are the react docs detailing forms: https://facebook.github.io/react/docs/forms.html

Resources