Javascript not checking whether a checkbox was selected or not - javascript

I'm trying to build a quiz with multiple choice questions, one of which has multiple correct answers. So I'm trying to check which checkboxes in my questions have been selected by a student in order to give the right feedback. my code is:
for(var i = 0; i< input1.length; i++)
{
if(input1[0].checked && input1[1].checked)
{
submit_answer.onclick = showFeedback1;
}
else
{
submit_answer.onclick = false1;
}
}
It never takes the first if, even if I select those two only. No matter what I put in the if statement, it only takes the else.
and this is just a part of my .js
var quiz = document.getElementById('quiz');
var questions = quiz.getElementsByTagName('p');
input1 = questions[0].getElementsByTagName('input');
var submit_answer = document.getElementById('submit_answers'); // this is the submit button

I cannot make proper assumption of what you are trying to do.
FIRST PROBLEM
Your for loop is incrementing on 1, so on the each next iteration it is comparing using same previously used value.
SECOND PROBLEM
Your structure is horrible, your script fetches up all the input elements inside every p. You should properly organize your element in groups and then match whether or not they are checked.

Related

Storing data with nested .each() function causes to replicate values

I've modified a survey-multi-choice plugin from JsPsych, in order to get responses in the form of checkboxes, instead of radio-buttons, since I need to present an image to the user, followed by 4 alternatives, like this:
Where A, B, C and D are also images, with their respective checkbox below each one. This structure must be presented more than once, like this:
So in this example, the expected output would be:
{"Q0":["Option A","Option B"]} //this is the first "question" displayed
{"Q1":["Option B","Option C"]} //second one
{"Q2":["Option B","Option D"]} //third one
But instead I get the first answer replicated for the rest of the questions:
{"Q0":["Option A","Option B"]} //this is the first "question" displayed
{"Q1":["Option A","Option B"]} //second one
{"Q2":["Option A","Option B"]} //third one
My code is provided below:
$("div." + plugin_id_name + "-question").each(function(index) {
var id = "Q" + index;
var val = [];
var a = $(".jspsych-survey-multi-choicemrbeta-option");
$("input:checkbox:checked").each(function(){
val.push($(this).attr("value"));
});
var obje = {};
obje[id] = val;
$.extend(question_data, obje);
});
I've tried tracking down the values generated on each step by printing them on console, so I'm guessing the problem is how I'm implementing those nested loops, thus the name of this question.
I've tried different approaches when implementing this loop, without better results:
for (var j = 0; j < trial.options[index].length; j++) {
if ($('jspsych-survey-multi-choicemrbeta-response-' + j).is(':checked')) {
val.push($(this).attr("value"));
}
}
A working example of my full code can be found here, for you to test it (look for the jspsych-survey-multi-choicemrbeta.js file, from line #141). CSS isn't included so it'll look slightly different.
Please note that the output of this code is a CSV file, and the full set of responses is given on a single cell, since all those questions belongs to the same JsPsych "trial".
Thanks for your help.
The inner loop iterates over all checkboxes, not only the ones belonging to the question.
Assuming the checkboxes are descendants of the div for the associated question, you should change the inner loop from this:
$("input:checkbox:checked").each( ...
to this:
$(this).find("input:checkbox:checked").each( ...

javascript if statement syntax (need help)

I've looked through the prior questions but do not see an answer that I can understand (they are all more complicated than mine).
I'm bootstrapping some javascript using old manuals and my experiences using a scripting language back 15 years ago.
By modifying a tutorial file I have this code and it works fine
var oemdc1 = parseInt(document.getElementById("vehicle_oem_draw").value);
var oemdc2 = parseInt(document.getElementById("vehicle_added_draw").value);
var oemdc3 = parseInt(document.getElementById("new_vehicle_draw").value);
var oemdc4 = parseInt(document.getElementById("include_prism_draw").value);
var total_current_draw = document.getElementById("total_hourly_current_draw");
total_current_draw.value = oemdc1 + oemdc2 + oemdc3
But I need to add this code so that if the user clicks a radio button (include_prism_draw) they get a different total.
if (oemdc4 == 1)
total_current_draw.value = oemdc1 + oemdc2 + oemdc3 + prism_cd;
else
total_current_draw.value = oemdc1 + oemdc2 + oemdc3;
But I get the added value (prism_cd) in my calculation regardless of the radio button values (a "1" or a "0"). Even if neither button is clicked I still get the added value.
So I think I need some braces or parentheses or something.
I have the var prism_cd declared at the top of the doc and it is inserted into a results field so it is working in that sense.
Any help is much appreciated.
(Okay, found the edit link, they should make it more prominent).
I cut/pasted the code from #Adam and still get the prism_cd regardless of the state of the buttons. (prism_cd is a number I set as a var and it shows up accurately but even when I don't want it.)
the button code is below. Maybe there is a simple mistake
Include PRISM 1.5 mA current draw in calculation?
<input type="radio" name="include_prism_draw" id="include_prism_draw" value="1" /> Yes
<input type="radio" name="include_prism_draw" id="include_prism_draw" value="0" /> No
To answer the other question about the vars, they are from popups the user manipulates, the script adds the values from the popups and does so accurately until I add the yes/no code with the buttons.
If the user wants to add the prism current draw (prism_cd) they click yes and it is to be added but as I say it is getting added whenever the code is in the script. At this point I do not have either button set to be checked.
The rest of script works accurately as I can test with the spreadsheet I am porting it from.
I still have more things to work through but they are mostly based on this type of "if/else set a var" logic so once I get this working hopefully I should be good to go.
I very much appreciate the replies.
M./
I'm not certain what your problem is. But, the best practice for if..else syntax is to put both blocks in braces.
var oemdc1 = parseInt(document.getElementById("vehicle_oem_draw").value);
var oemdc2 = parseInt(document.getElementById("vehicle_added_draw").value);
var oemdc3 = parseInt(document.getElementById("new_vehicle_draw").value);
var oemdc4 = parseInt(document.getElementById("include_prism_draw").value);
var total_current_draw = document.getElementById("total_hourly_current_draw");
if (oemdc4 === 1){
total_current_draw.value = oemdc1 + oemdc2 + oemdc3 + prism_cd;
} else {
total_current_draw.value = oemdc1 + oemdc2 + oemdc3;
}
Look at this question: Get Radio Button Value with Javascript
You cannot get the value of a number of associated radio-buttons by just doing
document.getElementById(ID).value;
also look at this question, why you should not give the same id to multiple HTML elements: Why is it a bad thing to have multiple HTML elements with the same id attribute?
Now a possible simple solution for you problem (according to solution from first link):
You could write a function, which returns the value of your two radio-buttons:
function getPrismDrawValue()
{
// predefined result, if no radio button is checked.
// in this case result will be 0 -> "No"
var result = 0;
// get a list of all HTML-elements with the name 'include_prism_draw'
var radios = document.getElementsByName('include_prism_draw');
// loop through all this elements and check if one of them is checked
for (var i = 0; i < radios.length; i++)
{
if (radios[i].checked)
{
// get the value of the checked radio button
result = parseInt(radios[i].value);
// only one radio can be logically checked, don't check the rest
break;
}
}
return result;
}
Now your variable oemdc4 should be declared like this:
var oemdc4 = getPrismDrawValue();
EDIT to answer new question:
now your problem is here:
var oemdc4 = parseInt(document.getElementById("prism_draw").value);
if you pass 1.5 to parseInt()-function it will return 1.
use function parseFloat() instead to get your expected result.
var oemdc4 = parseFloat(document.getElementById("prism_draw").value);

Run 4 individual form submit functions from a single button click using Javascript

I am currently attempting to make a page that would allow for users to search multiple knowledge bases from a single field.
Currently, I have been able to build this tool out so that clicking the corresponding button will search the designated tool, but I am trying to get a single button to search all 4.
Where I am stuck is the function tied to the All button. When I click it, it only appears to be running the last function in the group rather than opening 4 browser tabs with all 4 results.
I have attached a JSFiddle, in case my explanation is poor.
Note: The page is not pretty as I am trying to get it working before I add any CSS. I really just need JS advice. I am still somewhat of a novice with JS, so if anyone can provide a fairly simple solution, that would be most ideal.
Super Search Fiddle:
This is just to give an idea on how it might work depending on you needs. Ill assume that all the searches return a boolean value. So the code would go something like this:
function doAll() {
var msg = ["google","payroll","inquira","sdfc"]
var retvalue = [googleSearch(),payrollSearch(),inquiraSearch(),sfdcSearch()];
for (var i = 0; i < retvalue.length; i++){
if(retvalue[i] == false){
console.log(msg[i]+" search returned false");
}
}
}
It will do all the searches first and after it finishes, it will give out which searches failed, but you can change that functionality according to your needs.
Hope it helps
Update/Alternative(Almost same code):
function doAll() {
var msg = ["google","payroll","inquira","sdfc"]
var retvalue1 = googleSearch();
var retvalue2 = payrollSearch();
var retvalue3 = inquiraSearch();
var retvalue4 = sfdcSearch();
var retvalue = [retvalue1,retvalue2,retvalue3,retvalue4];
//var retvalue = [googleSearch(),payrollSearch(),inquiraSearch(),sfdcSearch()];
for (var i = 0; i < retvalue.length; i++){
if(retvalue[i] == false){
console.log(msg[i]+" search returned false");
}
}
}

Calculating the total of an online order form using javascript

I'm working on a basic order form and I would like to see if I can build it from stratch.
I have a form which is made up of a table with 12 items listed and text input fields for item quantity. What I would like to do is have the code run through the form to check for any quantities that have been entered, then relate these values to the prices in an array.
So far I have the array:
var juicePrice = new Array();
juicePrice["citrusZing"]=20.00;
juicePrice["strawberrySmooth"]=22.00;
juicePrice["carrotSpin"]=21.50;
juicePrice["Tropical"]=20.75;
...
and a way to run through the form:
calculateTotal()
{
var juiceForm = document.forms["juiceform"];
//Get a reference to the juice the user Chooses name=selectedJuiceQty":
var selectedJuiceQty = juiceForm.elements["selectedJuiceQty"];
for(var i = 0; i < selectedJuiceQty.length; i++);
but I'm not quite sure how to connect the information from the form to calculate the totals. Can anyone point me in the right direction? Is it something like this?
for(var i = 0; i < selectedJuiceQty.length; i++){
var juiceTotal = 0;
if(selectedJuiceQty[i]>0) {
juiceTotal += juicePrice[selectedJuiceQty[i].value]*selectedJuiceQty;
//If we get a match then we break out of this loop
break;
}
return total;
}
Is it possible to use the same name tag for each field or should I just use citrusZingQty = parseInt(document.getElementById("citrusZing").value); for each item? Then I would have to list all of the items, which doesn't seem a very elegant way. What would happen if multiple items are selected?
Any help anyone can give to point me in the right direction would be great.
So you can do what you want. Michael pointed this out in the comments but it may have been overlooked.
var myPrices = new Object();
myPrices['eggs'] = 1.50;
myPrices['bread'] = 1.00;
// ...
Then you can loop through your form fields and check against your 'myPrices' object.
EDIT
To answer your question in the comments - I would not use the same name for all of my input fields. It does make looping through the form easier perhaps. However, using the id/class of the input tag is not a nice solution in my opinion. HTML id/class are there for CSS/Javascript manipulation and using it to identify which fruit the input represents will not be apparent to other developers working on the project (I realize this may be a small project for you but it's best not to start any bad habits). I would name each input after the juice/drink it represents.

How to reference an array in a function argument

I have a series of arrays that contain words I want to use as text in various HTML divs (there are about 35 of these, I included only a few for brevity).
var bodyplan = ['Anguilliform', 'Compressiform', 'Depressiform', 'Filiform', 'Fusiform', 'Globiform', 'Sagittiform', 'Taeniform'];
var mouthposition = ["Inferior", "Jawless", "Subterminal", "Superior", "Terminal"];
var barbels = ['1', '2', '4 or more'];
var caudalshape = ['Continuous', 'Emarginate', 'Forked', 'Lunate', 'Rounded', 'Truncate'];
I have a switch function that is supposed to change the text based on user selections:
switch(n){
case 1:
changelabels(bodyplan, 8);
break;
case 2:
changelabels(mouthposition, 5);
break;
case 3:
changelabels(barbels, 3);
break;
case 4:
changelabels(caudalshape, 6);
break;
case 5:
changelabels(dorsalspines, 8);
break;
default:
alert("handquestsel error")}};
Finally, I have the function which I would like to make the changes (except it doesn't):
function changelabels(opt1,opt2){
var i = opt2;
var im = opt2 - 1;
var c = 1;
var index = 0;
while (i>=c){
var oldlbl = document.getElementById("rb" + c + "lbl");
var newlbla = opt1.slice(im,i);
var newlblb = opt1.toString();
oldlbl.innerHTML = newlblb;
c = c + 1
index = index + 1
}};
I know the code for my function is just plain wrong at this point, but I have altered it so many times that I'm not sure what's going on anymore. At one point I did have the function able to change the text, but it did so incorrectly (it parsed the name of the array, not extracted a value from the array as I wished). Please help. I know I am overlooking some fundamental concepts here, but am not sure which ones. I've lost count of the hours I've spent trying to figure this out. It's seems like it should be so simple, yet in all my chaotic attempts to make it work, I have yet to stumble on an answer.
EDIT: I want my switch statement to call the function and pass to the function, the appropriate array from which to pull the labels from. The purpose of the app is to help a user learn to identify fish. When the user makes selections on the page, a series of pictures will be shown for various character states with an accompanying label describing the state. For example, when the user selects Mouth Position a series of divs will show the different mouth positions that fish have and have a label below the picture to tell the user what that certain character state is called. I can get the pictures to change just fine, but I am having a hell of a time with the labels.
Why not just something along the lines of:
document.getElementById("bodyplan_label").innerHTML = bodyplan[bodyplan_index];
You seem trying to put everything in really abstract data structures, I see no reason to. Just keep it simple.
Also bodyplan has only 8 elements, so bodyplan[8] will give you an out of bounds exception because arrays start at 0 as is common in all modern programming languages.
If I'm reading your requirement and code correctly, in your switch statement you are passing both a reference to the appropriate array and that array's expected length - you don't need the second parameter because all JavaScript arrays have a .length property.
You don't want to use .slice() to get the individual values out of the array, because that returns a new array copied out of the original - just use arrayVariable[index] to get the individual item at index.
So, putting that together try something like this (with your existing array definitions):
switch(n){
case 1:
changelabels(bodyplan);
break;
case 2:
changelabels(mouthposition);
// etc.
}
function changelabels(data) {
var i,
lbl;
for (i = 0; i < data.length; i++) {
lbl = document.getElementById("rb" + (i+1) + "lbl");
lbl.innerHTML = data[i];
}
}
Notice how much simpler that is than your code? I'm assuming here the elements you are updating have an id in the format "rb1lbl", "rb2lbl", etc, with numbering starting at 1: I'm getting those ids using (i+1) because JavaScript array indexes start at zero. Note also that you don't even need the lbl variable: you could just say document.getElementById("rb" + (i+1) + "lbl").innerHTML = data[i] - however I've left it in so that we have something to expand on below...
Within your function you seem to be changing the labels on a set of elements (radio button labels?), one per value in the array, but you stop when you run out of array items which means any leftover elements will still hold the values from the previous selection (e.g., if the previous selection was "bodyplan" with 8 options and you change to "mouthposition" with only 5 - you probably should hide the 3 leftover elements that would otherwise continue to display the last few "bodyplan" items. One way to do that is instead of setting your loop up based on the array length you could loop over the elements, and if the current element has an index beyond the end of the array hide it, something like this:
function changelabels(data) {
var i,
lbl,
elementCount = 20; // or whatever your element count is
for (i = 0; i < elementCount; i++) {
lbl = document.getElementById("rb" + (i+1) + "lbl");
if (i < data.length) {
lbl.innerHTML = data[i];
lbl.style.display = "";
} else {
lbl.innerHTML = "";
lbl.style.display = "none";
}
}
}
If these elements are labels for radio buttons (just a guess based on the ids) then you'd also want to hide or show the corresponding radio buttons, but I hope you can figure out how to add a couple of lines to the above to do that.
(As mentioned above, be careful about having element ids count up from 1 when the array indexes start at 0.)
If the above doesn't work please post (at least some of) the relevant HTML - obviously I've just had to guess at what it might be like.
SOLUTION: Changed the scope of the array variables to local by moving them into the function where they are used, instead of having them as global variables at the top of the page. I don't understand as I was following every rule of variable declaration. But for some unknown reason, global variables in javascript are abhorrent.
Solution Edit: Found an error in declaring my global variables. This may have been the source of my problem of why I could not access them. But it is a non-issue at this point since I corrected my code.
I don't understand what your trying to achieve exactly with your code. But to pass a variable (in this case an array) by reference you just have to add "&" before the variable.
function the_name(&$var_by_ref, $var_by_value) {
// Here if you modify $var_by_ref this will change the variable passed to the function.
}
More: http://php.net/manual/en/language.references.pass.php
Hope that helps.

Categories