Can't set the number of paginations with JavaScript - javascript

I'm trying to add the numbers of pagination using Javascript. The arrows navigation is working fine but when I try to add the numbers of pages my code doesn't work. I have 2 pages with 10 results each. When I click in the number 1 the console print the number 3. The problem is inside the function createPagination when I create the loop for the page numbers. Any help?
var arrFull = [];
var pageSize = 10;
var pages = -1;
var actualPage = 0;
function changePagination(pagination) {
if(Number(pagination) !== actualPage && pagination > 0 && pagination <= pages) {
var start = ((pagination - 1) * pageSize) + 1;
if(pagination === 1) {
ini = 0;
}
var end = pagination * pageSize;
if(end > arrFull.length) {
end = arrFull.length;
}
var arr = arrFull.slice(start,end);
for(var i = 0; i < arr.length; i++) {
createObject(arr[i]);
}
actualPage = Number(pagination);
createPagination();
}
}
function createPagination() {
var paginator = document.getElementById('pagination');
paginator.innerHTML = "";
var arrowLeft = document.createElement('a');
arrowLeft.setAttribute('href', '');
var arrowRight = document.createElement('a');
arrowRight.setAttribute('href', '');
arrowLeft.innerHTML = '<span class="arrow"></span>';
arrowLeft.addEventListener('click', function(event) {
event.preventDefault();
changePagination(actualPage - 1);
});
arrowRight.innerHTML = '<span class="arrow"></span>';
arrowRight.addEventListener('click', function(event) {
event.preventDefault();
changePagination(actualPage + 1);
});
paginator.appendChild(arrowLeft);
for(var pagination = 1; pagination <= pages; pagination++) {
var number = document.createElement('a');
number.setAttribute('href', '');
number.innerHTML = pagination;
number.addEventListener('click', function(event) {
event.preventDefault();
changePagination(pagination);
console.log(pagination);
});
paginator.appendChild(number);
}
paginator.appendChild(arrowRight);
}

When you pass on your pagination variable it passes the last value set to it in that context (the 3 because of its last iteration in the loop).
You should declare a variable inside the click event and assign to it the value of pagination and then pass your local variable to your method:
number.addEventListener('click', function(event)
{
let currentPage = pagination;
event.preventDefault();
changePagination(currentPage);
console.log(currentPage);
});
That should do the trick.
Edit
This is the actual solution:
number.setAttribute("page", pagination);
number.addEventListener('click', function(event) {
let currentPage = +event.target.getAttribute("page");
event.preventDefault();
changePagination(currentPage);
console.log(currentPage);
});
The reason why the number 3 is being returned is because the let currentPage = pagination; line is being executed when the event triggers; by that time the value of the variable pagination is equal to 3, so you need to save its value through every iteration (it can be saving it inside a property within your element outside of the event scope like so: number._pageNumber = pagination;; or as the given example: number.setAttribute("page", pagination);).
Full implementation
<html>
<body>
<!--Element to simulate the pagination-->
<div id="pagination"></div>
<script>
var arrFull = [];
var pageSize = 10;
var pages = 2; // Change to simulate your case (changed the '-1' to '2')
var actualPage = 0;
function changePagination(pagination) {
if(Number(pagination) !== actualPage && pagination > 0 && pagination <= pages) {
var start = ((pagination - 1) * pageSize) + 1;
if(pagination === 1) {
ini = 0;
}
var end = pagination * pageSize;
if(end > arrFull.length) {
end = arrFull.length;
}
var arr = arrFull.slice(start,end);
for(var i = 0; i < arr.length; i++) {
createObject(arr[i]);
}
actualPage = Number(pagination);
createPagination();
}
}
function createPagination() {
var paginator = document.getElementById('pagination');
paginator.innerHTML = "";
var arrowLeft = document.createElement('a');
arrowLeft.setAttribute('href', '');
var arrowRight = document.createElement('a');
arrowRight.setAttribute('href', '');
arrowLeft.innerHTML = '<span class="arrow"></span>';
arrowLeft.addEventListener('click', function(event) {
event.preventDefault();
changePagination(actualPage - 1);
});
arrowRight.innerHTML = '<span class="arrow"></span>';
arrowRight.addEventListener('click', function(event) {
event.preventDefault();
changePagination(actualPage + 1);
});
paginator.appendChild(arrowLeft);
for(var pagination = 1; pagination <= pages; pagination++) {
var number = document.createElement('a');
number.setAttribute('href', '');
number.innerHTML = pagination;
// <Here_is_the_sugested_code> //
number.setAttribute("page", pagination);
number.addEventListener('click', function(event) {
let currentPage = +event.target.getAttribute("page");
event.preventDefault();
changePagination(currentPage);
console.log(currentPage);
});
// </Here_is_the_sugested_code> //
paginator.appendChild(number);
}
paginator.appendChild(arrowRight);
}
createPagination(); // Call to the function to simulate the generation
</script>
</body>
</html>

Related

Carousel with dynamic images

Hello I want to implement a carousel in Java Script.
When I launch the page the image loads very strangely and the bootstrap carousel does not work. Do I need to import something to make it work? If I make it static in HTML it works. However the task is to load the images with iiif. Also, there would be way too many images to make it static. Also, I would like to have a filter function implemented which only works dynamically.
Can someone help me how to implement the carousel?
Here is all the JS code:
'import bootstrap.js'
function changeIIIFInformation(iiif, size, quality) {
var index = iiif.indexOf('full')
iiif = iiif.substring(0, index)
iiif += "full/"
iiif += "pct:" +size.toString() +"/"
iiif += "0/"
iiif += quality +".jpg"
return iiif
}
function search_period(period, max_num, offset) {
var count = 0;
var link = ""
var div = document.createElement('div')
var div1 = document.createElement ('div')
var a=document.createElement('a')
var span1=document.createElement('span')
var span2=document.createElement('span')
a.setAttribute('class','carousel-control-prev')
a.setAttribute('href','#carouselExampleControls')
a.setAttribute('role','button')
a.setAttribute('data-slide','prev')
span1.setAttribute('class','carousel-control-prev-icon')
span1.setAttribute('aria-hidden', 'true')
span2.setAttribute('class','sr-only')
span2.innerHTML = 'Previous'
div.setAttribute('class', 'carousel slide')
div.setAttribute('data-ride', 'carousel')
div.setAttribute('id', 'carouselExampleControls')
div1.setAttribute('class','carousel-inner')
var h2 = document.createElement('h2')
var iiif = ""
h2.innerHTML = period
document.body.appendChild(h2)
const keys = Object.keys(urls);
for(const elem of keys) {
var label = urls[elem].label
for(const el of urls[elem].variants) {
if(el.label.includes('front')) {
iiif = el.url
}
}
if(!periods.hasOwnProperty(label)) {
continue;
}
if(periods[label] != period) {
continue;
}
if(count < offset) {
count+=1
continue
}
var div2= document.createElement ('div')
div2.setAttribute('class','carousel-item active')
link = changeIIIFInformation(iiif, 10, "default")
var figure = document.createElement('figure')
var figcaption = document.createElement('figcaption')
var linkToImage = document.createElement('a')
//linkToImage.setAttribute('#image', label)
linkToImage.setAttribute('href', 'annotator#'+label)
linkToImage.innerHTML = label
figcaption.appendChild(linkToImage)
var image = document.createElement('img')
image.setAttribute("id", "myimg");
image.setAttribute('src', link)
image.setAttribute('class','d-block w-100')
// figure.appendChild(image)
// figure.appendChild(figcaption)
div.appendChild(div1)
div.appendChild(a)
div1.appendChild(div2)
a.appendChild(span1)
a.appendChild(span2)
div2.appendChild(image)
figure.setAttribute("id", "myFigure");
count += 1;
if(count >= max_num+offset) {
break;
}
}
document.body.appendChild(div)
}
function clear_dom() {
var elements = document.getElementsByTagName('div')
var headings = document.getElementsByTagName('h2')
var buttons = document.getElementsByTagName('button')
while(buttons.length > 0) {
buttons.item(0).remove()
}
while(elements.length > 0) {
elements.item(0).remove()
}
while(headings.length > 0) {
headings.item(0).remove()
}
}
function show_initial_load() {
search_period('Ur III (ca. 2100-2000 BC)', )
}
function show_filtered(selected, offset) {
clear_dom()
search_period(selected, 10, offset)
var previous = document.createElement('button')
if(offset-10 < 0) {
previous.onclick = () => show_filtered(selected, 0)
} else {
previous.onclick = () => show_filtered(selected, offset-10)
}
previous.innerHTML = 'Previous'
document.body.appendChild(previous)
var next = document.createElement('button')
next.onclick = () => show_filtered(selected, offset+10)
next.innerHTML = 'More'
document.body.appendChild(next)
}
function update_view() {
var selected = document.getElementById('perriod-select').value
clear_dom()
if(selected == '') {
show_initial_load()
} else {
show_filtered(selected, 0)
}
}

Automatically Change Individual Table Data Using Javascript

I'm trying to mimic the look of a stock-exchange board, but can't seem to automatically change text without stopping another.
I've tried
var text = ["2.0%", "1.7%", "1.9%", "1.8%", "1.9%"];
var counter = 0;
var elem = document.getElementById("n1");
var inst = setInterval (change, 1000);
function change () {
elem.innerHTML = text[counter];
counter++;
var content = document.getElementById("n1");
if (counter >= text.length) {
counter = 0;
}
}
var text = ["-12.0%", "-13.7%", "-13.9%", "-12.8%", "-13.9%"];
var counter = 0;
var elem = document.getElementById("n2");
var inst = setInterval (change, 1000);
function change () {
elem.innerHTML = text[counter];
counter++;
var content = document.getElementById("n2");
if (counter >= text.length) {
counter = 0;
}
}
To no avail.
You can't have two different functions with the same name. One will override the other.
I created a single function that accomplishes your goals by passing in the target element and the data as arguments.
function change(elem, data) {
let counter = 0;
setInterval(function() {
elem.innerHTML = data[counter];
counter++;
if (counter >= data.length) {
counter = 0;
}
}, 1000);
}
change(document.getElementById("n1"), ["2.0%", "1.7%", "1.9%", "1.8%", "1.9%"]);
change(document.getElementById("n2"), ["12.0%", "2.7%", "3.9%", "4.8%", "5.9%"]);
<div id="n1"></div>
<div id="n2"></div>

Uncaught ReferenceError: showCurrentPage is not defined at HTMLButtonElement.onclick

Having a mare with this one...
I have a function, which displays pagination ( 1, 2, 3 etc) buttons, for each page of my todo app results.
Specifically for example, if you click on button 2, you'll see page 2 of the results. Here's the full function and the buttons are being inserted via template literals:
// CREATE BUTTONS FOR EACH PAGE THAT EXISTS
function displayNumberedButtons(bookMarksArray) {
for (let x = 0; x < bookMarksArray.length; x++)
listArray.push(x);
numberOfPages = Math.ceil(listArray.length / numberPerPage);
let individualPagesArray = [];
for (var i = 1; i <= numberOfPages; i++) {
individualPagesArray.push(i);
}
// BUTTONS ARE ADDED HERE
for (var i = 0; i < individualPagesArray.length; i++) {
document.getElementById("numbers").innerHTML += `<button onclick=showCurrentPage(${i+1})>` + individualPagesArray[i] + `</button>`;
}
}
However, my onclick function, does not seem to register in my JavaScript:
// PAGINGATION CTAS
window.showCurrentPage = (i) => {
currentPage = i;
paginationCountLogic(bookMarksArray);
}
If I click on any button, I get the following error. And I have no idea why, as I can see the buttons in my DOM.
index.html:1 Uncaught ReferenceError: showCurrentPage is not defined
at HTMLButtonElement.onclick (index.html:1)
This only happens when I compiled my JS files in advanced mode, using google closure compiler. Otherwise, this works fine if the files are not compiled.
Not sure how to resolve this.
Here is the full order the code appears as in my script:
function Pagination() {
let listArray = new Array(); //store the collection of data to be sorted.
let pageList = new Array(); //keep track of the items to display on the current page only
const numberPerPage = 3;
let currentPage = 1; //keep track of where we are in the pagination
let numberOfPages = 1; // calculates the total number of pages
const list = document.querySelector('.url-list');
let nextButton = document.getElementById("next");
const previousButton = document.getElementById("previous");
let bookMarksArray = window.localStorage.getItem('bookMarksArray') ? JSON.parse(window.localStorage.getItem('bookMarksArray')) : [];
// CREATE BUTTONS FOR EACH PAGE THAT EXISTS
function displayNumberedButtons(bookMarksArray) {
for (let x = 0; x < bookMarksArray.length; x++)
listArray.push(x);
numberOfPages = Math.ceil(listArray.length / numberPerPage);
let individualPagesArray = [];
for (var i = 1; i <= numberOfPages; i++) {
individualPagesArray.push(i);
}
for (var i = 0; i < individualPagesArray.length; i++) {
document.getElementById("numbers").innerHTML += `<button id="${i+1}" onclick=showCurrentPage(${i+1})>` + individualPagesArray[i] + `</button>`;
}
}
// CALCULATE WHEN PAGINATION SHOULD BEGIN AND STOP
function paginationCountLogic(bookMarksArray) {
let begin = ((currentPage - 1) * numberPerPage);
let end = begin + numberPerPage;
pageList = bookMarksArray.slice(begin, end);
nextButton.disabled = currentPage === numberOfPages ? true : false;
previousButton.disabled = currentPage === 1 ? true : false;
displayBookmarks(pageList);
}
// DISPLAY BOOKMARKS
function displayBookmarks(pageList) {
list.innerHTML = "";
for (let r = 0; r < pageList.length; r++) {
list.innerHTML +=
`<div>
<form class="text animated slideInDown bookmarksForm" id=${pageList[r].name}>
<input class="nameItem" type="text" name="name" value=${pageList[r].name} id="name" placeholder="Name">
<input class="urlItem" type="url" name="url" value=${pageList[r].url} id="url" placeholder="https://example.com">
<button type="button" class="js-edit-url" id="edit">edit</button>
<button type="button" class="js-delete-url" id="delete">delete</button>
</form>
</div>`;
}
}
// PAGINGATION CTAS
window.showCurrentPage = (i) => {
currentPage = i;
paginationCountLogic(bookMarksArray);
}
window.nextPage = () => {
currentPage += 1;
paginationCountLogic(bookMarksArray);
}
window.previousPage = () => {
currentPage -= 1;
paginationCountLogic(bookMarksArray);
}
return {
displayNumberedButtons,
displayBookmarks,
paginationCountLogic
};
}
The cause is probably that the compiler doesn't see the function being called. Part of the advanced compilation is removing unused code and renaming the methods/variables.
Within your js or html it is never called because the function call is only defined in a string value here :
for (var i = 0; i < individualPagesArray.length; i++) {
document.getElementById("numbers").innerHTML += `<button onclick=showCurrentPage(${i+1})>` + individualPagesArray[i] + `</button>`;
}
you can solve this pretty simply by rewriting this:
window.showCurrentPage = (i) => {
to this:
window['showCurrentPage'] = (i) => {
See : https://developers.google.com/closure/compiler/docs/api-tutorial3#removal

How to make horizontal margin between images constant in mosaic

I am trying to replicate a mosaic that can be found on many webpages. While looking for solutions to my problem I came accross a very good implementation on squarespace seen at https://native-demo.squarespace.com/images-native/. I have hosted my website containing the mosaic at http://alexstiles.000webhostapp.com.
My issue is that when you resize the window the horizontal spacing between the images flucuates like it has an animation instead of staying consistient. Although it sorts itself out if you resize slowly, rapid movements can cause the margin to be to large or small. This behavior is not present in the squarespace template. How can I remove this and make the margin consistient when resizing? I have already tried using css margins instead of javascript. I have added the javascript below to help.
let mosaic = document.getElementsByClassName("mosaic")[0]; // For a single mosaic for now
let numImages = 12;
let imageTopic = "design";
let originalImageTopic = "design";
let rowWidth = 3;
let scale = 1;
let mosaicLoader = document.getElementsByClassName("loader-container")[0]
let search = document.getElementById("search");
let searchBtn = document.getElementById("search-button");
let form = document.getElementsByTagName("form")[0];
function rem(rems) {
return rems * (16 * scale);
}
searchBtn.addEventListener("click", function(event) {
event.preventDefault();
searchResult(search.value);
});
search.addEventListener("click", function() {
form.classList.add("focused");
});
search.addEventListener("blur", function() {
form.classList.remove("focused");
});
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '13' || e.which == '13' || e.key === "Enter") {
e.preventDefault();
searchResult(search.value);
}
}
if (window.location.hash) {
let hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
search.value = hash;
searchResult(hash);
}
function searchResult(query) {
// Get and set query
query = ((query != "" && query != originalImageTopic) ? search.value : imageTopic);
imageTopic = query;
if (imageTopic != originalImageTopic) {
parent.location.hash = imageTopic;
document.getElementById("search-term").textContent = imageTopic + " pictures";
}
// Put up loader while fetching images
mosaicLoader.style.display = "flex";
// Remove old images
let length = mosaic.children.length;
while (mosaic.lastChild && length > 1) {
mosaic.removeChild(mosaic.lastChild);
length--;
}
// Create new images
let loadedImageNum = 0
for (let i = 0; i < numImages; i++) {
let image = document.createElement("img");
image.src = `https://source.unsplash.com/random?${imageTopic}/sig${i}/`;
mosaic.appendChild(image);
}
// Wait for all images to load
let loadedImages = 0;
let image = mosaic.querySelectorAll("img");
imageCheck = setInterval(function() {
for (let i = 0; i < numImages; i++) {
if (image[i].naturalHeight !== 0 && image[i].complete) {
loadedImages++;
}
if (loadedImages == numImages) {
clearInterval(imageCheck);
// alert("Loaded!")
// Lay them out
setTimeout(imagesLoaded, 2000); // Needs some time before laying out
// Break loop
break;
}
}
}, 200)
}
searchResult(imageTopic); // Inital images with no search query
window.onload = function() {
windowResizeEvents();
}
window.onresize = function() {
windowResizeEvents();
}
function windowResizeEvents() {
imagesLoaded();
}
function mosaicCalibration() {
let images = document.querySelectorAll(".mosaic img");
if (window.innerWidth < 750) {
mosaic.classList.add("column");
} else if (window.innerWidth < 1100) {
rowWidth = 2;
} else {
rowWidth = 3 // Math.round(window.innerWidth/(426 + (2/3)));
}
if (window.innerWidth > 750) {
mosaic.classList.remove("column");
for (let i = 0; i < images.length; i++) {
images[i].style.width = `calc((100% - ${((rowWidth - 1) * 1)}rem) / ${rowWidth})`;
}
}
}
function imagesLoaded() {
// Find out row width, image width, etc
mosaicCalibration();
// Remove loader and set height to 0 so new height can be calculated
mosaicLoader.style.display = "none";
mosaic.style.height = 0;
// Define variables
let images = document.querySelectorAll(".mosaic img");
let row = 0;
let rowNum = 0;
let margin = rem(1.25);
let imageWidth = ((mosaic.scrollWidth - (2 * margin)) / rowWidth);
let column = [];
for (let i = 0; i < images.length; i++) {
images[i].style.top = i > rowWidth - 1 ? column[i-rowWidth] + margin : 0;
if (row < rowWidth) {
if (window.innerWidth > 1100) {
images[i].style.left = row * imageWidth + (row >= 1 ? row * margin : 0);
} else {
images[i].style.left = row * imageWidth + (row >= 1 ? (row + 0.5) * margin : 0);
}
row++
} else {
images[i].style.left = 0;
row = 1;
rowNum++;
}
if (rowNum > 0) {
column.push(column[i-rowWidth] + images[i].scrollHeight + margin);
} else {
column.push(images[i].scrollHeight);
}
}
mosaic.style.height = mosaic.scrollHeight;
}

Random LocalStorage Jquery

I have a group of divs called "oponente", and if the user do not click on one of them in five seconds the script will choose one randomly. What I dont know how to do is to keep in LocalStorage which div the script had choose. Here is my script, I dont know what to write on 'key name' and so on.
$(document).ready(function () {
$(".oponente").addClass("gray");
var elements = $(".oponente");
var elementCount = elements.size();
var elementsToShow = 1;
var alreadyChoosen = ",";
var i = 0;
while (i < elementsToShow) {
var rand = Math.floor(Math.random() * elementCount);
if (alreadyChoosen.indexOf("," + rand + ",") < 0) {
alreadyChoosen += rand + ",";
setTimeout(function () {
elements.eq(rand).window.localStorage.setItem('key name', 'key name');
}, 5000);
++i;
}
}
});
You can store index of selected one. Then you can get child from the parent with that index number clearly.
Let me simulate
$(document).ready(function () {
$(".oponente").addClass("gray");
var elements = $(".oponente");
var elementCount = elements.size();
var elementsToShow = 1;
var alreadyChoosen = ",";
var i = 0;
while (i < elementsToShow) {
var rand = Math.floor(Math.random() * elementCount);
if (alreadyChoosen.indexOf("," + rand + ",") < 0) {
alreadyChoosen += rand + ",";
setTimeout(function () {
localStorage.setItem('indexOfSelected', selectedDiv.index());
}, 5000);
++i;
}
}
});
Then you can get the selected div with
var indexOfSelected = localStorage.getItem('indexOfSelected');
myDiv = parentDiv.children(":eq("+indexOfSelected+")")
All you need to init a selectedDiv then a parentDiv which is parent of the selectedDiv.

Categories