0

I'm struggling to enter a value whenever a user enters a value when edit is selected, it will not let me enter a value.

I suspect it should be something to do with the onChange method, I'm not sure what I should do. I think the onChange method is right.

I read a question similar to this, but doesn't have the solution I'm looking for.

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} from '../actions/';
import PostItem from './PostItem';
const Styles = {
    myPaper: {
        margin: '20px 0px',
        padding: '20px'
    }
}
class PostList extends Component{
    constructor(props){
        super(props);
        this.state ={
            isEditing:false,
            isEditingId:null
        }
    }
    // Return a new function. Otherwise the DeletePost action will be dispatch each
     // time the Component rerenders.
    removePost = (id) => () => {
        this.props.DeletePost(id);
    }
    // this will be onChange used for the <Editable component/>
    onChange = (e) => {
        e.preventDefault();
        this.setState({
            [e.target.title]: e.target.value
        })
    }

    formEditing = (id) => ()=> {
        this.setState({
            isEditingId: id
          });
    }

    render(){
        const {posts, editForm, isEditing, editChange} = 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 editChange={this.onChange} editForm={this.formEditing} isEditing={this.state.isEditingId === post.id} removePost={this.removePost} {...post} />
                    </Paper>
                ))}
            </div>
        )
    }
}
const mapDispatchToProps = (dispatch) => ({
    // Pass id to the DeletePost functions.
    DeletePost: (id) => dispatch(DeletePost(id))
});
export default connect(null, mapDispatchToProps)(PostList);

Editable.js

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"
            variant="outlined"/>

    </div>
)

export default Editable; 

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';
const Styles = {
    myPaper: {
        margin: '20px 0px',
        padding: '20px'
    }
}
// editChange will passed in as an argument. So the <Editable/> component can 
//use it
const PostItem = ({ title, id,  removePost, createdAt, post_content, username, editForm, isEditing, editChange}) => {
    return(
         <div>
                <Typography variant="h6" component="h3">
                {/* if else teneray operator */}
                {isEditing ? (
                    <Editable editField={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>
                ):(
                    <Button variant="outlined" type="submit" onClick={editForm(null)}>
                        Update
                    </Button>
                )}
                <Button
                    variant="outlined"
                    color="primary"
                    type="submit"
                    onClick={removePost(id)}>
                    Remove
                </Button>
        </div>
    )
}
export default PostItem;

update()

I want to keep the current title value instead of deleting the value.

enter image description here

enter image description here

kcrisman
  • 4,374
  • 20
  • 41
randal
  • 1,272
  • 3
  • 23
  • 48

1 Answers1

2

I think you are not passing down your title state correctly. Add these to your state to initialize to empty:

this.state ={
     isEditing:false,
     isEditingId:null,
     title: ""
}

onChange to this

  onChange = (e) => {
        e.preventDefault();
        this.setState({
            title: e.target.value
        })
    }

PostItem to this

const PostItem = ({ title, id,  removePost, createdAt, post_content, username, editForm, isEditing, editChange }) => {
    return(
         <div>
                <Typography variant="h6" component="h3">
                {/* if else teneray operator */}
                {isEditing ? (
                    <Editable editField={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>
                ):(
                    <Button variant="outlined" type="submit" onClick={editForm(null)}>
                        Update
                    </Button>
                )}
                <Button
                    variant="outlined"
                    color="primary"
                    type="submit"
                    onClick={removePost(id)}>
                    Remove
                </Button>
        </div>
    )
}
export default PostItem;

Then pass down title to your PostItem as props,

for example

 <PostItem title={this.state.title} editChange={this.onChange} editForm={this.formEditing} isEditing={this.state.isEditingId === post.id} removePost={this.removePost} {...post} />

update

change this

<Editable editField={myTitle} editChange={editChange}/>

to(this makes it so the title is appended in the values while you can still edit the value feel free to improve this) it acts a little buggy or wierd but it work.

 <Editable editField={title} editChange={editChange}/>
Ange
  • 138
  • 7
  • How would i pass the title to postItem props, can you demonstrate how i would do that ? thanks :) – randal Apr 16 '19 at 02:16
  • this don't seem to work, let me see what im doing wrong – randal Apr 16 '19 at 02:24
  • I also think there's a problem with your onChange function. You are using event.target.title but it is not defined. Can you also change into this: this.setState({ [event.target.name]: e.target.value }) – Ange Apr 16 '19 at 02:32
  • i got it working, im going to make an edit to you answer. – randal Apr 16 '19 at 02:33
  • Is their a way i can do this `editField={myTitle}`. Like edit the the title that is already set. You know what i mean ? – randal Apr 16 '19 at 02:37
  • as of now, when i click edit it deletes the value that is already set. I'll show an example – randal Apr 16 '19 at 02:38
  • Just wondering if you really need the update button? Since you are using a TextField you could just click on the text field and edit the current Title – Ange Apr 16 '19 at 02:53
  • im going to need it later to update the value on back end. – randal Apr 16 '19 at 02:54
  • i just want the {title} to append to the value. – randal Apr 16 '19 at 02:54
  • i think i figured it out. let me know your thoughts. – randal Apr 16 '19 at 03:09
  • Ok got it. Based on reading your code, I think you're displaying the title props but you are editing the myTitle props. I think it should be the same like, {isEditing ? ( ): (
    {myTitle}
    )}
    – Ange Apr 16 '19 at 03:11
  • i just updated it check the edit, let me know ur thoughts. – randal Apr 16 '19 at 03:12
  • I just checked your edit, It should work but you will be using two variables. Which I think using one is enough. Why not directly edit title instead of declaring another variable called myTitle? Altho I'm not sure if you need those two variables on other parts of your code. – Ange Apr 16 '19 at 03:20
  • can you please show me in code how you would do it, its hard to understand in words. – randal Apr 16 '19 at 03:21
  • Sure. I improved your edit :) With this, you will just be editing the title only and display the updated one – Ange Apr 16 '19 at 03:26
  • thanks for the edit, but when changing mytitle to title which title is actually the mapped post attribute. It leads me back to square one, where i can not enter a value in the input field. – randal Apr 16 '19 at 03:31
  • I see. Well I guess appending should be fine – Ange Apr 16 '19 at 03:34
  • nevermind its too much work putting it up on sandbox. Ill just leave it like it is. Thank you for your time and effort. – randal Apr 16 '19 at 03:36