0

I am stuck on this for a day now. Have read multiple answers but could not find anything.

My task is simple, I have a page where a user can answer a question.

  • The page will have two editors open(by default). (Found this in a react-quill GitHub discussion).

  • There will be an 'Add step' button which will, of course, add another quill editor below and the user can add as many steps as he/she likes.

  • The editors will have a 'Delete' button alongside it to delete the editors, except for the first two editors.

Now, I want to store the said steps separately in my DB as well, but the onClick on the editor does not have e.target, instead, it just gives the HTML value. Therefore, how can I add editors onClick and separate the value from the multiple editors?

Any direction or hint towards the solution would be appreciated. Thanks.

1 Answer 1

2

You can have separate values by using Array of Objects.

It can be done by having two separate components,

  1. One for RichText Editor,
  2. A main component that has a state (Array of Objects)

I used react-quill library for text editor and react-bootstrap for styling in the following code. You can replace one or both of them of your choice

Create two components:

 - App.js // Main component
 - ReactQuill.js // Editor component 

ReactQuill.js

    import React from "react";
    import ReactQuill from "react-quill";
    
    import "react-quill/dist/quill.snow.css";
    
    class ReactQuillEditor extends React.Component {
      render() {
        const { response, handleChange } = this.props;
        return (
          <ReactQuill
            style={{ marginTop: "4px" }}
            value={response}
            onChange={handleChange}
          />
        );
      }
    }
    
    export default ReactQuillEditor;

App.js

import { useState } from "react";
import { Button } from "react-bootstrap";

// Editor Component
import Editor from "./components/ReactQuill";

export default function App() {
  const [steps, setStep] = useState([
    {
      step: 1,
      response: ""
    },
    {
      step: 2,
      response: ""
    }
  ]); // For Default Two Inputs

  const handleChange = (value, index) => {

    // Updates, Remove and Replaces an object at index n
    const steptoReplace = steps[index];
    steptoReplace.response = value;

    steps.splice(index, 1);
    steps.splice(index, 0, steptoReplace);

    setStep(steps);
  };

 // Adds an empty entry
  const addStep = () => {
    setStep([
      ...steps,
      {
        step: steps.length + 1,
        response: ""
      }
    ]);
  };

  const reduceStep = () => {
    // To have Two text editor always
    if (steps.length > 2) {
      steps.pop();
      setStep([...steps]);
    }
  };

  const submit = () => {
    // You will have an Array of Objects of all steps
    console.log("steps", steps);
  };

  return (
    <div className="container">
      <h1>Multiple React Quill</h1>
      <div className="mt-4">
        {steps.map((step, index) => (
          <div key={index}>
            Step {index + 1}
            <Editor
              response={step.response}
              handleChange={(value) => handleChange(value, index)}
            />
          </div>
        ))}

        <div className="d-flex mt-4  justify-content-between">
          <Button onClick={addStep}>Add Step </Button>
          <Button onClick={reduceStep}>Remove Step</Button>
        </div>

        <Button className="mt-4" onClick={() => submit()}>
          Submit
        </Button>
      </div>
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for this @Mohamed. I wont be able to test the solution for a day or two, but will def get back if this works or if I have any doubts regarding this.
This works, just one thing: I used value = {response || ''} in Editor.js because I was accessing the value of component before onChange is called. Thanks for your time.

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.