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);
}
Related
I am using JS to paginate a data set. I also have the possibility to filter my dataset through tags. I want to hide the pagination navigation when I only have one page of results either for all results or when I use the filter. Here is the JS code:
var itemsNumber = 8,
$items,
pages = 1,
current = 1;
function makePages() {
$items = $(".filtered-div:visible");
pages = Math.ceil($items.length / itemsNumber);
$("#pages").empty();
for (var p = 1; p <= pages; p++) {
$("#pages").append($('' + p + ""));
}
showPage(1);
}
function showPage(page) {
$items
.hide()
.slice((page - 1) * itemsNumber, page * itemsNumber)
.show();
current = page;
$("div.ctrl-nav a").show();
if (current == 1) {
$("div.ctrl-nav a:first").hide();
} else if (current == pages) {
$("div.ctrl-nav a:last").hide();
}
$("div.ctrl-nav a.active").removeClass("active");
$("#pages a")
.eq(current - 1)
.addClass("active");
}
makePages();
$("div.ctrl-nav").on("click", "a", function () {
var action = $(this).html();
if (action == '<i class="fas fa-angle-left" aria-hidden="true"></i>') {
current--;
} else if (
action == '<i class="fas fa-angle-right" aria-hidden="true"></i>'
) {
current++;
} else if (+action > 0) {
current = +action;
}
if (current <= 1) {
current = 1;
} else if (current >= pages) {
current = pages;
}
showPage(current);
});
var $myitems = $(".filtered-div");
$(".btn-container").on("click", ".btn", function () {
var value = $(this).data("filter");
if (value == "all") {
$myitems.show();
} else {
var $selected = $myitems
.filter(function () {
return $(this).data("tag").indexOf(value) != -1;
})
.show();
$myitems.not($selected).hide();
}
$(this).addClass("active").siblings().removeClass("active");
makePages();
});
You can find my code at this codepen
As you already have a variable which stores the pages just ask it how many pages you have and hide the nav.
Before
function makePages() {
$items = $(".filtered-div:visible");
pages = Math.ceil($items.length / itemsNumber);
$("#pages").empty();
for (var p = 1; p <= pages; p++) {
$("#pages").append($('' + p + ""));
}
showPage(1);
}
After
function makePages() {
$items = $(".filtered-div:visible");
pages = Math.ceil($items.length / itemsNumber);
$("#pages").empty();
for (var p = 1; p <= pages; p++) {
$("#pages").append($('' + p + ""));
}
showPage(1);
if(pages <= 1) {
$("div.ctrl-nav").hide();
} else {
$("div.ctrl-nav").show();
}
}
You can check the selected data and itemsNumber.
If they are equal then hiden pagniation.
Refer
var $myitems = $(".filtered-div");
$(".btn-container").on("click", ".btn", function () {
var value = $(this).data("filter");
if (value == "all") {
$myitems.show();
} else {
var $selected = $myitems
.filter(function () {
return $(this).data("tag").indexOf(value) != -1;
})
.show();
if(itemsNumber == $selected.length) {
$("div.ctrl-nav").hide();
} // compare
$myitems.not($selected).hide();
}
$(this).addClass("active").siblings().removeClass("active");
makePages();
});
How can the global "x" variable be reduced in scope to local variable?
Please note that simply moving the "var x" inside the "showAddress" function will not work as the keyup event listener will reset the variable to 0 evetytime. Any help is appreciated.
document.getElementById("where").addEventListener("keyup", showAddress, false);
var x = 0;
function showAddress (e) {
var search = document.getElementById("where").value;
if (search.length < 2) {
document.getElementById("addressNav").innerHTML = '';
return 0;
} else {
var hr = new XMLHttpRequest();
var url = "/handlers/suggestAddress.php";
hr.open("POST", url, true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.onreadystatechange = function () {
if (hr.readyState == 4 && hr.status == 200) {
document.getElementById("addressNav").innerHTML = hr.responseText;
// click on the address
var divs = document.getElementById("addressNav").getElementsByTagName("div"), i;
for (i = 0; i < divs.length; i++) {
divs[i].onclick = function () {
document.getElementById("where").value = this.innerHTML;
document.getElementById("addressNav").innerHTML = '';
};
}
//navigate address from keyboard
if (e.keyCode == 38) {
if (x > 0) {
x -= 1;
} else {
x = divs.length - 1;
}
} else if (e.keyCode == 40) {
if (x < divs.length - 1) {
x += 1;
} else {
x = 0;
}
} else {
if (e.keyCode == 13) {
document.getElementById("where").value = divs[x].innerHTML;
document.getElementById("addressNav").innerHTML = '';
}
}
divs[x].setAttribute("class", "addressListKeyboard");
console.log(x);
}
};
hr.send("search=" + search);
}
}
Variable x should remember the last selected div and that's why it has global scope. Moving it to local scope will not work as showAddress is keyup event handler which will erase the value of x each time the keyup event occurs.
My menu is sliding down into the page as I want but it does not go up to a "0px" i marginTop when I click the image again. The image has a onclick="meny()" event.
var menu;
var x = 0;
function meny() {
menu = document.getElementById('menu-slider');
if(x = 1) {
menu.style.marginTop = "0px";
x = 0;
} else if(x = 0) {
menu.style.marginTop = "-300px";
x = 1;
}
};
You might want to get rid of the quotes here: x='0' and try x=1 instead of x=x+1 same goes for the else if
It should be
if(x == 1) {
...
} else if (x == 0) {
...
}
rather than
if (x = 1) {
...
} else if (x = 0) {
...
}
function getFormState() {
var fields = document.getElementsByTagName('form')[0].elements;
if (fields.length === 0) {
return;
};
for (var i = 0; i <= fields.length - 1; i++) {
var name = fields[i].getAttribute('name');
if (document.getElementByTagName('name').checked === true) {
localStorage.setItem('name', "true");
} else {
localStorage.setItem('name', "false");
}
}
}
function fillFormState() {
var fields = document.getElementsByTagName('form')[0].elements;
if (fields.length === 0) {
return;
};
for (var i = 0; i <= fields.length - 1; i++) {
var name = fields[i].getAttribute('name');
getStatus = localStorage.getItem('name'); {
if (getStatus === "true") {
console.log("its checked");
document.getElementByTagName("name").setAttribute('checked', 'checked');
} else {
console.log("its not checked");
}
}
}
} // run the below functions when the web page is loadedwindow.onload = function () {
// check if HTML5 localStorage is supported by the browser
if ('localStorage' in window && window['localStorage'] !== null) {
// get the form state
getFormState();
// save the state of the form each X seconds (customizable)
setInterval('fillFormState()', 1 * 1000);
}
};
But it doesn't seem to work. And Im trying to figure out why. Im not very experienced with javascript so it might be quite obvious. Sorry for that. Im trying.
I'm guessing your localStorage is never being set because of this loop:
for (var i = 0; i <= fields.length - 1; i++) {
var name = fields[i].getAttribute('name');
if (document.getElementByTagName('name').checked === true) {
localStorage.setItem('name', "true");
} else {
localStorage.setItem('name', "false");
}
}
There is no document.getElementByTagName, and you are also searching for "name" instead of your variable name.
for (var i = 0; i <= fields.length - 1; i++) {
var name = fields[i].getAttribute('name');
if (fields[i].checked === true) { //Check the current field
localStorage.setItem(name, "true"); //Set the actual name, not "name"
} else {
localStorage.setItem(name, "false");
}
}
All,
I have three cards which can be shuffled by the user, upon hover, the target card pops to the top, the last card on top should sit in the second position. While with the code below, I can have this effect in one direction (left to right), I am struggling to come up with logic & code for getting the effect to work in both directions without having to write multiple scenarios in js (which doesnt sound like very good logic).
Hopefully the demo will do a better explanation.
Code:
$(".cBBTemplates").on (
{
hover: function (e)
{
var aBBTemplates = document.getElementsByClassName ("cBBTemplates");
var i = 2;
while (i < aBBTemplates.length && i >= 0)
{
var eCurVar = aBBTemplates[i];
if (eCurVar === e.target)
{
eCurVar.style.zIndex = 3;
} else if (eCurVar.style.zIndex === 3) {
console.log (eCurVar);
eCurVar.style.zIndex = 3-1;
} else
{
eCurVar.style.zIndex = i;
}
i--;
}
}
});
Try this:
$(function(){
var current = 2;
$(".cBBTemplates").on (
{
hover: function ()
{
var target = this,
newCurrent, templates = $(".cBBTemplates");
templates.each(
function(idx){
if(this === target){
newCurrent = idx;
}
});
if(newCurrent === current){return;}
templates.each(function(index){
var zIndex = 0;
if(this === target) {
zIndex = 2;
}
else if (index == current) {
zIndex = 1;
}
$(this).css('zIndex', zIndex);
});
current = newCurrent;
}
});
});