Search code examples
javascriptreactjsdraftjs

enable button to submit only when all the fields are filled


I have a form which has 3 field. First two fields are email_from and email_subject and the last field is an editor. I have used draftjs for editor. If there is no editor i could enable and disable the submit button but due to the inclusion of the editor i did not know how can i enable the button only when all the fields are filled with no error.

Here is my code.

AdminEditor is the component which has draftjs editor

class EmailTemplate extends React.Component {
  state = {
    emailSubject: '',
    emailFrom: ''
  };

  handleChange = event =>
    this.setState({ [event.target.name]: event.target.value });

  handleSubmit = event => {
    event.preventDefault();
  };

  render() {
    const { emailSubject, emailFrom } = this.state;
    return (
      <form onSubmit={this.handleSubmit}>
        <FieldGroup
          id="formControlsText"
          name="emailSubject"
          type="text"
          label="Email Subject"
          placeholder="Enter Email Form"
          onChange={this.handleChange}
          validationState={emailSubject ? 'success' : 'error'}
          required
        />
        <FieldGroup
          id="formControlsText"
          name="emailFrom"
          type="email"
          label="Email From"
          placeholder="Enter Email From"
          onChange={this.handleChange}
          validationState={emailFrom ? 'success' : 'error'}
          required
        />
        <AdminEditor />
        <Button type="submit">
          Submit
        </Button>
      </form>
    );
  }
}

export default EmailTemplate;

class AdminEditor extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      editorState: EditorState.createEmpty(),
      isEmpty: true
    };
  }

  onEditorStateChange = editorState => {
    this.setState({
      editorState
    });
  };

  onEditorChange = editorContent => {
    this.setState({
      editorContent
    });
  };

  handleChange = event =>
    this.state.editorState.getCurrentContent().hasText()
      ? this.setState({ isEmpty: false })
      : this.setState({ isEmpty: true });

  render() {
    const { editorState } = this.state;
    return (
      <div>
        <Editor
          editorState={this.state.editorState}
          initialContentState={rawContentState}
          toolbarClassName="home-toolbar"
          wrapperClassName="home-wrapper"
          editorClassName="home-editor"
          onEditorStateChange={this.onEditorStateChange}
          toolbar={{
            textAlign: { inDropdown: true },
          }}
          onContentStateChange={this.onEditorChange}
          placeholder="write text here..."
          onChange={this.handleChange}
        />
      </div>
    );
  }
}

export default AdminEditor;

Can anyone please help me?


Solution

  • There are many ways to do this, mostly based around passing some callbacks down into the controlled component which updates the state in the parent. A simple way would be to pass a handler that sets a flag if the editor is empty or not:

    class AdminEditor extends React.PureComponent {
    
    ...
    
      handleChange = event =>
        this.props.setEditorIsEmpty(
          this.state.editorState.getCurrentContent().hasText()
        );
    

    Then in EmailTemplate:

    setEditorIsEmpty(editorIsEmpty) {
      this.setState({
        editorIsEmpty
      });
    }
    
    render() {
      const { emailSubject, emailFrom } = this.state;
      return (
        <form onSubmit={this.handleSubmit}>
    
          ...
    
          <AdminEditor
            setEditorIsEmpty={this.setEditorIsEmpty}
          />
          <Button
            type="submit"
            disabled={!emailSubject || !emailFrom || editorIsEmpty}>
            Submit
          </Button>
        </form>
      );
    }