else condition is always executed even if the if statement is true - javascript

I am trying forever to fix this code: i have a list and i am searching through the list to find students. Once i don't find a student, an error message should appear. At the moment i have a function who searches the student based on text match. I have an if statement inside the function. When the match is found show student and when not, hide all the students. I created a variable 'found' set to 'true' when the student is found. if this is false the message should be appended.
The problem is that both conditions are being executed it seems so if i put found as being false inside the second condition the error message will display every time.
At the moment i have another if which checks if found was false. the problem is it doesn't recognise that it is false...so confusing. Please see screenshot with the console where you can see that although the student is found, the second condition is executed each time... screenshot with the console - second condition is always executed
First condition doesn't execute unless it's true.
Please help as I am trying to investigate this forever and I asked lots of questions here around this issue but with no big results.
Thanks so much,
Alina
var ul = document.getElementsByClassName("student-list");
var li = document.getElementsByTagName("li");
//add search bar
$( ".page-header" ).append('<div class="student-search"></div>');
$( ".student-search" ).append('<input id="input-search" placeholder="Search for students..."/><button id="search">Search</button>');
// append to the .page the container div for the error message
$('.page').append('<div class="error"></div>');
// append to the error div a p with the error message if student is not found
var found = true;
//myFunction
function myFunction() {
var input = document.getElementById("input-search");
var filter = input.value.toUpperCase();
for (var i = 0; i < li.length; i+=1) {
var h = li[i].getElementsByTagName("h3")[0];
if (h.innerHTML.toUpperCase().indexOf(filter) != -1) {
li[i].style.display = "";
console.log('yey found it');
found = true;
} else {
li[i].style.display = "none";
console.log('condtion 2');
}
}
if (found===false) {
$('.error').append('<p>"student not found!"</p>');
}
$('.pagination').hide();
}
//myFunction end
$('#search').on('click', function(){
myFunction();
});
// when the input is empty return to page 1, empty the error div, show pagination,
$('#input-search').on('keyup', function() {
if($(this).val() === '') {
go_to_page(0);
$('.pagination').show();
}
});

I think the function is called more than once judging that 'condition 2' got logged 50 times , and the condition isn't satisfied every time,
To make sure that it doesn't reach the else statement even if the code entered the if statement edit the function to be like this:
function myFunction() {
var input = document.getElementById("input-search");
var filter = input.value.toUpperCase();
found = false
for (var i = 0; i < li.length; i+=1) {
var h = li[i].getElementsByTagName("h3")[0];
if (h.innerHTML.toUpperCase().indexOf(filter) != -1) {
li[i].style.display = "";
console.log('yey found it');
found = true;
} else {
li[i].style.display = "none";
console.log('condtion 2');
}
}
if (found===false) {
$('.error').append('<p>"student not found!"</p>');
}
$('.pagination').hide();
console.log('--------------------------------------');
}
That way you see how many times the function was being called

Related

How can I fix my for loop in a javascript quiz?

I'm making a javascript quiz using a single HTML page. For some reason, my code will only display one question and upon clicking the element, it does not go to the next question. And it doesn't start the quiz with the first question.
I used a for loop inside a for loop. The first loop renders the question and then the other renders its corresponding choices. The questions and choices are held in an array containing the objects.
I've only been coding with Javascript and jQuery for a few weeks, so you'll have to tell me in beginner terms. I will have to refactor it. I apologize for it being somewhat messy.
I tried taking out the return commands. Same with preventDefault, no changes.
function renderQuiz(i) {
$heading.text("");
$mainDiv.text("");
$heading.text(quizQuestions[i].question);
for (var j = 0; j < quizQuestions[i].choices.length; j++) {
//console.log(quizQuestions[0].choices.length);
var li = document.createElement("li");
li.innerText = JSON.stringify(quizQuestions[i].choices[j]);
$mainDiv.append(li);
};
$('li').on("click", function() {
if (event.target.matches('li')) {
event.preventDefault();
var guess = event.target.innerText;
var answer = (JSON.stringify(quizQuestions[i].answer[0]));
if (guess === answer) {
timeLeft += 10;
console.log(timeLeft + "it works");
} else {
timeLeft -= 10;
console.log(timeLeft)
};
}
});
return;
};
mainPage();
$button.on("click", function(click) {
event.preventDefault();
for (var i = 0; i < quizQuestions.length; i++) {
renderQuiz(i);;
}
});
The $button click event is iterating through all of the questions, that is why the last question is the one displayed.
You need to define the variable i outside of the $button click function, then increment i on each click of the button.
var i = -1;
function renderQuiz(i) {
...
};
mainPage();
$button.on("click", function(click) {
event.preventDefault();
renderQuiz(++i);
});
There is an error in the $button onclick handler (in your console you should have "Uncaught ReferenceError: event is not defined").
If the function takes click as parameter then you should apply the method preventDefault() to that same parameter. In other words instead of
$button.on("click", function(click) {
event.preventDefault();
you should have
$button.on("click", function(event) {
event.preventDefault();
By the way there is the same error here
$('li').on("click", function() {
you should have
$('li').on("click", function(event) {
I hope this help.

Why doesn't the removeChild remove the element?

I have written this scrip to take out ads on a website. Was working on it the whole day.
This is the JS code:
var timer = setInterval(deletor, 1);
function deletor() {
timer;
var slider = document.querySelector("#slider-con");
var bannerTop = document.querySelector("#MainContent > div:nth-child(2)")
var bannerMiddle = document.querySelector("#MainContent > iframe");
var bannerRandom = document.querySelector("#MainContent > div:nth-child(7)");
var bannerRandom2 = document.querySelector("#MainContent > div:nth-child(6)");
if (slider == undefined) {
return false;
} else {
slider.parentNode.removeChild(slider);
};
if (bannerTop == undefined) {
return false;
} else {
bannerTop.parentNode.removeChild(bannerTop);
};
if (bannerMiddle == undefined) {
return false;
} else {
bannerMiddle.parentNode.removeChild(bannerMiddle);
};
if (bannerRandom == undefined) {
return false;
} else {
bannerRandom.parentNode.removeChild(bannerRandom);
};
if (bannerRandom2 == undefined) {
return false;
} else {
bannerRandom2.parentNode.removeChild(bannerRandom2);
};
};
Now, as you can see, it gets the values first and then goes through if statements. Idea behind this is: On first try, it deletes the elements and on the second one, it stops the function.
But when I inserted this last element, it won't delete it. The ID is correct, everything is correct but it won't delete the element, so I keep getting the same alert over and over.
Also, I found out that, I get this banner ad on two places. When I have "var bannerRandom = document.querySelector("#MainContent > div:nth-child(7)");" this, it appears as "document.querySelector("#MainContent > div:nth-child(6)")" this, and when I have both, it appears as "document.querySelector("#MainContent > div:nth-child(6)")" this. And it's not deleted.
Console shows no errors.
Your various statements in the form:
if (slider == undefined) {
return false;
} else {
slider.parentNode.removeChild(slider);
};
mean this: "If slider wasn't found in the DOM, exit the function. Otherwise, remove the slider and continue the function."
So that means your function will terminate the first time one of the elements you're looking for doesn't exist. Since it terminates then, none of the other elements after it is checked. That seems unlikely to be what you want to do.
You probably just wanted:
if (slider) {
slider.parentNode.removeChild(slider);
}
...and so on.
Note that you don't put ; at the end of a block attached to a flow-control statement like if or else, which is why I've removed it above. (Doing so is harmless, because JavaScript ignores them; but it's pointless.)

Validating only visible sections of a form

I've been trying to get this working for days and am just going around in circles, no matter what resource I read. I think I'm going to have a ton of errors in my code but I just can't figure it out.
I've got a form that I'm wanting to break down into smaller parts, on the click of a next button it will validate all the data in that section then hide it and show the next section. I've also got the issue of my form adds in sections depending on if the person has a partner or children. I'm not sure on how to handle that so would really appreciate some tips.
Here's my validation function, the jfiddle for the full code is below
$(".next").click(function() {
$('#travelform').find(":visible").find("input[required]").each(function(){
var myPattern = $(this).attr('pattern');
var myPlaceholder = $(this).attr('placeholder');
var isValid = $(this).val().search(myPattern) >= 0;
var isEmpty = true;
var abort = false;
$("div.error").remove();
//traverse through each required field to ensure it's been filled in
$(':input[required]').each(function() {
if($(this).val()==='') {
$(this).after('<div class="error">This is a required field</div>');
abort = true;
}
});
if (abort) { return false;} else {return true;}
});
});
Fiddle: https://jsfiddle.net/gq4kyhs3/
Why don't you add a class to all the inputs that have been validated and have a value and then check for this each time next is pressed like this:
$(".next").click(function() {
$('#travelform').find(":visible").find("input[required]").each(function(){
var myPattern = $(this).attr('pattern');
var myPlaceholder = $(this).attr('placeholder');
var isValid = $(this).val().search(myPattern) >= 0;
var isEmpty = true;
var abort = false;
$("div.error").remove();
//traverse through each required field to ensure it's been filled in - Added this check in to see if it has already been checked...if not then continue...
if ($(this).hasClass('checked-and-filled') {
$(':input[required]').each(function() {
if($(this).val()==='') {
$(this).after('<div class="error">This is a required field</div>');
abort = true;
} else {
// if the value is not empty then we know its been checked and it has a value
addClass('checked-and-filled');
}
});
if (abort) { return false;} else {return true;}
}
});
Also a quick comment about your HTML. I noticed this in your fiddle but I think you might have this error in your actual code...
On all of the part sentences you start with a h3 tag but end with a h2:
<h3 class="center">Part 1 of 5</h2>

jquery validation loop producing false positives

$(document).ready( function()
{
// hides the story and error text when the page loads
$('.errorText').hide();
$("#story").hide();
// global variables for the blanks and the textarea forms
var input = $("form").children();
var storyBlank = $('#story').children();
// Main Event on Click
$('button.submit').on( "click", function (event)
{
// if the form is not validated, highlights errors and prevents the submit from going through
if(!validate())
{
event.preventDefault();
}
// if the form is validated, fills the blanks in the story and displays it
else
{
fillInTheBlanks();
}
});
// Checks to see if there are any empty fields and highlights them if they are empty
function validate()
{
console.log('validate() initiated')
var success = false;
errcnt = 0;
cnt = 0;
while (cnt < 9)
{
if (input.eq(cnt).val().length == 0)
{
errcnt++;
input.eq(cnt).removeClass("hide");
console.log('errorcount', errcnt, 'at input', cnt);
}
else if (input.eq(cnt).val().length !== 0 && !(input.eq(cnt)).hasClass("hide"))
{
input.eq(cnt).addClass("hide");
}
cnt++;
}
if (errcnt == 0)
{
success = true;
}
return success;
}
// Fills in the blanks of the story
function fillInTheBlanks()
{
console.log('fillInTheBlanks() executed');
var blankCount = 0;
while (blankCount < 9)
{
storyBlank.eq(blankCount).empty().append(input.eq(blankCount).val());
blankCount++;
}
$("#story").show();
}
});
I am trying to make a mad libs style page with 9 textboxes for input. I am running into two problems.
First, when I click submit with all textboxes empty, only the the first four show an error (this is done in css, I have two classes on all the textboxes "error hide", I remove the class hide in my loop to show the error).
The second problem I'm having is if I click submit with text in all the textboxes, my validate functions errorcount goes up to 4 errors at every other textbox. I've even tried '$('input').eq(0).val().length == 0' for every textbox in the index and it's returning false every time. I don't understand how it's getting into that if then statement if it doesn't satisfy the argument.
i don't understand your problem, but if is validation on inputs empty... using
http://parsleyjs.org/

Javascript size of a form object

I have a very critical issue.
Below is my jsp code:
<html:select property="city" name="city" onchange="javascript:checkCity(this);">
<html:option value="N">NewYork</html:option>
<html:option value="F">France</html:option>
<html:option value="I">Italy</html:option>
<html:option value="P">Paris</html:option>
</html:select>
There can be single or multiple html select since my <html:select> is placed in for loop.
Below is my Javascript code:
var citySelected = new Array();
function checkCity(selObject)
{
var form = document.forms[0];
var cityObj = form["city"];
var len = cityObj.length;
if(selObject==cityObj) // if there is single <html:select> selObject is same as city Object.so this logic works fine
{
if(cityObj.value==cityObj.options[3].value)
{
alert("You have selected Paris City");
citySelected[0] = true;
}
if(!cityObj.options[3].selected && cityObj[0])
{
var result = confirm("You have selected cities other than paris");
if(result)
{
citySelected[0] = false;
}
else
{
cityObj.options[cityObj.options.selectedIndex].selected=false;
cityObj.options[3].selected=true;
}
}
}
else{
for(var i=0; i<len; i++) { //if there are multiple <html:select> then take length of form object n iterate
if (selObject == cityObj[i] )
{
if(cityObj[i].value==cityObj[i].options[3].value) // if 3rd option is selected
{
alert("You have selected Paris City");
citySelected[i] = true;
}
if(!sctypeObj[i].options[3].selected && citySelected[i]) //if 3rd option is deselected
{
var result = confirm("You have selected cities other than paris");
if(result)
{
cityObj[i] = false;
}
else
{
cityObj[i].options[cityObj[i].options.selectedIndex].selected=false;
cityObj[i].options[3].selected=true;
}
}
}
}
}
}
Below is Javascript which works on jsp onload():
function onload()
{
var form = document.forms[0];
var formObj = form["city"];
var size=formObj.size;
var len = formObj.length;
for(var i=0; i<len; i++) {
citySelected[i] = false;
}
if(size==0){ //if there is seingle <html:select> element
var cityvalue=formObj.value;
if(cityvalue=="P")
{
citySelected[0] = true;
}
}
else
{
for(var i=0; i<len; i++) { //if there are multiple <html:select> elements
var cityvalue=formObj[i].value;
if(cityvalue=="P")
{
citySelected[i] = true;
}
}
}
}
Here is where am finding problem. Onload if there is single or multiple <html:select> elements the logic works fine.But when there are no <html:select> elements at all in my jsp per say if I have option to delete all dropdowns then my jsp throws Javascript error:
"size is null or not an object".
How do I resolve this? In onload() function I am differentiating between <html:select> element using size.
if(size==0)
{
//logic for single <html:select>
}
else
{
//logic for multiple html select
}
But when there are no <html:select> elements at all in my jsp per say if I have option to delete all dropdowns then my jsp throws Javascript error:
"size is null or not an object".
How do I resolve this? Any help would be great..
An alternate way to determine the number of <select> elements within a form would be to use jQuery's selectors like so:
$('#myForm select').length // returns number of <select> elements in the form
You can use the fact that null/undefined evaluates to false in Javascript, like so:
if(!size)
{
//logic for single <html:select>
}
else
{
//logic for multiple html select
}
The line var size=formObj.size; could be the cause of the problem. Try using an "or" statement to prevent the error when the size attribute is null or undefined:
var size = formObj.size || 0;
If for single select element length is returning 4, then it seems that other select elements present inside jsp with the same name and those are hidden.
However, getElementByName('propertyName') is not a correct function to iterate collection type, rather we need getElementsByName('propertyName').
Use:
var formObj = document.getElelementsByName('city');
var length = formObj.length;
if(length == 0) {
// No select element
}
if(length == 1) {
// One select element
} else {
// More than one select elements
}
I am not sure how size will help here, this is not required. Size always will be returning undefined in this case.

Categories