How i make an element to be shown or not? - javascript

anchorArrows is an element that if I click the checkbox it must be shown and if it's not checked it must be hidden. The classList hidden and show are CSS classes with opacity 0 and 1
let q = document.getElementById("Q").value;
let q2 = document.getElementById("q2").value;
const anchorArrows = document.getElementById("anchor");
if((chkQ.checked == true) && (chkQ2.checked == false)){
anchorArrows.classList.add("show");
anchorArrows.classList.remove("hidden");
if(q > 0){
flechas(0,"x");
}else{
flechas(180,"x");
}
}else{
anchorArrows.classList.remove("show");
anchorArrows.classList.add("hidden");
}
if((chkQ2.checked == true) && (chkQ.checked == false)){
anchorArrows.classList.add("show");
anchorArrows.classList.remove("hidden");
if(q > 0){
flechas(0,"y");
}else{
flechas(180,"y");
}
}else{
anchorArrows.classList.remove("show");
anchorArrows.classList.add("hidden");
}
CSS:
.hidden{
opacity: 0;
}
.show{
opacity: 1;
}

You need to use else if and one else. The issue you have is the first if can be true, but the second else will wipe away the class.
if (chkQ.checked && !chkQ2.checked) {
anchorArrows.classList.add("show");
anchorArrows.classList.remove("hidden");
if (q > 0) {
flechas(0, "x");
} else {
flechas(180, "x");
}
} else if (chkQ2.checked && !chkQ.checked) {
anchorArrows.classList.add("show");
anchorArrows.classList.remove("hidden");
if (q > 0) {
flechas(0, "y");
} else {
flechas(180, "y");
}
} else {
anchorArrows.classList.remove("show");
anchorArrows.classList.add("hidden");
}
And to get rid of repeated code
let isValid = false;
if ((!chkQ.checked && chkQ2.checked) || (chkQ.checked && !chkQ2.checked)) {
isValid = true;
const num = +q > 0 ? 0 : 180;
const code = chkQ.checked ? "x" : "y";
flechas(num, code);
}
anchorArrows.classList.toggle("show", isValid);
anchorArrows.classList.toggle("hidden", !isValid);

Personally, I wouldn't use classes to change opacity, as multiple variables can affect the outcome of it. Instead, I would put opacity in the original Id/Class in the CSS, and use .style.opacity to change it.
For Example:
CSS:
#box {
opacity:1;
}
HTML:
<div id="box"></div>
Javascript:
document.getElementById('box').style.opacity = .5;
In your code, it would be anchorArrows.style.opacity = 1; for show, and anchorArrows.style.opacity = 0; for hidden.

Related

Hiding and unhiding a particular element

I'm trying to hide a particular element on my browser game.
When it reaches the point of being visible it has to stay visible.
At the moment I've tried a few approaches but none of them seem to do the last part which is keeping it visible when the number of clicks goes back under the amount needed to make it visible.
CSS:
upgrade3 {
display: none;
}
js1(which completely doesn't work):
function showPerk() {
if (clicks >= price3reached || totalupgradeperk3 > 0) {
do{
document.getElementById("upgrade3").style.display =="block";
}
while(document.getElementById("upgrade3".style.display === 'none'));
}
update();
}
js2 (works but hides the element when going under the amount needed):
if (blnhideperk = true) {
if (clicks >= price3reached || totalupgradeperk3 > 0) {
document.getElementById("upgrade3").style.display = "block";
blnhideperk === false;
} // use === its something wierd about js = / == / === all do different comparisons
else {
document.getElementById("upgrade3").style.display = "none";
}
}
upgrade
Try
document.getElementById("upgrade3").style.display = "none";
Note the 1 equal sign, not 2 or 3, as those have other uses.
if (blnhideperk = true){
if (clicks >= price3reached || totalupgradeperk3 > 0){
document.getElementById("upgrade3").style.display = "block";
blnhideperk === false;}}
and moving
document.getElementById("upgrade3").style.display = "block";
out of the loop istead of in the else statement
seemed to do the trick

Javascript Element.ClassName always returning true on mousewheel change

I have a scroll wheel function that changes the class of a div as you scroll down or up.
It is actually functioning really well in all modern browsers, the thing is, it is trying to change the class everytime it is executing, even though I have a validation that should stop this from happening.
The function asks that if the div already has that class active then it should not change, but if you look at the console it is trying to do it every time despite that validation.
I don't know why the className method always returns true.
I used jquery's hasClass function and had the same behavior.
Thank you so much for your help.
JAVASCRIPT CODE:
var sections = ['one', 'two', 'three', 'four', 'five'];
function changeSection(section) {
for (var x = 0; x < sections.length; x++) {
$('#bg-main').removeClass('bg-' + sections[x]);
if (sections[x] === section) {
if (document.getElementById('bg-main').className != ('bg-' + section)) {
$('#bg-main').addClass('bg-' + section);
console.log("Active: " + section);
} else {
console.log("Inactive: " + sections[x]);
}
}
}
}
var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel"
if (document.attachEvent)
document.attachEvent("on" + mousewheelevt, displaywheel)
else if (document.addEventListener)
document.addEventListener(mousewheelevt, displaywheel, false)
var position = 0;
function displaywheel(e) {
var evt = window.event || e
var delta = evt.detail ? evt.detail : evt.wheelDelta
if (delta < 0) {
position = (mousewheelevt == 'DOMMouseScroll') ? position - 1 : position + 1;
} else {
position = (mousewheelevt == 'DOMMouseScroll') ? position + 1 : position - 1;
}
if (position < 0) position = 0;
if (position > 100) position = 100;
// Change sections on Scroll
if (position >= 0 && position <= 19) {
changeSection('one');
} else if (position >= 20 && position <= 39) {
changeSection('two');
} else if (position >= 40 && position <= 59) {
changeSection('three');
}
if (position >= 60 && position <= 79) {
changeSection('four');
} else if (position >= 80 && position <= 100) {
changeSection('five');
}
}
CSS CODE:
#bg-main {
width: 100%;
height: 300px;
}
.bg-one {
background-color: blue;
}
.bg-two {
background-color: red;
}
.bg-three {
background-color: green;
}
.bg-four {
background-color: yellow;
}
.bg-five {
background-color: purple;
}
HTML CODE:
<div id="bg-main" class="bg-one">SCROLL TO SEE THE CHANGE OF BACKGROUND</div>
Working fidddle:
https://jsfiddle.net/9vpuj582/
You are removing the class before you check to see if the element has the class that you passed into your function (so your if statement will never evaluate as false).
The placement of the following line of code in your changeSection function is your issue:
$('#bg-main').removeClass('bg-'+sections[x]);
You could simplify your current function quite a bit. First check if the element already has the class you want. Then, if not, remove all classes from the element (rather than looping through them and checking each one) and then add the new class. For example:
const bg = $('#bg-main');
function changeSection(section) {
if (!bg.hasClass('bg-' + section)) {
bg.removeClass();
bg.addClass('bg-' + section);
}
}

How to check if switch is true or not to hide the div?

I have some problem when I check the function validation, I need when checking all the cassis is true hide the parent div * errors message *
var error_pass = false;
$('#pass').focusout(function(){
check_pass();
error_pass = false;
if(error_pass !== true){
console.log('its showing!');
}else{
$('.test').fadeOut('522');
}
});
function check_pass() {
var fpass= $('#pass').val();
switch(error_pass = true){
case(fpass.length < 6 ? $('#pass-error-message3').css('color','red'):$('#pass-error-message3').css('color','green') ):
$('#pass-error-message3').show();
case(fpass.search(/(?=.[a-z])(?=.*[A-Z])/) == -1 ? $('#pass-error-message4').css('color','red') : $('#pass-error-message4').css('color','green')):
$('#pass-error-message4').show();
case(fpass.search(/\d/) == -1 ? $('#pass-error-message2').css('color','red'):$('#pass-error-message2').css('color','green')):
$('#pass-error-message2').show();
default:break;
}
}
Use if else statements like this
function validation() {
var error = false;
if (fpass.length < 6) {
error = true;
$('#pass-error-message3').css('color', 'red').show();
} else {
$('#pass-error-message3').css('color', 'green');
}
if (fpass.search(/(?=.[a-z])(?=.*[A-Z])/) == -1) {
error = true;
$('#pass-error-message4').css('color', 'red').show();
} else {
$('#pass-error-message4').css('color', 'green')
}
if(fpass.search(/\d/) == -1){
error = true;
$('#pass-error-message2').css('color','red').show();
}else{
$('#pass-error-message2').css('color','green');
}
if(error === false){
hideParentDiv(); // Here hide the div
}
}
Much cleaner approach

Simplifying IF/ELSE IF/ELSE Block

I'm creating my own validation code. I need to separate the if statements per input box for the error to show at the same time. I noticed that if it's on same if block, only the first error will show. Any way to simplify my code?
flag = 0;
//first if
if (first_name.length == 0) {
flag = 0;
$("label[for='firstname'").text('This field is required').css("display", "inline-block");
} else if (!first_name.match(name_regex)) {
flag = 0;
$("label[for='firstname'").text('Firstname must be composed of letters only').css("display", "inline-block");
} else if (first_name.length < 3) {
flag = 0;
$("label[for='firstname'").text('3 letters are required for lastname').css("display", "inline-block");
} else {
flag = +1;
$("label[for='firstname'").hide();
}
//second if
if (last_name.length == 0) {
flag = 0;
$("label[for='lastname'").text('This field is required').css("display", "inline-block");
} else if (!last_name.match(name_regex)) {
flag = 0;
$("label[for='lastname'").text('Lastname must be composed of letters only').css("display", "inline-block");
} else if (last_name.length < 2) {
flag = 0;
$("label[for='lastname'").text('2 letters are required for lastname').css("display", "inline-block");
} else {
$("label[for='lastname'").hide();
flag += 1;
}
//third if
if (validateEmail(email)) {
if (data.result) {
$("input#userEmail").css("border-color", "#ac2925");
$("label[for='email'").text('Email exists').css("display", "inline-block");
} else {
$("input#userEmail").css("border-color", "#e3e3e3");
$("label[for='email'").hide();
flag += 1;
}
} else {
$("input#userEmail").css("border-color", "#ac2925");
$("label[for='email'").text('Please input a valid email address').css("display", "inline-block");;
}
//fourth if on verification success
if (flag == 3) {
alert("All validation succeded!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Just extract it into a function:
function validate(inputName, labelName, minLetters, regex){
const el = $(inputName);
const label = $(labelName);
if(!el || !!label) throw "validate: el not found";
if(!el.val()){
label.text("You need to fill in this!");
return false;
}
if(regex && !el.val().test(regex)){
label.text("The input contains invalid chars!");
return false;
}
if(minLetters && el.val().length < minLetters){
label.text("to short!");
rerurn false;
}
return true;
}
I would suggest to make the validation routine more generic. Please see following solution (note: untested):
function validate(funcName, minLength) {
if (this[funcName].length == 0) {
$("label[for='"+funcName+"'").text('This field is required').css("display", "inline-block");
} else if (!this[funcName].match(name_regex)) {
flag = 0;
$("label[for='"+funcName+"'").text(funcName +' must be composed of letters only').css("display", "inline-block");
} else if (this[funcName].length < minLength) {
$("label[for='"+funcName+"'").text(minLength + ' letters are required for ' + funcName).css("display", "inline-block");
} else {
$("label[for='"+funcName+"'").hide();
return true;
}
return false;
}
if (validate("firstname", 2)
&& validate("lastname", 3)
&& validateEmail(email)
) {
// everything seems to be OK.
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
My approaches will be :
Have individual If blocks for each validations by which all the validations will be checked. And build/append the validation error message on each check.
Write if else blocks within a function. That function can be called for each fields being validated. And the function will return validation error message for each invokation which can be appended into a single string.

Unexpectedly passing integer by reference?

I'm having some issues with this. For some reason, updateCurrentItem is always called with the same parameter regardless.
function updatePromoList(query) {
query = query.toUpperCase();
clearCurrentList();
var numItems = 0;
currentItem = 0;
result_set = cached[query.charAt(0)][query.charAt(1)][query.charAt(2)];
for(i in result_set){
if(numItems >= NUMBER_MATCHES){
$("<li/>").html("<span style='color: #aaa'>Please try to limit your search results</span>").appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(numItems+1); });
break;
}
promo = result_set[i];
found_number = false;
if (!promo.client)
found_number = (promo.prj_number.toString().substr(0,query.length) == query) ? true : false;
if (query.length >= MATCH_NAME) {
if(promo.prj_name && typeof promo.prj_name == 'string'){
found_name = promo.prj_name.toUpperCase().indexOf(query);
} else {
found_name = -1;
}
if (promo.client)
found_client = promo.client_name.toString().indexOf(query);
else
found_client = -1;
} else {
found_name = -1;
found_client = -1;
}
if(found_client >= 0) {
var thisIndex = numItems+1;
console.log("setting", thisIndex);
$("<li/>").text(promo.client_name).bind('click',function(e){ updatePromoChoice(e,promo); }).appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(thisIndex); }); } else if(found_name >= 0 || found_number) { var thisIndex = numItems+1;
console.log("setting", thisIndex);
$("<li/>").text(promo.prj_number+": "+promo.prj_name).bind('click',function(e){ updatePromoChoice(e,promo); }).appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(thisIndex); });
}
if(found_number || found_client >= 0 || found_name >= 0){
numItems++;
}
}
}
function updateCurrentItem(i){
currentItem = i;
console.log("updating to", i);
}
The results of running this are:
setting 0
setting 1
setting 2
setting 3
setting 4
setting 5
setting 6
setting 7
setting 8
setting 9
setting 10
setting 11
setting 12
setting 13
then when I move my mouse over the content area containing these <li>s with the mouseOver events, all I ever see is:
updating to 4
Always 4. Any ideas?
You're creating a closure but it's still bound to the numItems variable:
function(event){ updateCurrentItem(numItems+1); }
What you should do is something like this:
(function(numItems){return function(event){ updateCurrentItem(numItems+1); }})(numItems)
Edit: I think I might have the wrong function but the same principle applies:
function(event){ updateCurrentItem(thisIndex); }
should be
(function(thisIndex)
{
return function(event){ updateCurrentItem(thisIndex); }
})(thisIndex)

Categories