React JS input field not behaving as expected - reactjs

I am creating a contact form using React JS and this is my code:
import React, { Component } from 'react';
export default class Create extends Component {
constructor(props) {
super(props);
this.onChangeFirstname = this.onChangeFirstname.bind(this);
this.onChangeLastname = this.onChangeLastname.bind(this);
this.onChangeMessage = this.onChangeMessage.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
person_firstname: '',
person_lastname: '',
message:''
}
}
onChangeFirstname(e) {
this.setState({
person_firstname: e.target.value
});
}
onChangeLastname(e) {
this.setState({
person_lastname: e.target.value
})
}
onChangeMessage(e) {
this.setState({
message: e.target.value
})
}
onSubmit(e) {
e.preventDefault();
console.log(`The values are ${this.state.person_firstname}, ${this.state.person_lastname}, and ${this.state.message}`)
this.setState({
person_firstname: '',
person_lastname: '',
message: ''
})
}
render() {
return (
<div style={{marginTop: 10}}>
<h3>Contact Form</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>First Name: </label>
<input type="text" className="form-control"
onChange={this.onChangeFirstName}/>
</div>
<div className="form-group">
<label>Last Name: </label>
<input type="text" className="form-control"
onChange={this.onChangeLastname}/>
</div>
<div className="form-group">
<label>Message: </label>
<textarea className="form-control"
onChange={this.onChangeMessage}>
</textarea>
</div>
<div className="form-group">
<input type="submit" value="Submit" className="btn btn-primary"/>
</div>
</form>
</div>
)
}
}
Everything seems fine, but the code gives a wrong result.
When I enter the following,
I get the following result
No matter what I enter in the first name field, it is ignored and I get a blank in the result.
I tried moving the Lastname input field above the Firstname input field and I still get the first input (Lastname) as blank in the console.

i refactor your code and everything looks fine ...
import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
export default class App extends Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
firstname: "",
lastname: "",
message: ""
};
}
handleChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
onSubmit(e) {
e.preventDefault();
console.log(this.state);
this.setState({
firstname: "",
lastname: "",
message: ""
});
}
render() {
return (
<div style={{ marginTop: 10 }}>
<h3>Contact Form</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>First Name: </label>
<input
type="text"
name="firstname"
className="form-control"
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<label>Last Name: </label>
<input
type="text"
name="lastname"
className="form-control"
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<label>Message: </label>
<textarea
name="message"
className="form-control"
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<input type="submit" value="Submit" className="btn btn-primary" />
</div>
</form>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

you have a typo, onChangeFirstname should have a capital N onChangeFirstName

Related

How to display an unordered list into a JSX <ul> element in a React Form using class component

I'd like to write an unordered list compiled from a form's input values into a <ul> when I click on the Submit button. It's a controlled form in a class based component. Unfortunately I haven't found out how I can achieve it without hooks.
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
message: "",
demo: "",
};
this.changeHandler = this.changeHandler.bind(this);
this.submitFormHandler = this.submitFormHandler.bind(this);
}
changeHandler = (e) => {
this.setState = {
name: e.target.value,
email: e.target.value,
message: e.target.value,
demo: `
<li>${this.state.name}</li>
<li>${this.state.email}</li>
<li>${this.state.message}</li> `
};
this.setState(this.setState)
};
submitFormHandler = (e) => {
e.preventDefault();
// I guess the solution will be here somehow
};
render() {
return (
<form onSubmit={this.submitFormHandler} >
<label htmlFor="name">Name:</label> <br/>
<input id="name" type="text" value={this.state.name} onChange={this.changeHandler} />
<br/>
<label htmlFor="mail">E-mail:</label> <br/>
<input id="mail" type="email" value={this.state.email} onChange={this.changeHandler} />
<br/>
<label htmlFor="msg">Message:</label> <br/>
<textarea id="msg" type="email" value={this.state.message} onChange={this.changeHandler} />
<h4>Values of the inputs:</h4>
<ul id="demo">
{this.state.demo} {/* the list would be here! */}
</ul>
<button type="submit">Submit</button>
</form>
); }
};
To show something when it is submitted I would make a isSubmitted flag. Also you controlled inputs were not working. When inputs ids are corresponding with names in state we can easier handle them in onChange handler function. Also when it is submitted we can prevent user from updating data in changeHandler with early return. So I fixed it in code below:
// import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: '',
isSubmitted: false,
};
this.changeHandler = this.changeHandler.bind(this);
this.submitFormHandler = this.submitFormHandler.bind(this);
}
changeHandler = ({ target }) => {
if (this.state.isSubmitted) return;
this.setState({ [target.id]: target.value });
};
submitFormHandler = (e) => {
e.preventDefault();
this.setState({ isSubmitted: true });
};
render() {
return (
<div>
<form onSubmit={this.submitFormHandler}>
<label htmlFor="name">Name:</label> <br />
<input
id="name"
type="text"
value={this.state.name}
onChange={this.changeHandler}
/>
<br />
<label htmlFor="email">E-mail:</label> <br />
<input
id="email"
type="email"
value={this.state.email}
onChange={this.changeHandler}
/>
<br />
<label htmlFor="message">Message:</label> <br />
<textarea
id="message"
type="email"
value={this.state.message}
onChange={this.changeHandler}
/>
<br />
<button type="submit">Submit</button>
</form>
{this.state.isSubmitted && (
<React.Fragment>
<h4>Values of the inputs:</h4>
<ul>
<li>{this.state.name}</li>
<li>{this.state.email}</li>
<li>{this.state.message}</li>
</ul>
</React.Fragment>
)}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

React: rendering multiple user inputs

I have a form containing several inputs and I am handling multiple user inputs but I want to display all the inputs when the submit button is clicked.
What do I need to add/change in my code to display the inputs when they are submitted?
class Planning extends React.Component {
constructor() {
super()
this.state = {
title: '',
goal: '',
tech: '',
features: '',
details: ''
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
})
}
handleSubmit(event) {
alert(`Plan: ` )
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div>
<label class="label-title">
Project Title:</label>
<input name="title" id="title" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-goal">
Motivational Goal: </label>
<input name="goal" id="goal" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-tech">
Technologies/tools:</label>
<input name="tech" id="tech" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-features">
Features:</label>
<input name="features" id="features" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-details">
Other details: </label>
<input name="details" id="details" type="text" onChange={this.handleChange}/>
</div>
<input class="submit" type="submit" value="Submit" />
</form>
)
}
}
The values are stored in the state so you could
handleSubmit(event) {
event.preventDefault();
alert(`Plan:\n${JSON.stringify(this.state,null,2)}`);
}
or the more explicit approach
handleSubmit(event) {
const {
title,
goal,
tech,
features,
details
} = this.state;
event.preventDefault();
alert(`Plan:
Title: ${title}
Goal: ${goal}
Tech: ${tech}
Features: ${features}
Details: ${details}
`);
}

Input filed is not clickable in react while using value attribute

This is the very beginning of my react learning. I am facing some issue about input field. If I use value field in form then this input filed become unchangeable. Like I can't write anything on that filed. But while I remove value filed it work fine.
Here is my code
import React, { Component } from 'react';
export class Registration extends Component{
constructor(){
super();
this.state = {
name: '',
email: '',
password: '',
};
this.onChange = this.onChange.bind(this);
}
onChange(e){
this.setState = ({
name: e.target.value
});
}
render(){
return(
<div className="registration">
<form name="registration" id="registration" >
<div className="userName">
<label> Name : </label>
<input name="name" type="text" onChange={this.onChange} value={this.state.name}/>
<br/>
</div>
<label> Email : </label>
<input name="email" type="email" />
<br/>
<label> Password : </label>
<input name="password" type="password" />
<br/>
</form>
</div>
);
}
}
On the name input field I am using value attribute. This is making this issue.
The problem is that you accidentally wrote
this.setState = ({
name: e.target.value
});
Instead of
this.setState({
name: e.target.value
});
The = is incorrect, as you're trying to call a method and not declare a variable with a dictionary.
Your this.setState is set wrong.
class Registration extends React.Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: ""
};
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({
name: e.target.value
});
}
render() {
return (
<div className="registration">
<form name="registration" id="registration">
<div className="userName">
<label> Name : </label>
<input
name="name"
type="text"
onChange={e => this.onChange(e)}
value={this.state.name}
/>
<br />
</div>
<label> Email : </label>
<input name="email" type="email" />
<br />
<label> Password : </label>
<input name="password" type="password" />
<br />
</form>
</div>
);
}
}
ReactDOM.render(<Registration />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app" />

react bootstrap table not rendering data without refresh

i am using react-redux with react bootstrap table . my UI is given in picture . when i add payment the data is saved in database. i have used componentdidupdate and componentdidUpdate to render the props data . but nothing is working . the table does not render the data without refresh . please help......................................................................................................
import React from 'react';
import { connect } from 'react-redux';
// import {bindActionCreators} from 'redux'
import { Link } from 'react-router';
import Messages from '../Messages';
import classnames from 'classnames';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import { getCrmOneCustomer, saveStatus, getCrmStatus } from '../../actions/crmAction';
//--------------------------------------------------------------------------
class CrmStatus extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '', shop_name: '', crm_id: '', status: ''
};
this.props.dispatch(getCrmOneCustomer(this.props.params.id));
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
this.props.dispatch(getCrmStatus(this.props.params.id));
}
//--------------------------------------------------------------------------
componentWillReceiveProps(newProps) {
console.log('componentWillReceiveProps............ from edit');
console.log(newProps)
this.setState({
name: newProps.CrmOne.name,
shop_name: newProps.CrmOne.shop_name,
status: newProps.CrmOne.status,
})
}
//--------------------------------------------------------------------------
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
//--------------------------------------------------------------------------
handleSubmit(event) {
event.preventDefault();
var Id = this.props.params.id;
var obj = {};
obj["crm_id"] = Id
obj["name"] = this.state.name
obj["shop_name"] = this.state.shop_name
obj["status"] = this.state.status
console.log(obj)
this.props.dispatch(saveStatus(obj))
}
//--------------------------------------------------------------------------
componentDidUpdate(){
this.products = this.props.CrmOneStatus
}
render() {
return (
<div className="container ca-container">
<div className="row">
<div className="col-md-12">
<h2>CRM Status</h2>
</div>
</div>
<div className="row">
<div className="col-md-12">
<div className ="col-md-8">
<BootstrapTable data={this.products} striped hover pagination={true} search>
<TableHeaderColumn isKey dataField='name'>Name</TableHeaderColumn>
<TableHeaderColumn dataField='status'>status</TableHeaderColumn>
<TableHeaderColumn dataField='createdAt'>Date</TableHeaderColumn>
</BootstrapTable>
</div>
<div className ="col-md-4">
<h4> Add Payment </h4>
<form onSubmit={this.handleSubmit} encType="multipart/form-data">
<div className="form-group">
<label>
Name:
</label>
<input disabled type="text" className="form-control" name="name" value={this.state.name} onChange={this.handleChange} placeholder="Zahid Hasan" />
</div>
<div className="form-group">
<label>
shop name:
</label>
<input type="text" className="form-control" name="shop_name" value={this.state.shop_name} onChange={this.handleChange} placeholder="amount" />
</div>
<div className="form-group">
<label>
Status:
</label>
<textarea rows="8" cols="50" type="text" className="form-control" name="status" value={this.state.status} onChange={this.handleChange} placeholder="comment" />
</div>
<div className="btn-group" role="group">
<button type="submit" className="btn btn-success btn-lg">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
);
}
}
// ======================== REDUX CONNECTORS ========================
const mapStateToProps = (state) => {
return {
CrmOne: state.crmCustomer.CrmOne,
CrmOneStatus: state.crmCustomer.CrmOneStatus
};
};
export default connect(mapStateToProps)(CrmStatus);
You are making a request to fetch the data in the componentDidMount function which is only executed once when the component has mounted, i.e the reason it works when you refresh the page, However you should get the data whenever the props change, i.e. use the componentWillReceiveProps function. Also you don't need to assign the props to the class variable, you can directly use the props to as data.
class CrmStatus extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '', shop_name: '', crm_id: '', status: ''
};
this.props.dispatch(getCrmOneCustomer(this.props.params.id));
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
this.props.dispatch(getCrmStatus(this.props.params.id));
}
componentWillReceiveProps(newProps) {
console.log('componentWillReceiveProps............ from edit');
console.log(newProps)
if(nextProps.params.id !== this.props.params.id) {
this.props.dispatch(getCrmStatus(nextProps.params.id));
}
this.setState({
name: newProps.CrmOne.name,
shop_name: newProps.CrmOne.shop_name,
status: newProps.CrmOne.status,
})
}
//--------------------------------------------------------------------------
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
//--------------------------------------------------------------------------
handleSubmit(event) {
event.preventDefault();
var Id = this.props.params.id;
var obj = {};
obj["crm_id"] = Id
obj["name"] = this.state.name
obj["shop_name"] = this.state.shop_name
obj["status"] = this.state.status
console.log(obj)
this.props.dispatch(saveStatus(obj))
}
//--------------------------------------------------------------------------
render() {
return (
<div className="container ca-container">
<div className="row">
<div className="col-md-12">
<h2>CRM Status</h2>
</div>
</div>
<div className="row">
<div className="col-md-12">
<div className ="col-md-8">
<BootstrapTable data={this.props.CrmOneStatus} striped hover pagination={true} search>
<TableHeaderColumn isKey dataField='name'>Name</TableHeaderColumn>
<TableHeaderColumn dataField='status'>status</TableHeaderColumn>
<TableHeaderColumn dataField='createdAt'>Date</TableHeaderColumn>
</BootstrapTable>
</div>
<div className ="col-md-4">
<h4> Add Payment </h4>
<form onSubmit={this.handleSubmit} encType="multipart/form-data">
<div className="form-group">
<label>
Name:
</label>
<input disabled type="text" className="form-control" name="name" value={this.state.name} onChange={this.handleChange} placeholder="Zahid Hasan" />
</div>
<div className="form-group">
<label>
shop name:
</label>
<input type="text" className="form-control" name="shop_name" value={this.state.shop_name} onChange={this.handleChange} placeholder="amount" />
</div>
<div className="form-group">
<label>
Status:
</label>
<textarea rows="8" cols="50" type="text" className="form-control" name="status" value={this.state.status} onChange={this.handleChange} placeholder="comment" />
</div>
<div className="btn-group" role="group">
<button type="submit" className="btn btn-success btn-lg">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
);
}
}
in constructor i added this
this.props.dispatch(getCrmStatus(this.props.params.id));
and handle submit
this.props.dispatch(getCrmStatus(this.props.params.id));
and it works like charm !!!!!!!!!!!!!!

Account base: options.password must be a string

I looked into some similar problems and added .value. But always get error: options.password must be a string, even I cast the password.value.toString().
import React, {Component} from 'react';
import ReactDom from 'react-dom';
import { Accounts } from 'meteor/accounts-base';
class Register extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit (event){
event.preventDefault();
console.log(this.email.value);
console.log(this.password.value);
const res = Accounts.createUser(this.email.value, this.password.value.toString());
console.log(res);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email:</label>
<input className="form-control" type="email" ref={(email) => this.email = email}/>
</div>
<div className="form-group">
<label htmlFor="password">Password:</label>
<input className="form-control" type="password" ref={(password) => this.password = password}/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">Submit</button>
</div>
</form>
);
}
}
export default Register;
You need to pass an object, not 2 string arguments:
const res = Accounts.createUser({
email: this.email.value,
password: this.password.value,
});
EDIT:
About your React component, using states and controlled components is a better practice than refs:
import React, {Component} from 'react';
import ReactDom from 'react-dom';
import { Accounts } from 'meteor/accounts-base';
class Register extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
}
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange(event) {
const target = event.target;
const name = target.name;
this.setState({
[name]: value,
});
}
handleSubmit (event){
event.preventDefault();
const res = Accounts.createUser({
email: this.state.email,
password: this.state.password,
});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email:</label>
<input className="form-control" type="email" name="email" onChange={this.handleInputChange} />
</div>
<div className="form-group">
<label htmlFor="password">Password:</label>
<input className="form-control" type="password" name="password" onChange={this.handleInputChange} />
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">Submit</button>
</div>
</form>
);
}
}

Resources