0

Ok so here's my code:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

var uuid = require("uuid-v4");
// Generate a new UUID
var myUUID = uuid();
// Validate a UUID as proper V4 format
uuid.isUUID(myUUID); // true

var questionNum = 0;

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      key: uuid(),
      title: "",
      author: "",
      questions: [],
      answers: []
    };

    this.handleChange = this.handleChange.bind(this);
    this.addQuestion = this.addQuestion.bind(this);
    this.removeItem = this.removeItem.bind(this)
  }

  componentDidMount() {
    // componentDidMount() is a React lifecycle method
    this.addQuestion();
  }

  handleChange(event) {
    const target = event.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }

  removeItem (index) {
    questionNum--;
    this.setState(({ questions }) => {
      const mQuestions = [ ...questions ]
      mQuestions.splice(index, 1)
      return { questions: mQuestions }
    })
    this.setState(({ answers }) => {
      const mAnswers = [ ...answers]
      mAnswers.splice(index, 4)
      return { answers: mAnswers}
    })
    console.log(
      "answers",
      this.state.answers,
      "questions",
      this.state.questions,
      questionNum,
      this.state.title,
      this.state.author
    );
  }

  addQuestion() {
    questionNum++;
    this.setState(previousState => {
      const questions = [
                          ...previousState.questions,
                          <input 
                            type="text"
                            onChange={this.handleChange}
                            name="question"
                            key={uuid()}
                          />
                        ];
      const answers = [
                        ...previousState.answers,
                      ];

      for (var i = 0; i < 4; i++) {
        answers.push(
          <input 
          type="checkbox" 
          name={uuid()}>
                <input 
                 type="text"
                 onChange={this.handleChange}
                 name={uuid()}
                />
          </input>
        );
      }
      return { questions, answers };
    });
    console.log(
      "answers",
      this.state.answers,
      "questions",
      this.state.questions,
      questionNum,
      this.state.title,
      this.state.author
    );
  }

  render() {
    return (
      <div className="App">
        <div>
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <h1 className="App-title">Quiz Form 3.0</h1>
          </header>
          <p className="App-intro">
            To get started, edit <code>src/App.js</code> and save to reload.
          </p>
        </div>

        <div  className="formDiv">
          <form>
            <div className="Intro">
              Give your Quiz a title:{" "}
              <input
                type="text"
                value={this.state.title}
                onChange={this.handleChange}
                name="title"
              />
              <br />
              Who's the Author?{" "}
              <input
                type="text"
                value={this.state.author}
                onChange={this.handleChange}
                name="author"
              />
              <br />
              <br />
            </div>
            <div className="questions">
            <div className="questions">
              Now let's add some questions... <br />
              <ol>
              {this.state.questions.map(question => {
                return (
                  <li>
                  <div key={uuid()}>
                    Question
                    {question}<br />
                    Answer Choices<br />
                    {Array.from({ length: 4 }, () => (
                      <input type="text" key={uuid()} onChange={this.handleChange} />
                    ))}
                  </div>
                  </li>
                );
              })}
              </ol>
            </div>
              {
              // This is what it would look like for the structure
              // I proposed earlier.
              // this.state.questions.map((question) {
              //   return (
              //       <div>{question.quesion}</div>
              //       {
              //           question.answers.map((answer) => {
              //               return (<div>{answer}</div>);
              //           })
              //       }
              //   );
              // })
              // This would output all questions and answers.
              }
            </div>
          </form>
          <button id="addQuestionButton" onClick={this.addQuestion}>Add Question</button>
          { this.state.questions.map((question, index) => {
          return <button key={uuid()} onClick={ () => this.removeItem(index) }>Remove Question</button>
        }) }
        </div>
      </div>
    );
  }
}

export default App;

Ok so here's a link to a quick video demonstrating what it does as of now. In the video you can see the Remove Question buttons that are created (at the bottom of the form) each time a question is added. I would like to have each question's Remove Question button be next to it/in the same div. I'm not entirely sure how I would go about doing this. Any thoughts?

UPDATE: Ok so I have put the buttons inside of the same div with the actual question, but I realized that i am adding a button for each object in the array. Which means that when a question is added a button to remove it is added to every question on the form. I need to make it so it does not .map this. I'm not entirely sure what other function I will do for this, maybe I don't even need a function. I will try my best to work it out. Here's the updated code (some of it):

<div className="questions">
              Now let's add some questions... <br />
              <ol>
              {this.state.questions.map(question => {
                return (
                  <li>
                  <div key={uuid()}>
                    Question
                    {question}<br />
                    {
                      this.state.questions.map((question, index) => {
                        return <button key={uuid()} onClick={ () => this.removeItem(index) }>Remove Question</button>
                      }) 
                    }
                    Answer Choices<br />
                    {Array.from({ length: 4 }, () => (
                      <div>
                        <input type="checkbox" />
                        <input type="text" key={uuid()} onChange={this.handleChange} />
                      </div>
                    ))}
                  </div>
                  </li>
                );
              })}
              </ol>

            </div>
3
  • I guess a more direct question would be, does this button need to be inside the same div as the question? Commented Jul 11, 2018 at 20:54
  • Wouldn't you put index parameter with the outer .map and remove the inner .map? I think you may be pretty close. Commented Jul 11, 2018 at 21:15
  • That's what I was thinking, I just wasn't sure of the syntax for it Commented Jul 12, 2018 at 15:24

1 Answer 1

2

Something like this...

        <ol>
          {this.state.questions.map((question, index) => {
            return (
              <li>
              <div key={uuid()}>
                Question
                {question}<br />
                <button onClick={ () => this.removeItem(index) }>
                  Remove Question
                </button>
                Answer Choices<br />
                {Array.from({ length: 4 }, () => (
                  <div key={uuid()}>
                    <input type="checkbox" />
                    <input type="text" onChange={this.handleChange} />
                  </div>
                ))}
              </div>
              </li>
            );
          })}
        </ol>
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.