Home > Software engineering >  How can I select the current div with Javascript
How can I select the current div with Javascript

Time:06-24

I have code to imitate a survey. Basically there are questions and some options under them. What I tried to do is something "object-oriented" let's say.

So I am grouping every question and there under each question I can add many options but all options should belong to their question.

A question would have a questionName and a list of options. I have implemented the grouping of the questions but I don't know how to exactly choose the current question so that when the user is adding options, they would be added to the last question let's say.

This is my code:

newQuestion()

function newQuestion() {
  // Create a variable which is basically the questionaire from the html
  var questionaire = document.getElementById('questionaire');

  /* HERE I AM CREATING A DIV WHICH WILL BE REPRESENTING EACH QUESTION */
  // Create a variable which is a new div to be the question
  const question = document.createElement('div');
  // add classname and put it as a child of questionaire
  question.classList.add("question");
  questionaire.append(question);

  /* HERE I AM CREATING A DIV WHICH WILL BE REPRESENTING THE QUESTION NAME */
  // Create a variable which is a new div to be the question name
  const qname = document.createElement('div');
  // add a classname, make it editable and set the text to be shown
  qname.classList.add("qName");
  qname.innerHTML = '<div contenteditable="true">Your Question</div>';
  // put qName as a child of question
  question.appendChild(qname);
  // add a new option and pass as parameter the question
  newOption(question)
}


function newOption(father) {
  /* IF THERE IS AN ARGUEMENT, father is the question where this option will belong */

  // else you need to get the question from the html
  if (arguments.length == 0) {
    // select current question

    /* PROBLEM IS HERE BUT DON'T KNOW HOW TO FIX*/

    var father = document.getElementsByClassName('question')[0];
  }

  // Create a variable which is a new div to be an option
  const op = document.createElement('div');
  // add a classname, make it editable and set the text to be shown
  op.classList.add("option");
  op.innerHTML = '<div> <ul id="optionList"> <li  contenteditable="true">Option <li >  <input type="checkbox"> </li> </ul> </div>';
  // put option as a child of question
  father.appendChild(op);
}
body {
  background-color : #00ffaa;
  }
#myText {
  margin-top       : 15px;
  font-family      : 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  text-align       : center;
  }
.question {
  border           : 3px solid black;
  border-radius    : 25px;
  margin           : 30px 200px 20px 200px;
  }
.qName {  
  color            : rgb(86, 17, 150);
  margin-top       : 10px;
  font-size        : 25px;
  text-align       : center;
  }
.optionname {
  margin-left      : -50px;
  }
.box {
  margin-left      : 90px;
  }
.option {
  display          : table;
  margin-left      : auto;
  margin-right     : auto;
  margin-top       : 10px;   
  }
ul#optionList li {
  display          : inline;
  }
.optionName {
  font-size        : 19px;
  font-style       : oblique;
}
<h1 id="myText" contenteditable="true">Survey Name</h1>

<button type="button" id="addQuButton" onclick="newQuestion()">
  Add Question
</button>
<button type="button" id="addOpButton" onclick="newOption()">
  Add Option
</button>

<form>
  <div id="questionaire"></div>
</form>

HTML CODE: (just the basic structure of the survey)
JAVASCRIPT CODE: (here's is most of the work where I have 2 functions to add the questions and options)
CSS CODE: (here's just for styling)

If anyone knows how to help with this code or you think an other approach would be better it would be highly appreciated. Thank you.

CodePudding user response:

Pls check the newly added line and modified line in newOption(father) function

newQuestion()

function newQuestion() {
  // Create a variable which is basically the questionaire from the html
  var questionaire = document.getElementById('questionaire');

  /* HERE I AM CREATING A DIV WHICH WILL BE REPRESENTING EACH QUESTION */
  // Create a variable which is a new div to be the question
  const question = document.createElement('div');
  // add classname and put it as a child of questionaire
  question.classList.add("question");
  questionaire.append(question);

  /* HERE I AM CREATING A DIV WHICH WILL BE REPRESENTING THE QUESTION NAME */
  // Create a variable which is a new div to be the question name
  const qname = document.createElement('div');
  // add a classname, make it editable and set the text to be shown
  qname.classList.add("qName");
  qname.innerHTML = '<div contenteditable="true">Your Question</div>';
  // put qName as a child of question
  question.appendChild(qname);
  // add a new option and pass as parameter the question
  newOption(question)
}


function newOption(father) {
  /* IF THERE IS AN ARGUEMENT, father is the question where this option will belong */

  // else you need to get the question from the html
  if (arguments.length == 0) {
    // select current question

    /* PROBLEM IS HERE BUT DON'T KNOW HOW TO FIX*/

var fatherlen = document.getElementsByClassName('question').length;//newly added one
    var father = document.getElementsByClassName('question')[fatherlen-1];//modified
  }

  // Create a variable which is a new div to be an option
  const op = document.createElement('div');
  // add a classname, make it editable and set the text to be shown
  op.classList.add("option");
  op.innerHTML = '<div> <ul id="optionList"> <li  contenteditable="true">Option <li >  <input type="checkbox"> </li> </ul> </div>';
  // put option as a child of question
  father.appendChild(op);
}
body {
  background-color : #00ffaa;
  }
#myText {
  margin-top       : 15px;
  font-family      : 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  text-align       : center;
  }
.question {
  border           : 3px solid black;
  border-radius    : 25px;
  margin           : 30px 200px 20px 200px;
  }
.qName {  
  color            : rgb(86, 17, 150);
  margin-top       : 10px;
  font-size        : 25px;
  text-align       : center;
  }
.optionname {
  margin-left      : -50px;
  }
.box {
  margin-left      : 90px;
  }
.option {
  display          : table;
  margin-left      : auto;
  margin-right     : auto;
  margin-top       : 10px;   
  }
ul#optionList li {
  display          : inline;
  }
.optionName {
  font-size        : 19px;
  font-style       : oblique;
}
<h1 id="myText" contenteditable="true">Survey Name</h1>

<button type="button" id="addQuButton" onclick="newQuestion()">
  Add Question
</button>
<button type="button" id="addOpButton" onclick="newOption()">
  Add Option
</button>

<form>
  <div id="questionaire"></div>
</form>

CodePudding user response:

I ended up changing more than originally intended. There were multiple ids and deep nested <div><div><ul><li><li> ... structures that resultet in many case in invalid html. For this reason I simplified both your markup and your JavaScript code. I also took the liberty of creating multiple "Add Option" buttons (one for each question). The page is by far not ready yet but I hope it can be a pointer of where to go ...

const questionnaire=document.getElementById('questionaire');
newQuestion();

function newQuestion() {
 questionnaire.insertAdjacentHTML('beforeend',
  `<div >
    <div contenteditable="true">Your Question</div>
    <ul></ul>
    <button type="button">Add Option</button>
   </div>`);
  newOption(questionnaire.querySelector("div.question:last-child ul"));
}

function newOption(q) {
  q.insertAdjacentHTML('beforeend',
   `<li >
      <span contenteditable="true">Option</span>
      <input type="checkbox">
     </li>`);
}

questionnaire.onclick=ev=>{
 if (ev.target.tagName==="BUTTON") newOption( ev.target.closest(".question").querySelector('ul') )
}
document.getElementById("addQuButton").onclick=newQuestion
body {
  background-color : #ccc;
  }
#myText {
  margin-top       : 15px;
  font-family      : 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  text-align       : center;
  }
.question {
  border           : 3px solid black;
  border-radius    : 25px;
  margin           : 30px 200px 20px 200px;
  text-align       : center;
  }

.question ul li {
  display          : block;
  }
<h1 id="myText" contenteditable="true">Survey Name</h1>
<button type="button" id="addQuButton">Add Question</button>
<form> <div id="questionaire"></div> </form>

  • Related