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 id
s 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>