Reputation: 1372
How can i tell onChange to set the disable button to true on the update button, if this.state.title is less than 3 characters, i made an attempt but it wont let me enter a value. It breaks the code pretty much. I want the update to be passed to redux.
here is what i have, disclaimer some code has been removed to be more relevant.
PostItem.js
import React, { Component } from 'react';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import moment from 'moment';
import Editable from './Editable';
import {connect} from 'react-redux';
import {UpdatePost} from '../actions/';
const Styles = {
myPaper: {
margin: '20px 0px',
padding: '20px'
},
button:{
marginRight:'30px'
}
}
class PostItem extends Component{
constructor(props){
super(props);
this.state = {
disabled: false,
}
}
onUpdate = (id, title) => () => {
// we need the id so expres knows what post to update, and the title being that only editing the title.
if(this.props.myTitle !== null){
const creds = {
id, title
}
this.props.UpdatePost(creds);
}
}
render(){
const {title, id, removePost, createdAt, post_content, username, editForm, isEditing, editChange, myTitle, postUpdate} = this.props
return(
<div>
<Typography variant="h6" component="h3">
{/* if else teneray operator */}
{isEditing ? (
// need a way to disable update button if the value is less than 3 characters
<Editable editField={myTitle ? myTitle : title} editChange={editChange}/>
): (
<div>
{title}
</div>
)}
</Typography>
<Typography component="p">
{post_content}
<h5>
by: {username}</h5>
<Typography color="textSecondary">{moment(createdAt).calendar()}</Typography>
</Typography>
{!isEditing ? (
<Button variant="outlined" type="submit" onClick={editForm(id)}>
Edit
</Button>
):(
// pass id, and myTitle which as we remember myTitle is the new value when updating the title
// how would i set disabled to false if the value from editField is less than 3 charaters.
<Button
disabled={this.state.title.length > 3 }
variant="outlined"
onClick={this.onUpdate(id, myTitle)}>
Update
</Button>
)}
<Button
style={{marginLeft: '0.7%'}}
variant="outlined"
color="primary"
type="submit"
onClick={removePost(id)}>
Remove
</Button>
</div>
)
}
}
const mapStateToProps = (state) => ({
disabled: state.post.disabled
})
const mapDispatchToProps = (dispatch) => ({
// pass creds which can be called anything, but i just call it credentials but it should be called something more
// specific.
UpdatePost: (creds) => dispatch(UpdatePost(creds)),
// Pass id to the DeletePost functions.
});
export default connect(mapStateToProps, mapDispatchToProps)(PostItem);
editChange is being called from this onChange method
PostList.js
import React, { Component } from 'react';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import moment from 'moment';
import {connect} from 'react-redux';
import {DeletePost, UpdatePost,EditChange, DisableButton} from '../actions/';
import PostItem from './PostItem';
const Styles = {
myPaper: {
margin: '20px 0px',
padding: '20px'
}
}
class PostList extends Component{
constructor(props){
super(props);
this.state ={
title: ''
}
}
// Return a new function. Otherwise the DeletePost action will be dispatch each
// time the Component rerenders.
removePost = (id) => () => {
this.props.DeletePost(id);
}
onChange = (e) => {
e.preventDefault();
this.setState({
title: e.target.value
})
}
formEditing = (id) => ()=> {;
this.props.EditChange(id);
}
render(){
const {posts} = this.props;
return (
<div>
{posts.map((post, i) => (
<Paper key={post.id} style={Styles.myPaper}>
{/* {...post} prevents us from writing all of the properties out */}
<PostItem
myTitle={this.state.title}
editChange={this.onChange}
editForm={this.formEditing}
isEditing={this.props.isEditingId === post.id}
removePost={this.removePost}
{...post}
/>
</Paper>
))}
</div>
)
}
}
const mapStateToProps = (state) => ({
// disabled: state.post.disabled,
isEditingId: state.post.isEditingId
})
const mapDispatchToProps = (dispatch) => ({
// pass creds which can be called anything, but i just call it credentials but it should be called something more
// specific.
EditChange: (id) => dispatch(EditChange(id)),
UpdatePost: (creds) => dispatch(UpdatePost(creds)),
// Pass id to the DeletePost functions.
DeletePost: (id) => dispatch(DeletePost(id))
});
export default connect(mapStateToProps, mapDispatchToProps)(PostList);
Action for this.props.DisableButton
export const DisableButton = () => {
return(dispatch) => {
dispatch({type:DISABLED});
}
}
Posts reducer for disable button, etc.
import { DISABLED} from '../actions/';
const initialState = {,
disabled: false,
isEditingId:null
}
export default (state = initialState, action) => {
switch (action.type) {
case DISABLED:
return({
...state,
disabled:true
})
default:
return state
}
}
editable component
import React from 'react';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import TextField from '@material-ui/core/TextField';
const Editable = (props) => (
<div>
<TextField
id="outlined-name"
label="Title"
style={{width: 560}}
name="title"
value={props.editField}
onChange={props.editChange}
margin="normal"
required
variant="outlined"/>
</div>
)
export default Editable;
Upvotes: 0
Views: 118
Reputation: 1208
You don't need to call DisableButton
method to disable its value.
Fix your onChange
, perhaps roughly like this:
onChange = (e) => {
this.setState({ title: e.target.value });
}
yes, this is sufficient.
now you can use a logic to disable the Button
component, like this:
<Button
disabled={this.state.title.length <= 3}
// rest of the attributes
/>
You don't need to use disabled props on redux. It's not necessary since you can just move the logic by using local state of title
directly on Button
component.
==== edit
you need to initialize this.state.title first
constructor(props) {
super(props);
this.state = {
title: '',
}
}
=== edit 2nd time after the questioner added some details
If this.state.title
is on PostList
(the parent component) component and your Button
is accessing it through myTitle
props since it's on PostItem
component. You can do it like this:
<Button
disabled={this.props.myTitle.length <= 3}
// rest of the attributes
/>
Upvotes: 1