Ayesha
Ayesha

Reputation: 221

Form-Clearing all the text and other components element when clicked on button

I have created a simple form with inputtext field, select options, radiobuttons and textArea. I have even created 2 button, one for submit and one to 'Clear' all the text from the Form. I can clear text from inputfield and the textarea's text, I have created a callback function in parentClass (Form.js) and from there I have sended the data as props to TextArea.js class

       <TextArea
          callbackFromParent={this.parentCallback}
        />

and when i clicked on 'Clear All' button, the textInput field and textarea clears up.So i thought to implement in the same way for 'Select' option and for other components. So I created select variable in state and in callback function (parentCallback) setting the select again and sending it as props to component as callbackFromParent, but then i am setting this props value in state as : selectCountry: this.props.callbackFromParent, From Select component I have to send it to TextArea.js component as the 'Clear all' button is there as well the function for it. I am stuck at this point and don't know exactly how to think or implement it. i have looked through Google but not got the answer I am looking for. I want to Clear each and every Form input field text and reset the select options, radiobuttons and so on. I will be gratefull for all the help I can get. Thanks in Advance!

My code link: https://codesandbox.io/s/reactforms-w1y38

Form.js:

import React from "react";
import Select from "./Select";
import SelectGender from "./RadioButton";
import TextArea from "./TextArea";

class Form extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      value: "",
      select: ""
    };
  }

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

  //Child to Parent — Use a callback and states
  // OR WE CAN SAY THAT PARENT NEED data FROM CHILD AND WE DO :
  parentCallback = () => {
    this.setState({
      value: "",
      select: ""
    });
  };

  render() {
    return (
      <div>
        <h3>Child form</h3>
        <label>Enter name: </label>
        <input type="text" value={this.state.value} onChange={this.onChange} />
        <p>You Entered: {this.state.value}</p>

        <Select callbackFromParent={this.parentCallback} />
        <SelectGender />
        <br />
        <TextArea
          callbackFromParent={this.parentCallback}
          //Data passing from parent to child
          dataFromParent={this.state.value}
        />
      </div>
    );
  }
}

export default Form;

-------------------------

Select.js

import React from "react";

class Select extends React.Component {
  state = {
    selectGenderOptions: ["Male", "Female", "Others"],
    selectCountry: this.props.callbackFromParent
  };

  render() {
    console.log("Select props", this.props);
    return (
      <div>
        <label>
          {/* <select selectGenderOptions={this.state.selectGenderOptions} /> */}
          Select Gender:
          <select>
            <option value="select" selected className="text-hide">
              {" "}
              {/*//change the Css style if you dnt want to hide the text */}
              Please select
            </option>
            <option value="male">Male</option>
            <option value="female">Female</option>
            <option value="other">Other</option>
          </select>
        </label>

        <label>
          <h3>Select Country</h3>
          <select>
            <option value="select" selected>
              {" "}
              Select Country{" "}
            </option>

            <option value="ind">India</option>
            <option value="pak">Pakistan</option>
            <option value="bang">Bangladesh</option>
            <option value="dub">Dubai</option>
            <option value="swe">Sweden</option>
            <option value="dan">Danmark</option>
            <option value="usa">USA</option>
            <option value="aus">Australia</option>
          </select>
        </label>
      </div>
    );
  }
}

export default Select;

-----------------------------
TextArea.js

import React from "react";

class TextArea extends React.Component {
  state = {
    textAreaValue: "",
    inputValue: ""
  };

  textAreaHandler = event => {
    this.setState({ textAreaValue: event.target.value });
  };

  onSubmitHandler = () => {
    return `Your comment ${this.state.textAreaValue}`;
  };

  clearAllHandler = e => {
    e.preventDefault();
    this.setState({
      textAreaValue: "",
      inputValue: this.props.callbackFromParent(this.state.inputValue)
    });
  };

  // sendDataFromChild = () => {
  //   this.props.callbackFromParent();
  // };

  render() {
    console.log("inputvalue", this.props);
    console.log("callback", this.props.callbackFromParent);
    return (
      <div>
        <label>
          <h3>Comment:</h3>
          <textarea
            value={this.state.textAreaValue}
            placeholder="Write anything"
            onChange={this.textAreaHandler}
          />
        </label>
        <div>
          <input type="submit" value="Submit" onClick={this.onSubmitHandler} />
          <button onClick={this.clearAllHandler}>Clear All</button>
        </div>
        <p>You wrote: {this.state.textAreaValue}</p>
        <p>Data Coming From Parent AS props: {this.props.dataFromParent}</p>
      </div>
    );
  }
}

export default TextArea;

enter image description here

Upvotes: 1

Views: 1432

Answers (2)

Egor
Egor

Reputation: 268

I noticed some stuff and re-work your code, please see all changes here https://codesandbox.io/s/reactforms-r6w6p?fontsize=14. I removed some fields to show you the basic idea, after that you should be able to apply it to other fields.

Explanation:

  • First things first: react app has a single state, be sure that you don't create a state for every component (I removed all states except one in the Form component), now you have only one source of truth. Well actually you have one more state in index.js so you still need to do a small clean up and pass the state down to your Form component. I hope you got the idea.
  • Events and values have to be passed as props from parent to child components (see how I done it for Select and ButtonRow), and then they have to be called like so this.props.myFunc().
  • Make your select controllable via attributes value and onChange event (see in the code).

Let me know if it's not what are you looking for.

Upvotes: 2

Tony B
Tony B

Reputation: 11

You may want to try changing:

<input type="submit" value="Submit" onClick={this.onSubmitHandler} />

to:

<input type="button" value="Submit" onClick={this.onSubmitHandler} />

By default "submit" is going to try to submit the data and wait for a response. Setting it to a type of button to "button" should not try to submit anymore.

Upvotes: 1

Related Questions