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 !!!!!!!!!!!!!!
Related
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
Hi I need to pass two parameters, to the class Chat. Currently it is getting only one parameter and displaying correctly.
const Chat = props => (
<div >
<ul>{props.messages.map(message => <li key={message}>{message}</li>)}</ul>
</div>
);
This Chat.js file is called from the Home.js. Suppose I need to pass the Chat component two parameters and I tried it like following.
import React, { Component } from 'react';
import { User } from './User';
import Chat from './Chat';
export class Home extends Component {
displayName = Home.name
state = {
messages: [],
names: []
};
handleSubmit = (message,name) =>
this.setState(currentState => ({
messages: [...currentState.messages, message],
names: [...currentState.names,name]
}));
render() {
return (
<div>
<div>
<User onSubmit={this.handleSubmit} />
</div>
<div>
<Chat messages={this.state.messages,this.state.name} />
</div>
</div>
);
}
}
In this scenario how should I change the Chat component to accept two parameters and display inside div tags.
This is what I tried. But seems it is incorrect.
const Chat = props => (
<div >
<ul>{props.messages.map((message, name) => <li key={message}>{message}</li> <li key={name}>{name}</li>)}</ul>
</div>
);
PS: The User Method
import * as React from 'react';
export class User extends React.Component{
constructor(props) {
super(props);
this.state = {
name: '',
message: ''
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
render() {
return (
<div className="panel panel-default" id="frame1" onSubmit={this.handleSubmit}>
<form className="form-horizontal" action="/action_page.php" >
<div className="form-group">
<label className="control-label col-sm-2" htmlFor="name">Your Name </label>
<div className="col-sm-10">
<input type="text" className="form-control" name="name" placeholder="Enter your Name" onChange={this.handleChange} />
</div>
</div>
<div className="form-group">
<label className="control-label col-sm-2" htmlFor="message">Message</label>
<div className="col-sm-10">
<input type="text" className="form-control" name="message" placeholder="Enter your Message" onChange={this.handleChange}/>
</div>
</div>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button type="submit" id="submit" className="btn btn-default">Submit</button>
</div>
</div>
</form>
</div>
);
}
handleChange(evt) {
this.setState({ [evt.target.name]: evt.target.value });
}
handleSubmit = (e) => {
e.preventDefault();
this.props.onSubmit(this.state.message, this.state.name);
this.setState({ message: "" });
this.setState({name:""});
};
}
You can do this by using separate attributes to pass different props. So for instance, you might revise your <Home/> components render method like so:
<Chat messages={this.state.messages} names={this.state.names} />
and then to access these two bits of data (messages and name) from inside the <Chat /> component you could do the following:
const Chat = props => (
<div >
<ul>{props.messages.map((message, index) => <li key={message}>
From: { Array.isArray(props.names) ? props.names[index] : '-' }
Message: {message}</li>)}
</ul>
</div>
);
Hope this helps!
You have to pass them separately:
<Chat messages={this.state.messages} name={this.state.name} />
I am new to ReactJS and trying to build a sample application
I am unable to get enter the value in textbox and unable to get the value in alert. Am I doing something wrong. I have tried the example given on React.Js Form, but not working.
import React, { Component } from "react";
class AddNewStudent extends Component {
constructor(props) {
super(props);
this.state = {value:''};
this.OnSubmit = this.OnSubmit.bind(this);
}
OnSubmit(event){
alert('name value is : '+this.state.value);
event.preventDefault();
}
render(){
return(
<div>
<form onSubmit={this.OnSubmit}>
<fieldset className="Student-Form" id={this.props.id}>
<legend className="Legend">Add mew student</legend>
<div>
<div className="Block">
<div className="Float-Left">
<label>
<span>Name : </span>
<input type="text" value={this.state.value} />
</label>
</div>
</div>
<div className="clearFix" />
<div className="Block">
<div className="Float-None">
<label>
<input type="submit" value="Save" />
</label>
</div>
</div>
</div>
</fieldset>
</form>
</div>
);
}
}
export default AddNewStudent;
please change :
<input type="text" value={this.state.value} />
to:
<input type="text" value={this.state.value} onChange = {this.onChange}/>
In your class, add the 'onChange' function:
onChange(e){
this.setState({
value: e.target.value
})
}
and in your constructor:
this.onChange = this.onChange.bind(this)
Edit 1:
please check my codepen here
Edit 2:
If you have too many inputs, you can use a function like this:(it's just a rough example, in real world I'll create a new component to handle this together)
//in your constructor
this.state = {}
//in class 'controlled component way'
createInput(num){
let inputArray = []
for(let i = 0; i < num; i ++){
inputArray.push(<input key = {i} name = {i} onChange = {this.onChange} value = {this.state[i] || ''} />)
}
return inputArray
}
onChange(e){
let key = e.target.name
let newState = {}
newState[key] = e.target.value
this.setState(newState)
}
// in your render function
return <div>
{this.createInput(100)}
</div>
check my codepen here for this example
and of course you can also do this using uncontrolled component.
controlled component and uncontrolled
You can either bind onChange event to your input or setState when submiting the value , you cant change the state like that
Change your code to something like this
import React, { Component } from "react";
class AddNewStudent extends Component {
constructor(props) {
super(props);
this.state = {value:''};
this.OnSubmit = this.OnSubmit.bind(this);
}
OnSubmit(event){
this.setState({value: this.refs.infield.value},()=>{
alert('name value is : '+this.state.value);
})
event.preventDefault();
}
render(){
return(
<div>
<form onSubmit={this.OnSubmit}>
<fieldset className="Student-Form" id={this.props.id}>
<legend className="Legend">Add mew student</legend>
<div>
<div className="Block">
<div className="Float-Left">
<label>
<span>Name : </span>
<input type="text" ref = "infield"/>
</label>
</div>
</div>
<div className="clearFix" />
<div className="Block">
<div className="Float-None">
<label>
<input type="submit" value="Save" />
</label>
</div>
</div>
</div>
</fieldset>
</form>
</div>
);
}
}
export default AddNewStudent;
Hi to get the value add a name to the input and an onChange function to set the value to the state and then do what evere you want in onsubmit function
I cant write you a working code now because I'm using my phone but my this Will help
onfieldchange(e) {
this.setState({[e.target.name]: e.target.value});
}
onaSubmit(){
//do your code here
}
....
....
<input type="text" name="firstName" value={this.state.firstName} />
Hope this help you
There are two ways to handle form elements in reactjs:
Controlled and uncontrolled components(using refs).In controlled component approach ,you have to add the state of the input field to the input field value and onChange event to it, which is the one you are trying to do.Here is the working code.
import React, { Component } from "react";
class AddNewStudent extends Component {
constructor(props) {
super(props);
this.state = {
firstname:''
};
this.OnSubmit = this.OnSubmit.bind(this);
this.OnChange = this.OnChange.bind(this);
}
OnSubmit(event){
alert('name value is : '+this.state.firstname);
event.preventDefault();
}
OnChange(){
this.setState({
[e.target.name] : [e.target.value]
});
}
render(){
return(
<div>
<form onSubmit={this.OnSubmit}>
<fieldset className="Student-Form" id={this.props.id}>
<legend className="Legend">Add mew student</legend>
<div>
<div className="Block">
<div className="Float-Left">
<label>
<span>Name : </span>
<input type="text"
name="firstname"
value={this.state.firstname}
OnChange={this.OnChange}
/>
</label>
</div>
</div>
<div className="clearFix" />
<div className="Block">
<div className="Float-None">
<label>
<input type="submit" value="Save" />
</label>
</div>
</div>
</div>
</fieldset>
</form>
</div>
);
}
}
export default AddNewStudent;
I have tried with the following code with react js
import React, { Component } from 'react';
import Sidebar from './../Sidebar';
import Header from './../Header';
import {get_profile} from './../services/Services';
import $ from 'jquery';
export default class Profile extends Component {
constructor(props) {
super(props);
this.state = { userDetails: '' } ;
}
componentWillMount() {
$(window).scrollTop(0)
console.log('sdfds')
get_profile().then((response) => {
var userResults = $.parseJSON(response.text);
this.setState({ userDetails: userResults.response });
console.log(userResults);
}).catch((error) => {
//alert(error)
console.log(error);
});
}
handleChange(event) {
console.log(event.target.id)
this.setState({[event.target.name]: event.target.value});
}
render() {
return (
<div className="admin-panel">
<Sidebar />
<Header />
<div className="main-content">
<div className="contents">
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h2 className="page-title">Profile</h2>
<div className="form-group">
<label >First Name</label>
<input type="text" id="firstName" className="form-control" value={this.state.userDetails.firstName} />
</div>
<div className="form-group">
<label >Last Name</label>
<input type="text" id="lastName" className="form-control" value={this.state.userDetails.lastName} />
</div>
<div className="form-group">
<label >Email</label>
<input type="text" id="email" name="email" className="form-control" value={this.state.userDetails.email} />
</div>
<button type="button" className="btn btn-squared btn-success margin-inline" onClick={(e)=> {this.profileUpdate()}}>Update</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
After fetching the results i'm unable to edit the input box value. I have tried with defaultValue but that also not working for me. I'm struck with this issue, Kindly help me to solve the issue.
Just pass an onChange handler to the input which will update the value of the corresponding key of userDetails like this:
<input
...
value={this.state.userDetails.firstName}
onChange={this.onChange}
/>
onChange(e) {
this.setState((previousState) => {
const userDetails = previousState.userDetails
return { userDetails: {...userDetails, firstName: e.target.value} }
})
}
or you can write a common onChange function like this:
<input
...
value={this.state.userDetails.firstName}
onChange={(e) => {this.onChange(e.target.value, 'firstName')}}
/>
<input
...
value={this.state.userDetails.lastName}
onChange={(e) => {this.onChange(e.target.value, 'lastName')}}
/>
<input
...
value={this.state.userDetails.email}
onChange={(e) => {this.onChange(e.target.value, 'email')}}
/>
onChange(value, key) {
this.setState((previousState) => {
const userDetails = previousState.userDetails
return { userDetails: {...userDetails, [key]: value} }
})
}
import React, { Component } from 'react';
class BigText extends Component {
constructor(props) {
super(props);
this.state = {
title: '',
text: '',
summary: ''
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
render() {
return (
<div>
<div>
<div className="row animated fadeIn">
<div className="px-1" style={{ width:100 + '%' }}><br />
<div className="mb-1">
<input type="text"
className="form-control"
placeholder="Title"
name="title"
value={this.state.title}
onChange={this.handleInputChange}
/>
</div>
<div className="mb-1">
<textarea
className="form-control"
placeholder="Text"
name="text"
value={this.state.text}
onChange={this.handleInputChange}
/>
</div>
<div className="mb-1">
<textarea
className="form-control"
placeholder="Summary"
name="summary"
value={this.state.summary}
onChange={this.handleInputChange}
/>
</div>
</div>
<div>
</div>
</div>
</div>
</div>
)
}
}
export default BigText;
import React, { Component } from 'react';
import BigText from './bigText.js';
import InboxStyle from './inboxStyle.js';
import ImageStyle from './imageStyle.js';
import BigTextMobile from './bigText.mobile.js';
import InboxStyleMobile from './inboxStyle.mobile.js';
import ImageStyleMobile from './imageStyle.mobile.js';
class BasicNotification extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleClick = this.handleClick.bind(this);
}
static contextTypes = {
router: React.PropTypes.object
}
handleClick() {
this.context.router.push('/notifications');
}
handleChange(event) {
this.setState({value: event.target.value});
}
checkRadio =(e) =>{
if(e.target.checked) {
this.setState({layout: e.target.value});
}
}
render() {
return (
<div>
<div>
<h1 className="px-2">Create Notification</h1>
<hr />
<div className="row px-1 py-2 animated fadeIn">
<div className="px-1 mr-2" style={{ width:50 + '%' }}><br />
<div className="mb-1">
<input type="text"
className="form-control"
placeholder="Title"
name="title"
/>
</div>
<div className="mb-1">
<textarea
className="form-control"
placeholder="Text"
name="text"
/>
</div>
<div>
<select placeholder="Logo" className="form-control" onChange={this.handleChange}>
<option default>Select Logo</option>
<option>Default</option>
<option>Custom</option>
</select>
</div>
<div><br />
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-css btn-outline-secondary">
<input type="radio" name="layout" value="image" onChange={this.checkRadio}/>ImageStyle
</label>
<label className="btn btn-css btn-outline-secondary">
<input type="radio" name="layout" value="big" onChange={this.checkRadio}/>BigText
</label>
<label className="btn btn-css btn-outline-secondary">
<input type="radio" name="layout" value="inbox" onChange={this.checkRadio}/>InboxStyle
</label>
</div>
{
(this.state.layout === "big")?
<BigText/>:
(this.state.layout === "image")?
<ImageStyle/>:
(this.state.layout === "inbox")?
<InboxStyle/>:
null
}
<br />
<div className="row px-1" >
<div>
<button className="nav-link btn btn-block btn-info" onClick={this.handleClick} >Save</button>
</div>
<div className="px-1">
<button className="nav-link btn btn-block btn-danger"> Cancel</button>
</div>
</div>
</div><br />
</div>
<div>
{
(this.state.layout === "big")?
<BigTextMobile text={this.state.text} summary={this.state.summary} title={this.state.title}/>:
(this.state.layout === "image")?
<ImageStyleMobile/>:
(this.state.layout === "inbox")?
<InboxStyleMobile/>:
null
}
</div>
</div>
</div>
</div>
)
}
}
export default BasicNotification;
This is the screen i made on which I had imported three files which will be shown on clicking radio buttons.
Also there is a relevant mobile screen as well shown aside
now for example i imported as you can see BigText , it is containing the form
Now i want to print its input values in BigTextMobile Component
To simplify the solution you can do something like this:
<BigText onChange={data => {this.setState({ data })}} />
In the BigText component then you can put some data via this callback like this:
handleInputChange(event) {
const data = {
[event.target.name]: event.target.value
};
this.setState(data );
this.props.onChange(data);
}
And transfer this data to your BigTextMobile component from state:
<BigTextMobile data={this.state.data} ... />