How to bring Radio Buttons inside an html link using Javascript - javascript

I’m looking for some help bringing Radio buttons that we have on a page inside a link. At the moment we have a Quiz with various questions with 4 possible choices for the respondent to choose. The text links work fine and advance the user to the next page, but the radio buttons don’t work. They are clickable, but they don’t advance you to the next page.
How would I bring the Radio buttons inside the link? I want the Radio buttons to send you forward, just like the text links.
Here is the test page for the Quiz (need to press Start Quiz to see the Radio buttons):
http://stephanieshipper.com/test/
Here is the piece of code from the .js file:
function updates(questions) {
for (i = 0; i < 20; i++) {
$("body").append("<article><p>" + questions[i] + "</p><input id='question-" + (i*10) + "-1' type='radio' order='1' name='question-" + i + "-0'><label for='question-" + (i*10) + "-1'>exactly like me</label><br><input id='question-" + (i*100) + "-2' type='radio' order='2' name='question-" + i + "-0'><label for='question-" + (i*100) + "-2'>sort of like me</label><br><input id='question-" + (i*1000) + "-3' type='radio' order='3' name='question-" + i + "-0'><label for='question-" + (i*1000) + "-3'>not really like me</label><br><input id='question-" + (i*10000) + "-4' type='radio' order='4' name='question-" + i + "-0'><label for='question-" + (i*1000) + "-4'>not at all like me</label><br></article>");
}
motions();
}
function motions() {
var step = 1;
results = [];
var order;
$("body > article > label").on("click", function() {
$(this).parent().hide(250);
if (step < 20) {
$(this).parent().next().show(250);
order = parseInt($(this).prev().attr("order"));
results[step-1] = order;
step++;
} else {

As I see, your are calling the next page just if the user click on the label tag :
$("body > article > label").on("click", function() {}
What you gonna need to do it's adding the radio button(your input tag), into this jquery
eg.:
$("input[type='radio']")
So maybe would work :
$("body > article >input[type='radio'] > label").on("click", function() {}

Related

Dynamically load Two Questions into separate forms as well as their appropriate answer options

I'm trying to have a button, that once pressed. Dynamically loads Two Questions (question1, and question2) into separate forms. But it also contains the questions 3 Answers to choose from. Currently my for loop adds an additional set of 3 answers(question 2's answers) to choose from to Question 1
OUTPUT Looks like the following :
It needs to be QUESTION 1 (YES, NO, OTHER) and QUESTION 2 (YES2, NO2, OTHER2)
CODE
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="center col-xs-12">
<button class="contentBtn btn"><label for="contentBtn">CONTENT</label></button>
</div>
<div class="row-2 center col-xs-12"></div>
<script src="js/jquery-1.11.3.min.js" type='text/javascript'>
</script>
<script>
$('.contentBtn').click(function(){
var contentArray = [
["QUESTION1?", "YES", "NO", "OTHER"],
["QUESTION2?", "YES2", "NO2", "OTHER2"]
];
for (var i = 0; i < contentArray.length; i++){
$('.row-2').append("<form><span class='question'>" + contentArray[i][0] + "<\/span><br>")
for (var x = 1; x < 4; x++){
$('form').append("<input type='radio' value='" + contentArray[i][x] + "'>" + contentArray[i][x] + "");
}
$('.row-2').append("<\/form><br>");
}
});
</script>
</body>
</html>
The short answer is that you are appending 'form', meaning you are appending every form on the DOM. The code is also corrupting the DOM. The inputs are not closed, and append should never be done in partials like given in the example.
// Always favor the 'on' events instead of the 'click' events.
$('.contentBtn').on('click', function () {
var contentArray = [
['QUESTION1?', 'YES', 'NO', 'OTHER'],
['QUESTION2?', 'YES2', 'NO2', 'OTHER2']
];
// we are going to use a for each on the first item,
// we could use a for as well but it just is really messy.
// remember that variables are defined at function scope, not block scope.
$(contentArray).each(function (index, item) {
// our item in the array is directly coming in to us now.
// do not add incomplete html blocks to the dom, always
// create them and then add them!
var newContent = $('<form><span class="question">' +
item[0] + '</span><br></form><br>');
// now we will foreach, but instead of going by a length of 4,
// I am looking at the actual length of the array.
for (var i = 1; i < item.length; i++) {
// we are going to precreate our dom object.
var answerContent = $('<input type="radio" value="' +
item[i] + '">' + item[i] + '</input>');
// now we are going to append the object to our form object.
newContent.append(answerContent);
}
// now that the structure is complete we will append the browser dom.
$('.row-4').append(newContent);
});
});
I have created a corrected fiddle with comments for you.
https://jsfiddle.net/t9h91nbk/
Hope this helps.
The problem is in this line :
$('form').append("<input type='radio' value='" + contentArray[i][x] + "'>" + contentArray[i][x] + "");
The javascript can't detect wich form you want to append input to it so it will append to all the forms in page, so you have to add an identifier to the form you create.
I'll add class to identify each form and append the input using this identifiers :
$('.row-2').append("<form class='form_"+i+"'><span class='question'>" + contentArray[i][0] + "</span><br>")
for (var x = 1; x < 4; x++){
$('.form_'+i).append("<input type='radio' value='" + contentArray[i][x] + "'>" + contentArray[i][x] + "");
}
Hope this helps.
Working fiddle

How do I create a div and give it an ID based on a changing variable?

I'm making a quiz. The user decides how many questions he wants to answer.
A function then takes this number and runs a loop to make an individual question div for each question. The quiz shows a Chinese character and the user has to pick the correct translation.
My code:
var fillInQuestion = function() {
questionDivIdHTML = 'question' + questionNum;
/****************************************
How do I make this Div's ID = to questionDivIdHTML?
// Creates question div
$('#questionArea').append("<div class='questionDiv'></div>");
//$('#questionArea:last-child').attr("id", questionDivIdHTML); <-- NOT WORKING
***************************************/
// Sets up a choice bank.
var choices = [];
// choices will be chosen from this.
var tempAnswerSet = allChoices.slice(0);
//find random item in the database for the question
var thisQuestion = allQuestions[Math.floor(Math.random() * allQuestions.length)];
// add that item to choices
choices.push(thisQuestion);
// remove item from 'database' so it cannot be used in another question
allQuestions.splice(allQuestions.indexOf(thisQuestion), 1);
// remove item from tempAnswer set so it can only be one choice
tempAnswerSet.splice(tempAnswerSet.indexOf(thisQuestion), 1);
// add three more items from the database (incorrect items)
var i = 3;
for (i; i > 0; i--) {
var addChoice = tempAnswerSet[Math.floor(Math.random() * tempAnswerSet.length)];
choices.push(addChoice);
// remove the one selected each time so they cant be chosen again
tempAnswerSet.splice(tempAnswerSet.indexOf(addChoice), 1);
//console.log("choices length: " + choices.length);
}
// shuffle the array
choices.shuffle();
// fill in the div with choices.
$('#questionDivIdHTML').append("Here is an question prompt:" + thisQuestion.english + " <br>");
$('questionDivIdHTMLwithHash').append("<input type='radio' name='question<script>questionNum</script>Choice' value='<script>choices[0].hanyu</script>'></input>" + choices[0].hanyu + "<br>");
$('questionDivIdHTMLwithHash').append("<input type='radio' name='question<script>questionNum</script>Choice' value='<script>choices[1].hanyu</script>'></input> " + choices[1].hanyu + "<br>");
$('questionDivIdHTMLwithHash').append("<input type='radio' name='question<script>questionNum</script>Choice' value='<script>choices[2].hanyu</script>'></input> " + choices[2].hanyu + "<br>");
$('questionDivIdHTMLwithHash').append("<input type='radio' name='question<script>questionNum</script>Choice' value='<script>choices[3].hanyu</script>'></input> " + choices[3].hanyu + "<br>");
};
var fillOutQuiz = function() {
for (questionAmount; questionAmount > 0; questionAmount--) {
fillInQuestion();
questionNum += 1;
}
};
I've gotten this code to work, but I broke it, when trying to add the dynamic ID and loop it.
You are saying that this portion of code is not working:
$('#questionArea').append("<div class='questionDiv'></div>");
$('#questionArea:last-child').attr("id", questionDivIdHTML);
Well, it does not work because the :last-child pseudo selector is used incorrectly (see below). It should be:
$('#questionArea').append("<div class='questionDiv'></div>");
$('#questionArea > :last-child').attr("id", questionDivIdHTML);
Or better, you can rearrange your code like this:
$("<div class='questionDiv'></div>")
.attr("id", questionDivIdHTML)
.appendTo("#questionArea");
#questionArea:last-child selects an element with id = questionArea which is also the last child of its parent
#questionArea > :last-child selects the last child of an element with id = questionArea

How do I make a loop advance using onclick?

I've been trying to figure this out for a while, and I'm totally stumped.
I'm writing a program that is supposed to display a basic series of multiple-choice questions. You see a question, you click one of the answers, and you move on to the next question.
The problem is, I can't figure out how to display one question, then display the next question when the user clicks one of the buttons. Nothing happens when I click a button. What's going wrong?
// progress meter
var progress = new Array();
for (var i = 0; i < questions.length; i++) progress.push("0");
var i = 0;
display(0);
// display questions
function display(i) {
var prg_string;
for (var j = 0; j < progress.length; j++) prg_string += progress[j];
document.write(
"<div id = 'background'>"
+ "<div id = 'progress'>" + progress + "</div>"
+ "<div id = 'title'>-JogNog Test v1-<br></br>" + tower + "</div>"
+ "<div id = 'question'>" + questions[i].text + "</div>"
+ "<div id = 'stats'>Level " + level + "/" + total_levels + " Question " + (i + 1) + "/" + questions.length + "</div>"
+ "</div>"
);
document.write("<button id = 'answer1' onclick = 'next(questions[i].answers[0].correct)'>" + questions[i].answers[0].text + "</button>");
if (questions[i].answers.length > 0)
document.write("<button id = 'answer2' onclick = 'next(questions[i].answers[1].correct)'>" + questions[i].answers[1].text + "</button>");
if (questions[i].answers.length > 1)
document.write("<button id = 'answer3' onclick = 'next(questions[i].answers[2].correct)'>" + questions[i].answers[2].text + "</button>");
if (questions[i].answers.length > 2)
document.write("<button id = 'answer4' onclick = 'next(questions[i].answers[3].correct)'>" + questions[i].answers[3].text + "</button>");
}
// go to next question, marking whether answer was right or wrong
function next(correct) {
if(correct) progress[i] = "T";
else progress[i] = "F";
i += 1;
display(i);
}
I haven't read through your code, (you might want to work on posting SSCCEs by focusing just on the part that handles the loop) but I get the feeling a loop is not what you want here. Loops are great if you need to automatically iterate through something. But really, you want to display only a single question at a time.
The easiest way to do this, assuming you have a means of handling each question independently, is just to keep track of which question the user is up to. Display that question. When the user submits an answer, call whatever function renders a question using the counter, plus one. Make sure to check that you haven't hit the end of the quiz so that you don't reference a question that doesn't exist.
Here's some pseudocode:
var questionNumber, questions; //assume these already have values
function printQuestion(questionNumber){ ... }
function nextQuestion(){
if(questionNumber < questions){
questionNumber++;
printQuestion(questionNumber);
}
else{
showResults();
}
}
I agree with #ngmiceli that a loop isn't what you want here. You want to display one question, and then create click event handlers that will move on to the next question when the user selects an answer to the previous question.
I went ahead and created a different setup to demonstrate. You can see a demo here:
-- jsFiddle DEMO --
But I'll walk through the process. First, I set up a basic HTML document:
<body>
<h1>-Test v1-</h1>
<h2>Simple Math</h2>
<div id="container">
<div><span id="numRight">0</span> of <span id="numQuestions">0</span></div>
<div id="question"></div>
<div id="answers"></div>
</div>
</body>
Then, I created a questions array, each element in the array being an object. Each question object contains the question itself, an array of possible answers, and an "answerIdx" property that indicates the array index of the correct answer.
questions = [
{
question: 'What is 0 / 6 ?',
options: ['0','1','2'],
answerIdx: 0
},
{
question: 'What is 2 + 2 ?',
options: ['72','4','3.5'],
answerIdx: 1
}
]
I also created some other variables that point to the HTML elements I am going to want to manipulate:
numRight = 0,
numQuestions = 0,
answerDiv = document.getElementById('answers'),
questionDiv = document.getElementById('question'),
numRightSpan = document.getElementById('numRight'),
numQuestionsSpan = document.getElementById('numQuestions');
Next, I created a 'displayQuestion' function which takes a single question object as a parameter:
function displayQuestion(q) {
// insert the question text into the appropriate HTML element
questionDiv.innerHTML = q.question;
// remove any pre-existing answer buttons
answerDiv.innerHTML = '';
// for each option in the 'options' array, create a button
// attach an 'onclick' event handler that will update
// the question counts and display the next question in the array
for(i = 0; i < q.options.length; i++) {
btn = document.createElement('button');
btn.innerHTML = q.options[i];
btn.setAttribute('id',i);
// event handler for each answer button
btn.onclick = function() {
var id = parseInt(this.getAttribute('id'),10);
numQuestionsSpan.innerHTML = ++numQuestions;
// if this is the right answer, increment numRight
if(id === q.answerIdx) {
numRightSpan.innerHTML = ++numRight;
}
// if there is another question to be asked, run the function again
// otherwise, complete the test however you see fit
if(questions.length) {
displayQuestion(questions.shift());
} else {
alert('Done! You got '+numRight+' of '+numQuestions+' right!');
}
}
answerDiv.appendChild(btn);
}
}
Finally, I displayed the first question:
displayQuestion(questions.shift());

Firing a function on click

I have addBanner() function shown below which is invoked every time I click addBanner button. This adds a input field and fires the ausu auto-suggestion jQuery script.
When I click addBanner() Button I get a input field and auto-suggestion works fine. Suppose I click addBanner() button again it adds another empty Input Field and auto-suggestion works fine for that too as the auto-suggest function is fired every time I click addBanner Function. But, if I want to edit the first Input Field which I had added there's conflict. Please tell me how to get the control back to the first input field.
var bnrc = 1;
var bnrl = 5;
function addBanner(divName){
if (bnrc == bnrl) {
alert("You have reached the limit of adding " + bnrc + " Banner companies.");
}
else {
var newdiv = document.createElement('div');
newdiv.className = "banner_sugg";
newdiv.innerHTML = (bnrc + 1) + ". <input type='text' value='' name='banner[]' id='banner" + (bnrc + 1) + "' autocomplete='off' /> <input type='hidden' value='' name='bannerID[]' id='bannerID" + (bnrc + 1) + "' autocomplete='off' />";
document.getElementById(divName).appendChild(newdiv);
bnrc++;
}
$.fn.autosugguest({
className: 'banner_sugg',
methodType: 'POST',
minChars: 1,
rtnIDs: true,
dataFile: 'e_data.php'
});
}
Did you spell suggest wrong on purpose? I'm spelling it correctly below so you may need to alter it.
You are currently (re)calling $.fn.autosuggest({}) every time you add a new item, which may be breaking the previous items.
Try:
$(newDiv).autosuggest({})
So it only adds autosuggest functionality to the new div. And you should move the code above into the section where you create the newDiv as it's even being called on error.

Adding and removing elements in Javascript?

I'm trying to make a generator for a mod menu in Call of Duty. I want people to be able to add a menu or delete one. I'm trying to id the menus sequentially so that I can use the text field values correctly. I made it so that if they delete a menu it changes the ids of all the other menus to one lower and same for the button id, but I don't know how to change the onlick event to remove the right element.
Better yet, if there's a better way to do this, I would love to know it.
<script type="text/javascript">
y = 1
function test2()
{
document.getElementById("test2").innerHTML += "<div id=\"child" + y + "\"><input type=\"text\" value=\"menu name\" \><input id=\"button" + y + "\" type=\"button\" value=\"remove?\" onclick=\"test3(" + y + ")\" /></div>";
y++;
alert(y);
}
function test3(x)
{
document.getElementById("test2").removeChild(document.getElementById("child" + x));
for(var t = x+1;t < y;t++)
{
alert("t is " + t + ". And y is " + y);
document.getElementById("button" + t).setAttribute("onclick" , "test3(t-1)");
document.getElementById("button" + t).id = "button" + (t-1);
document.getElementById("child" + t).id = "child" + (t-1);
}
y--;
}
</script>
<input value="testing" type="button" onclick="test2()" />
<div id="test2" class="cfgcode"></div>
I wouldn't worry about re-indexing all of the elements after you add or remove one, that seems a waste. It would be better to simply write a more generic function, rather than one with the element id hard coded into it.
For example, your first function could be written as so:
function genericFunction(el)
{
var html = ''; // create any new html here
el.innerHTML = html;
}
You can then add onclick handlers such as:
myDiv.onclick = function() { genericFunction(this) };
I would also agree with all the commenters above, use jQuery, it makes any code which interacts with the DOM much much simpler.

Categories

Resources