How can I simplify this using Javascript or jQuery? - javascript

I have 4 vertical sliding panels and I am using the following code for it. Is there any way I can simplify the code?
$(".sliding-panels").click(function() {
var n = $(this).attr("number");
$(".panel" + n).toggleClass("panel-active");
if (n == 1) {
$(".panel2").toggleClass("panel-push-right");
$(".panel3").toggleClass("panel-push-right");
$(".panel4").toggleClass("panel-push-right");
}
else if (n == 2) {
$(".panel1").toggleClass("panel-push-left");
$(".panel3").toggleClass("panel-push-right");
$(".panel4").toggleClass("panel-push-right");
}
else if (n == 3) {
$(".panel1").toggleClass("panel-push-left");
$(".panel2").toggleClass("panel-push-left");
$(".panel4").toggleClass("panel-push-right");
}
else if (n == 4) {
$(".panel1").toggleClass("panel-push-left");
$(".panel2").toggleClass("panel-push-left");
$(".panel3").toggleClass("panel-push-left");
}
});

How about replacing the if statement with:
var i, toggle_class;
for (i = 1; i <= 4; ++i) {
if (i === n) { toggle_class = "panel-active"; }
else if (i < n) { toggle_class = "panel-push-left"; }
else /* i > n */ { toggle_class = "panel-push-right"; }
$(".panel" + i ).toggleClass(toggle_class);
}

This may be a bit of a stretch, but assuming all the elements have the same class (maybe it even is .sliding-panels?) and are in order, i.e.
<div class="panel1"></div>
<div class="panel2"></div>
<div class="panel3"></div>
...
you can do:
var $panels = $(".sliding-panels").click(function() {
var n = $(this).attr("number") - 1;
$panels.toggleClass(function(index) {
return index === n ?
'panel-active' :
(index < n ? 'panel-push-left' : 'panel-push-right');
});
});
Let jQuery handle the element traversal.

Related

How to make multiple conditions inside single filter

I am trying to make a filter based on checkboxes.
The thing is js ignoring other conditions inside filter when one is active
filterData() {
return this.airlines.filter(x => {
if (this.filters.options.length != 0 || this.filters.airlines.length != 0) {
for (let i = 0; this.filters.options.length > i; i++) {
if (this.filters.options[i] == 0) {
return x.itineraries[0][0].stops == 0;
}
if (this.filters.options[i] == 1) {
return x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
}
}
} else {
return x;
}
})
}
I know that return will stop the current loop, but is there any way to do it correctly?
Update-1: (When to filter record for every case checked OR case)
Replace for loop and all conditions in a single return by && for if and || condition for data:
var chbox = this.filters.options;
return $.inArray(0, chbox) != -1 && x.itineraries[0][0].stops == 0
|| $.inArray(1, chbox) != -1 && x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
Hope this helps !!
$.inArray(value, arr) method will check for each checkboxes and will work for every checked ones .
Update-2 (When to filter record for every case checked AND case)
As per comment below, you are trying to use checkbox on demand so use below code:
var chbox = this.filters.options;
boolean condition = true;
if ($.inArray(0, chbox) != -1) {
conditon = conditon && x.itineraries[0][0].stops == 0;
}
if ($.inArray(1, chbox) != -1) {
conditon = conditon && x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
}
return condition;
Your filter function is returning an object, which ideally should be a boolean value. Please refactor the code as below.
filterData() {
return this.airlines.filter(x => {
let result = false;
if (this.filters.options.length != 0 || this.filters.airlines.length != 0) {
for (let i = 0; this.filters.options.length > i; i++) {
if (this.filters.options[i] == 0) {
result = x.itineraries[0][0].stops == 0;
break;
} else if (this.filters.options[i] == 1) {
result = x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
break;
}
}
}
return result;
})
}

Math.pow returning 0 in calc

I'm making a calculator currently and I'm running into an issue with one of the functions, specifically x^y, it keeps returning 0 and not even seeming to run the setInterval at all, though it runs without the if function around it. fn is for which function its using which is x^y, and vi is just a tool in the calculator to distinguish which number you are changing as in reactant, or reactant2, reactants are the 2 numbers that are squared against each other in this case. (this is only the portion of the code with the problem)
function click15(){
if (reactant > 0) {
reactant = parseFloat(reactant);
}
if (reactant2 > 0) {
reactant2 = parseFloat(reactant2);
}
if (fn === 0) {
product = reactant / reactant2;
} else if (fn === 1) {
product = reactant * reactant2;
} else if (fn === 2) {
product = reactant - reactant2;
} else if (fn === 3) {
product = reactant + reactant2;
} else if (fn === 4) {
if (vi === 0) {
vi = 1;
var timer = setInterval(function(){
if (vi === 0) {
product = (Math.pow(reactant, reactant2));
clearInterval(timer);
}
}, 4);
}
}
reactant = product;
product = 0;
reactant2 = "0";
vir = 0;
vir2 = 0;
vi = 0;
di1 = 0;
di2 = 0;
fn = -1;
}

clear javascript : determine which link was clicked

I have a cycle of links and I determined click event on them. And I want to define if navbar[1].clicked == true {doing something} else if navbar[2].cliked == true {doing something} etc. "By if else in " reveal functional callbackFn".
Here is the code:
var navbar = document.getElementById("navbar").getElementsByTagName("a");
for (var i = 0; i < navbar.length; i++) {
navbar[i].addEventListener('click', function() { reveal('top'); });
}
function reveal(direction) {
callbackFn = function() {
// this is the part where is running the turning of pages
classie.remove(pages[currentPage], 'page--current');
if (navbar[1].clicked == true) {
currentPage = 0;
} else if(navbar[1].clicked == true) {
currentPage = 1;
} else if(navbar[2].clicked == true) {
currentPage = 2;
} else if(navbar[3].clicked == true) {
currentPage = 3;
} else if(navbar[4].clicked == true) {
currentPage = 4;
};
classie.add(pages[currentPage], 'page--current');
};
}
This is typically a problem of closure.
You can make the following change
Here the call back function of the addEventListener is an IIFE, & in the reveal function pass the value of i
var navbar = document.getElementById("navbar").getElementsByTagName("a");
for (var i = 0; i < navbar.length; i++) {
navbar[i].addEventListener('click', (function(x) {
reveal('top',x);
}(i))};
}
In this function you will have access to
function reveal(direction,index) {
// not sure what this function is mean by, but you will have the value of `i` which is denote the clicked element
callbackFn = function() {
// this is the part where is running the turning of pages
classie.remove(pages[currentPage], 'page--current');
if (index == 1) {
currentPage = 0;
} else if (index == 1) {
currentPage = 1;
} else if (index == 2) {
currentPage = 2;
} else if (index == 3) {
currentPage = 3;
} else if (index == 4) {
currentPage = 4;
};
classie.add(pages[currentPage], 'page--current');
};
}
Here is the solution in my case.
Thank you brk for helping in any case, thanks again.
// determine clicked item
var n;
$('#navbar a').click(function(){
if($(this).attr('id') == 'a') {
n = 0;
} else if($(this).attr('id') == 'b') {
n = 1;
} else if($(this).attr('id') == 'c') {
n = 2;
} else if($(this).attr('id') == 'd') {
n = 3;
} else if($(this).attr('id') == 'e') {
n = 4;
};
});
var pages = [].slice.call(document.querySelectorAll('.pages > .page')),
currentPage = 0,
revealerOpts = {
// the layers are the elements that move from the sides
nmbLayers : 3,
// bg color of each layer
bgcolor : ['#52b7b9', '#ffffff', '#53b7eb'],
// effect classname
effect : 'anim--effect-3'
};
revealer = new Revealer(revealerOpts);
// clicking the page nav
document.querySelector("#a").addEventListener('click', function() { reveal('cornertopleft'); });
document.querySelector("#b").addEventListener('click', function() { reveal('bottom'); });
document.querySelector("#c").addEventListener('click', function() { reveal('left'); });
document.querySelector("#d").addEventListener('click', function() { reveal('right'); });
document.querySelector("#e").addEventListener('click', function() { reveal('top'); });
// moving clicked item's `n` into the function
function reveal(direction) {
var callbackTime = 750;
callbackFn = function() {
classie.remove(pages[currentPage], 'page--current');
currentPage = n;
classie.add(pages[currentPage], 'page--current');
};
revealer.reveal(direction, callbackTime, callbackFn);
}

How to create a pause in recursion function loop

I'm new here so sorry if dublicate.
I'm trying to write a sudoku solver using backtracking method to make it pass all data dynamically into the document with its each recursion. When I tried to use setInterval() or setTimeout() it doesn't work the way I want it to work. What I need should be similar to this
Here's the code:
function backtrack(position) {
if (position === 81) {
return true;
}
if (sudokuArray[position] > 0) {
backtrack(position + 1);
} else {
for (var x = 1; x <= 9; x++) {
if (isValid(x, parseInt(position / 9), position % 9) === true) {
sudokuArray[position] = x;
//some code that invokes putSudokuArrayBack function with a small delay
//everytime backtrack function is invoked
if (backtrack(position + 1) === true) {
return true;
}
}
}
sudokuArray[position] = 0;
return false;
}
}
function putSudokuArrayBack() {
for (var i = 0; i <= 81; i++) {
var indexString = '#val-' + parseInt(i / 9) + '-' + i % 9;
$(indexString).val(sudokuArray[i]);
}
}
Any ideas(if it's even possible)? Thanks in advance!

Shortening if, else if, else if ... else using loops

I have the following lines of code:
$(function(){
$("div").scroll(function() {
function hpos(id) {
var pos = $("#" + id).position();
return pos.top;
}
function final(id) {
$("#header").html($("#" + id).html()),
$("h1").css("visibility","visible"),
$("#" + id).css("visibility","hidden");
}
if (hpos(5) < 0) {
final(5);
}
else if (hpos(4) < 0) {
final(4);
}
else if (hpos(3) < 0) {
final(3);
}
else if (hpos(2) < 0) {
final(2);
}
else {
final(1);
}
});
});
Shouldn't I be able to shorten it by using a loop instead of the else if statements? I can't find a way to make the loops work with my position().
for (var i = 5; i > 0; i--){
if (hpos(i) < 0) {
final(i);
break;
}
}
would something like this work? Not tested by the way
This should be shorter:
$.each([5,4,3,2], function(i,v) {
if( hpos(v) < 0 ) {
final(v);
return false;
} else if( v === 2 ) {
final(1);
}
});
An easier way to do lots of else if statements is to use the case method.
In case you need a while version:
:)
var elemId = 5;
while (elemId > 1) {
if (hpos(elemId) < 0) {
break;
}
elemId--;
}
final(elemId);

Categories

Resources