0

My Objective is to show error to the particular object id when we dont enter any value in the textfield in onChange method. But it is appearing in the other id text field.

JSON data looks in this way:

"details": [
      { "id": "12wer1", "name": "ABC", "age": 15 },
      { "id": "78hbg5", "name": "FRE", "age": 21 }
    ]

I've tried in this way:

{this.state.details.map((y) => (
              <Grid container justify="center" spacing={2}>
                <Grid item xs={3}>
                  <TextField label="Name" name="dName" variant="outlined" value={y.name}
 onChange={(e)=>this.onChange(e.target.name, e.target.value)}
/>
                </Grid>
                <Grid item xs={3}>
                  <TextField label="Age" name="age"variant="outlined" value={y.age} onChange={(e)=>this.onChange(e.target.name, e.target.value)}/>
 <FormHelperText >
                                        {this.state.errors.age}
                                    </FormHelperText>
                </Grid>
              </Grid>
            ))}

OnChange method:

onChange = (name, value)=> {

this.state.details.forEach((item) => {
                    if (!item.age) {
                        errors.age = "age is required";
                    }
                    else {
                        errors.age = ""
                    }


}

I'm getting error in other ids also. for example i want to clear the age for 1st id then error is showing on both the ids.

Can anyone help me to fix this error?

1 Answer 1

1

We will have to something like this.

import React from "react";
import { Grid, TextField, FormHelperText } from "@material-ui/core";
import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      details: [
        { id: "12wer1", name: "ABC", age: 15 },
        { id: "78hbg5", name: "FRE", age: 21 }
      ],
      errors: {
        name: {},
        age: {}
      }
    };

    this.onNameChange = this.onChange.bind(this, "name");
    this.onAgeChange = this.onChange.bind(this, "age");
  }

  onChange = (property, id, e) => {
    const value = e.target.value;
    let { details, errors } = this.state;
    details.forEach((d) => {
      if (d.id === id) {
        d[property] = value;
        errors[property][id] = value === "" ? `${property} is required` : "";
      }
    });

    console.log(errors);

    this.setState({
      details: details,
      errors: errors
    });
  };

  render() {
    return (
      <div className="App">
        {this.state.details.map((y) => (
          <Grid container justify="center" spacing={2}>
            <Grid item xs={3}>
              <TextField
                label="Name"
                name="dName"
                variant="outlined"
                value={y.name}
                onChange={(e) => this.onNameChange(y.id, e)}
              />
              <FormHelperText>
                {this.state.errors.name[y.id] || ""}
              </FormHelperText>
            </Grid>
            <Grid item xs={3}>
              <TextField
                label="Age"
                name="age"
                variant="outlined"
                value={y.age}
                onChange={(e) => this.onAgeChange(y.id, e)}
              />
              <FormHelperText>
                {this.state.errors.age[y.id] || ""}
              </FormHelperText>
            </Grid>
          </Grid>
        ))}
      </div>
    );
  }
}

We basically have to link each error's object with it's specific rendered element. Here is the running code for the same: codesandbox

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.