Binding and saving react button value - reactjs

I am trying to save the value of the button as a string.If i click residence button it will save the value in categoryName as 'residence' or 'commercial' and redirect to another page .I have built a Rest API in the backend to bind and save the value in database.The code is something like this
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
class CustomizedButtons extends React.Component {
constructor(props) {
super(props);
this.state = {
apiUrl:config.publicRuntimeConfig.publicRuntimeConfigValue.apiUrl,
category: " ",
};
}
saveValue = () => {
console.log('savecategory');
axios.post( this.state.apiUrl+'/api/v1/leadsurvey/category', {
'categoryName':this.state.category,
}, {})
};
render() {
const { classes} = this.props;
return (
<div>
<div>
<p>What is the type of your property?</p>
<div>
<button onClick={() => this.saveValue()}>Residence</button>
<button onClick={() => this.saveValue()}>Commercial</button>
</div>
<div style={{marginTop: '90px'}}>
</div>
</div>
</div>
);
}
}
export default CustomizedButtons;
I am not getting how to make it work to bind and save.In case of saving form value i did something like this.
this.state = {
apiUrl:config.publicRuntimeConfig.publicRuntimeConfigValue.apiUrl,
FreeQuoteName :"",
};
this.handleFreeQuoteName = this.handleFreeQuoteName.bind(this);
saveFreeQuote = () => {
console.log('saveFreeQuote ...', this.state);
axios.post( this.state.apiUrl+'/api/v1/SalesLead/save', {
'name': this.state.FreeQuoteName,
}
}
handleFreeQuoteName(event) { this.setState({ FreeQuoteName: event.target.value }); }
<Form>
<p>Name*</p>
<input maxLength="30" onChange={this.handleFreeQuoteName} value={this.state.FreeQuoteName}
type="text" placeholder="Enter name here"/>
<div style={{textAlign:'center', marginTop:'35px', marginBottom:'22px'}} className={card.disable}>
<button disabled={isDisabled} type="button" fullwidth="true" variant="contained"
onClick={() => this.saveFreeQuote()} style={{padding: '9px 0px'}}>Submit</button>
</Form>
I want to do same for the value button.If i click the button it will save the value as a string and redirect to another page.How can i do it?

from your post I assumed that you want to save button value in state and also want to initiate the axios request while button click.
try to change like below
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import axios from 'axios';
class CustomizedButtons extends React.Component {
constructor(props) {
super(props);
this.state = {
apiUrl:config.publicRuntimeConfig.publicRuntimeConfigValue.apiUrl,
category: "",
};
}
saveValue = (e) => {
console.log('savecategory', e.target.innerHTML);
this.setState({
category: e.target.innerHTML
}, this.makeAxiosRequest);
};
makeAxiosRequest = () => {
axios.post( this.state.apiUrl+'/api/v1/leadsurvey/category', {
'categoryName':this.state.category,
}, {})
};
render() {
const { classes} = this.props;
return (
<div>
<div>
<p>What is the type of your property?</p>
<div>
<button onClick={this.saveValue}>Residence</button>
<button onClick={this.saveValue}>Commercial</button>
</div>
<div style={{marginTop: '90px'}}>
</div>
</div>
</div>
);
}
}
export default CustomizedButtons;
here am using callback function inside setState() to initiate axios request after button value saved in state.
Hope this helps.

Related

React not re-rendering after state change

import React, {Component, Fragment} from 'react'
import axios from 'axios'
import PropTypes from "prop-types";
import { connect } from 'react-redux'
import { postComment } from "../../../actions/comments"
import './styles.scss'
export class Comments extends Component {
constructor(props) {
super(props)
this.state = {
comment: "",
author: null
}
}
static propTypes = {
postComment: PropTypes.func.isRequired
};
componentDidMount() {
axios
.get(`/api/auth/user`)
.then(res => {
const author = res.data.id
this.setState({author});
})
.catch(err => console.log(err));
}
onSubmit(e) {
e.preventDefault();
const variables = {
content: this.state.comment,
post: this.props.post.id,
author: this.state.author
}
this.props.postComment(variables)
this.setState({content: ""});
}
onFieldChange(fieldName) {
return function (event) {
this.setState({[fieldName]: event.target.value});
}
}
render() {
return (
<Fragment>
<div class="input">
<form style={{ display:'flex'}} onSubmit={e => this.onSubmit(e)}>
<div class="input-group">
<input
class="form-control rounded-corner"
style={{width: '100%', borderRadius: '5px'}}
onChange={this.onFieldChange('comment').bind(this)}
value = {this.state.comment}
placeholder="Leave a comments"
/>
<span class="input-group-btn p-l-10">
<button class="btn btn-primary f-s-12 rounded-corner">Comment</button>
</span>
</div>
</form>
</div>
<div>
{/* Comment Lists */}...
))}
</div>
</Fragment>
);
}
}
export default connect(
null,
{ postComment }
)(Comments);
This is a page when I add comments to the posts, which works fine but it doesn't update immediately and I have to refresh. The componentDidMount method uses axios to get current user for setting the author for the current comment. I'm changing the state after the form submit, I can't see what the issue is.

duplicates being created in todo list app

I am creating a todo list where when the user clicks the checkbox "complete" that is next to the todo item, it appears in the complete component however there is a duplicate of that item that is being added as well and i am also having an issue trying to have the checkbox not appear in the completed component...
When a user creates a new todo it appears in the active component first and it has a checkbox next to it called completed and when the user clicks the checkbox it appears in the completed component
import React from 'react';
import Active from './Components/Active';
import Completed from './Components/Completed';
import Todoform from './Components/Todoform';
import './App.css';
class App extends React.Component {
state = {
items: [],
task: '',
id: 0,
completedItems: []
}
handleInput = (event) => {
this.setState({
task: event.target.value
})
}
handleSubmit = (event) => {
event.preventDefault()
const newTask = {
id: this.state.id,
title: this.state.task
}
const updatedItems = [...this.state.items, newTask]
this.setState({
items: updatedItems,
task: '',
id: this.state.id + 1
})
}
handleComplete = (newTask) => {
this.setState({completedItems: [...this.state.items, newTask]})
//console.log(this.state.items)
}
render() {
return (
<div id="main-content">
<h1>Task Lister</h1>
<Todoform
handleChange={this.handleInput}
handleSubmit={this.handleSubmit}
task={this.state.task}
/>
<Active
items={this.state.items}
handleComplete={this.handleComplete}
/>
<Completed
completedItems={this.state.completedItems}
/>
</div>
)
}
}
export default App;
import React from 'react'
class Todo extends React.Component{
state = {
checked: false
}
handleCheck = () => {
this.setState({
checked: !this.state.checked
})
}
handleClick = () => {
this.props.handlecompletedList(this.props.title)
}
render(){
const { title } = this.props
return (
<div className="ui checked checkbox">
<input type="checkbox" checked={this.state.checked} onChange={this.handleCheck}
onClick={this.handleClick}/>
<label>Completed {title}</label>
</div>
)
}
}
export default Todo;
import React from 'react'
import Todo from './Todo'
const Active = (props) => {
const { items, handleComplete } = props
return(
<div id="activeList">
<h2 className="position">Active</h2>
<ul id="tasks">
{
items.map(item => {
return(
<Todo key={item.id} handlecompletedList={handleComplete} title={item.title}/>
)
})
}
</ul>
</div>
)
}
export default Active;
import React from 'react'
import Todo from './Todo'
const Completed = (props) => {
const { completedItems } = props
return(
<div id="completedList">
<h2 className="position">Completed</h2>
<ul id="tasks">
{
completedItems.map(item => {
return(
<Todo key={item.id} title={item.title}/>
)
})
}
</ul>
</div>
)
}
export default Completed
import React from 'react';
class Todoform extends React.Component {
render(){
const {task, handleChange, handleSubmit} = this.props;
return(
<form onSubmit={handleSubmit}>
<label>Task description:</label>
<input type="text" name="name" placeholder="description" value={task} onChange={handleChange}/>
<button>Create New Task</button>
</form>
)
}
}
export default Todoform;
To hide the checkbox next to completed items you need to use Conditional Rendering. An example would be to add a prop IsCompleted to your component and use it when rendering html like this:
{this.props.isCompleted &&
<input
type="checkbox"
checked={this.state.checked}
onChange={this.handleCheck}
onClick={this.handleClick}/>
}
The duplicate item issue is probably because you use this.state.items in your handleComplete method instead of using this.state.completedItems if this is not the issue, would you mind sharing the code for the Todoform component as well?
EDIT: The item duplicates because when the handleComplete is called it copies this.state.items to the list and adds the one that you clicked on.
You should use this.state.completedItems in the handleComplete, also you are currently only sending and appending the title in the handleComplete method, you should be appending an object that has a title. The solution would be to update your handleClick method to this and update handleComplete to use this.state.completedItems:
handleClick = () => {
this.props.handlecompletedList({
title: this.props.title
});
};

save range Slider value in state and initiate the axios request while button click

I am trying to save the Range-slider value .If i click "NEXT" i want it save the value in 'Squarefeet' variable and redirect to another page .I have built a Rest API in the backend to bind and save the value in database.The code is something like this
import React, { Component } from 'react'
import Slider from 'react-rangeslider'
import Link from "next/link";
import axios from "axios";
import getConfig from "next/config";
const config = getConfig();
class Horizontal extends Component {
constructor (props, context) {
super(props, context)
this.state = {
apiUrl:config.publicRuntimeConfig.publicRuntimeConfigValue.apiUrl,
}
}
handleChangeStart = () => {
console.log('Change event started')
};
handleChange = value => {
this.setState({
value: value
})};
handleChangeComplete = () => {
console.log('Change event completed')
};
saveValue = () => {
console.log('saveValue ...', this.state);
axios.post( this.state.apiUrl+'/api/v1/LeadSurvey/save', {
'squareFeet':this.state.value,
}, {} )
};
render () {
const { value } = this.state
return (
<div>
<div className='slider' style={{ marginTop:'165px',marginLeft:'319px',width:'700px',backgroundColor:'EF5350'}} >
<Slider min={850} max={5000} value={value} onChangeStart={this.handleChangeStart}
onChange={this.handleChange}
onChangeComplete={this.handleChangeComplete}
/>
<div className='value'>{value} Squarefeet</div>
<div style={{marginTop:'86px'}}>
<Link prefetch href="/estimate"><a href="#" >
<span onChange={this.handleChange} onClick={() => this.saveValue()} >Next</span></a></Link>
</div>
</div>
</div>
)
}
}
export default Horizontal
I am not getting how to make it work to bind and save.How should i do it?

Why is my method Render Props of the React Component not working?

I have a problem. I'm trying do the method Render Prop but it not is working.
My project is: It has to render some names of ComponentDidMount, and I can get it to do the filter and to filter the names. But I passed the function filter for a component, and do the Render Prop.
I pass it here:
import React from 'react';
import './Body.css';
import { Link } from "react-router-dom";
import axios from 'axios';
import Filter from './Filter';
class Body extends React.Component {
constructor(props) {
super(props);
this.state = {
employee: []
}
}
componentDidMount() {
axios
.get("http://127.0.0.1:3004/employee")
.then(response => this.setState({ employee: response.data }));
}
getName = (filter) => {
const { employee, add } = this.state;
return employee.filter(employee => employee.name.includes(filter)).map(name => (
<div className='item' key={name.id}>
<Link className="link" to={`/user/${name.id}`}>
<div key={name.id}>
<img className="img" alt="imgstatic"
src={`https://picsum.photos/${name.id}`}
/>
</div>
<h1 className="name2"> {name.name} </h1>
</Link>
</div>
));
};
getValueInput = (evt) => {
const inputValue = evt.target.value;
this.setState({ input: inputValue });
}
render() {
return (
<div>
<h4 className="manager"> Hello {this.props.currentManager}, here be all employees available for change. </h4>
<div className="body">
{this.getName()}
</div>
<div className='input'>
<Filter render={this.getName} />
</div>
</div>
)
}
}
export default Body;
And here I get him:
import React from 'react';
class Filter extends React.Component {
constructor() {
super();
this.state = {
input: ''
}
}
getValueInput = (evt) => {
const inputValue = evt.target.value;
this.setState({ input: inputValue });
console.log();
console.log(this.state.input)
}
render() {
return (
<div>
<input placeholder='Search name here' type="text" onChange={this.getValueInput} />
</div>
)
}
}
export default Filter
But something's not working...
Can someone help me?
You are not at all using the render prop being supplied to the Filter component. Also the objective of render prop is to render the data, go using this.getName() inside the render Body Component isn't correct either(for one you are not passing the filter value to the getName). You would use it like
import React from 'react';
import './Body.css';
import { Link } from "react-router-dom";
import axios from 'axios';
import Filter from './Filter';
class Body extends React.Component {
constructor(props) {
super(props);
this.state = {
employee: []
}
}
componentDidMount() {
axios
.get("http://127.0.0.1:3004/employee")
.then(response => this.setState({ employee: response.data }));
}
getName = (filter) => {
const { employee, add } = this.state;
return employee.filter(employee => employee.name.includes(filter)).map(name => (
<div className='item' key={name.id}>
<Link className="link" to={`/user/${name.id}`}>
<div key={name.id}>
<img className="img" alt="imgstatic"
src={`https://picsum.photos/${name.id}`}
/>
</div>
<h1 className="name2"> {name.name} </h1>
</Link>
</div>
));
};
getValueInput = (evt) => {
const inputValue = evt.target.value;
this.setState({ input: inputValue });
}
render() {
return (
<div>
<h4 className="manager"> Hello {this.props.currentManager}, here be all employees available for change. </h4>
<div className='body'>
<Filter render={this.getName} />
</div>
</div>
)
}
}
export default Body;
and Filter as
import React from 'react';
class Filter extends React.Component {
constructor() {
super();
this.state = {
input: ''
}
}
getValueInput = (evt) => {
const inputValue = evt.target.value;
this.setState({ input: inputValue });
console.log();
console.log(this.state.input)
}
render() {
return (
<React.Fragment>
{this.props.render(this.state.input)}
<div className='input'>
<input placeholder='Search name here' type="text" onChange={this.getValueInput} />
</div>
</React.Fragment>
)
}
}
Note React.Fragment is available from v16.2.0 onwards and if you are not using the relevant version replace React.Fragment with <div>

How to toggle attributes of elements created on child components that were generated after a form submission

I have the following code where someone can add names into a an array of objects. I can't get to toggle one of the elements created after submission.
import React, { Component } from 'react';
import User from './User';
class App extends Component {
constructor(props){
super(props);
this.state = {
list:list,
searchTerm:'',
userInputValue:'',
users:[],
};
}
userUpdateMethod = e =>
this.setState({
userInputValue:e.target.value
});
newUserSubmitHandler = (e) =>{
e.preventDefault();
this.setState({
users: this.state.users.concat([{name:this.state.userInputValue,isConfirmed:false}]),
userInputValue:""
});
}
toggleAttendance = () =>{
const toggleConfirmed = this.state.users.isConfirmed;
this.setState({
users:!toggleConfirmed
});
}
render() {
const {searchTerm, list} =this.state;
return (
<div className="App">
<User
a = {this.state.userInputValue}
b = {this.userUpdateMethod}
c = {this.newUserSubmitHandler}
d = {this.state.users}
e = {this.toggleAttendance}
/>
</div>
);
}
}
export default App;
The function that I can get to work is toggleAttendance and it resides on the User component
import React, { Component } from 'react';
const User = props =>
<div>
<h2>User Component</h2>
<form onSubmit={props.c}>
<input type="text" onChange={props.b} value = {props.a}/>
<button type="submit" name="submit" value="submit"> Submit</button>
</form>
<div>The follwowing will be attending:{props.d.map((user,index) =>
<div> {user.name} is {user.isConfirmed? "coming":"not coming"}
<button onClick={()=>props.e(index)}>toggle attendance</button>
</div>
)}
</div>
</div>;
export default User;
I have tried several ways to update the toggleAttendance method from the main App component but with no luck

Resources