Image gallery with max items and pagination with javascript - javascript

This is my situation:
I have a image gallery with 10 images visible on the main page and a pagination bar. The images came from a for loop iteration over a json file. That's no problem, they are just there ;-)
Something like:
for i=0; i <10; i++
create div with styles and images[i].image;
My question is:
I want to display the next 10 images on page 2, so when you click on page 2, it counts from 11 to 20.
I found the jQuery 'Jpaginate'-plugin...
Can i accomplish that with this plugin?
Could someone explain me in the way i have to thing with Vars, Counts, Objects??
Thanks and kind regards,
Mike

I have made you an example on how you can approach this. I'm not saying it is bugproof, but it's the concept that matters. You might find some inspiration and maybe reach your goal.
var imgSrc = "https://s-media-cache-ak0.pinimg.com/236x/36/a5/7b/36a57b0f0ab16e885fcc230addb695c2.jpg";
var json = [];
for (var i = 0; i < 36; i++)
json.push({
Title: "Title " + (i + 1),
Source: imgSrc
});
/*
Just for ease, I'm creating an array with 36 objects (3x3 gallery)
so 9 images per page
*/
var pageLimit = 9;
var page = 1;
showImages();
$("#btnPrevious").click(function() {
if (pageLimit <= 9) {
pageLimit = 9;
page = 1;
} else {
page--;
pageLimit -= 9;
}
showImages();
});
$("#btnNext").click(function() {
if (pageLimit >= json.length) {
pageLimit = json.length;
} else {
page++;
pageLimit += 9;
}
showImages();
});
function showImages() {
$(".images").empty();
for (var i = pageLimit - 9; i < pageLimit; i++) {
var template = $("<div></div>").addClass("template");
var img = $("<img>");
img.attr("src", json[i].Source);
img.attr("alt", json[i].Title);
var br = $("<br/>");
var title = $("<span></span>").html(json[i].Title);
template.append(img).append(br).append(title);
$(".images").append(template);
}
$("#page").html("Page " + page);
}
.gallery {
width: 100%;
height: 500px;
border: 1px solid black;
background-color: lightgray;
text-align: center;
}
.images {
width: 90%;
margin: 0 auto;
height: 100%;
margin-bottom: 15px;
}
img {
height: auto;
width: 33%;
margin: 20px 5px;
}
.template {
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gallery">
<div class="images"></div>
<button id="btnPrevious">
< Previous
</button>
<span id="page"></span>
<button id="btnNext">
> Next
</button>
</div>
Don't mind the CSS, because I suck at that (lol). It was based on the space I had on jsFiddle, but looking at it now (on full page or just the area the snippet provides) it looks awful. If a CSS guru could fix this .. Question in a question?

You can create your own pagination plugin.
You must store current page somewhere and modify your factory.
Something like: for i=current_page * count_per_page; i < count_per_page * (current_page + 1); i++ create div with styles and images[i].image;

Related

progressbar html tag change

I'am working on progressbar that change the level when reaching some point.
The code.
I want to change the text under the progressbar when the progressbar reach 100 or above 90.
I could change it once but I want to go to next level, like this.
silver ==> gold ==> diamond ==> and more
const step = 5;
var content=document.getElementById('mylevel').innerHTML;
const updateProgress = () => {
const currentWidth = Number(document.getElementById("progressvalue").style.width.replace( "%", ""));
if (currentWidth>=100) {
return;
}
else {
document.getElementById("progressvalue").style.width = `${currentWidth+step}%`;
}
if (currentWidth > 90) {
document.getElementById("mylevel").textContent = "gold";
document.getElementById("progressvalue").style.width = "0%";
}
if (currentWidth > 90 && content == "gold") {
document.getElementById("mylevel").textContent = "diamond";
document.getElementById("progressvalue").style.width = "0%";
}
}
const restart = () => {
document.getElementById("progressvalue").style.width = "0%";
}
.progress {
background-color: #ededed;
width: 100%;
overflow: hidden;
}
#progressvalue {
height: 40px;
background-color: lightgreen;
width: 0%;
}
<div class="progress">
<div id="progressvalue"></div>
</div>
<p id="mylevel">silver</p>
<br />
<button type="button" onclick="updateProgress()">
Update Progress
</button>
<button type="button" onclick="restart()">
Restart
</button>
When the updateprogress is above 90 the silver change to gold, but I need to change again to diamond when the updateprogress is again above 90.
Am I putting the if condition in a wrong place, I tried many times.
I don't know what I'am missing and am new with JavaScript
I started the code but got help here to make it much better (80% of the code done by
teresaPap thanks)
Update
After closer inspection it is an issue of content not updating you need to put it inside updateProgress() or it will forever remain the initial value.
const step = 5;
const updateProgress = () => {
var content = document.getElementById('mylevel').innerHTML;
//the rest of the code
I do however recommend you to improve your if statements. You only need one if for this task.
A better solution
A better solution would be something like this:
Add a hidden value to keep your level progress
</div>
<p id="hiddenlevel">0</p>
<p id="mylevel">silver</p>
<br />
and css:
#hiddenlevel {
height: 0px;
visibility: hidden;
width: 0%;
}
now that you have a hidden value you can wrap up all future ifs in a single one.
const levels = ["silver", "gold", "diamond"]
var mylevel = Number(document.getElementById("hiddenlevel").innerHTML);
if(currentWidth > 90 && mylevel < levels.length){
document.getElementById("hiddenlevel").textContent = mylevel + 1;
document.getElementById("mylevel").textContent = levels[mylevel + 1];
document.getElementById("progressvalue").style.width = "0%";
}
and just like that you can just add a new level inside the levels array and it will be added without issues.
Update 2
Just noticed I made a mistake!
You don't need a hidden element for this: you might end up having to use hidden elements when using plugins, but it was completely unnecessary here :)
Updated code:
const step = 5;
var mylevel = 0;
const updateProgress = () => {
const currentWidth = Number(document.getElementById("progressvalue").style.width.replace( "%", ""));
if (currentWidth>=100) {
return;
}
else {
document.getElementById("progressvalue").style.width = `${currentWidth+step}%`;
}
const levels = ["silver", "gold", "diamond"];
if(currentWidth > 90 && mylevel < levels.length){
mylevel = mylevel + 1;
document.getElementById("mylevel").textContent = levels[mylevel];
document.getElementById("progressvalue").style.width = "0%";
}
}
const restart = () => {
document.getElementById("progressvalue").style.width = "0%";
}
.progress {
background-color: #ededed;
width: 100%;
overflow: hidden;
}
#progressvalue {
height: 40px;
background-color: lightgreen;
width: 0%;
}
<div class="progress">
<div id="progressvalue"></div>
</div>
<p id="mylevel">silver</p>
<br />
<button type="button" onclick="updateProgress()">
Update Progress
</button>
<button type="button" onclick="restart()">
Restart
</button>

Add clicks when differents div are clicked

Im working on a project and i have basically some troubles with things for my website.
This one is a bit hard for me, i have some ideas but i dont know how to do them in my javascript code.
I have 98 divs (it's a calendar where you can select everyday differents hours to book slots).
There is a Summary (kinda same thing on commercial website) which i want that it says how many slots you selected. But the problem is that i have like I said 98div so i wanna do it in one function.
On the slots you want to book, you can click on it (it selects it) and if you click on it again it deselects it.
I want that you can select as many slots that you want, and the summary shows how many you selected then you can go to next step.
Here is my code if you guys have some ideas !
function x1(e) {
var target = e.target,
count = +target.dataset.count;
target.style.backgroundColor = count === 1 ? "#707070" : 'black';
target.dataset.count = count === 1 ? 0 : 1;
target.innerHTML = count === 1 ? '' : 'réserver';
target.classList.toggle('Resatxt');
target.classList.toggle('unselectable');
}
Actually this code is for the selection of the slots (it's going background black when you clicl on it, and then back to the normal color when you deselect it).
But i think i can do what i want with this.
I thinked about incrementing +1 when we click on the div but the problem that i dont know how to figure it out is when you deselect it you have to do -1 but im a bit lost.
I tried to be clear but ik that is not really.
If you guys have some ideas, go for it.
Thanks a lot
it's nice to see that your joining the programming community. I hope I understood you correctly and made a simple and minimal example to present you how can you achieve what you want. This is just an idea, don't take it too serious and write your own logic to handle the functionality!
const divs = 98;
const list = document.querySelector("#list");
const selectedList = document.querySelector("#selectedList");
let selected = [];
let elementsAdded = 1;
const onSelectDiv = (element) => {
const elementCopy = element.cloneNode(true);
elementCopy.id += "-copy";
selected = [
...selected,
{
id: elementsAdded,
elementId: element.id
}
];
elementsAdded += 1;
selectedList.appendChild(elementCopy);
};
const onClick = (e) => {
if (e.target.className.includes("selected")) {
e.target.classList.remove("selected");
elementsAdded -= 1;
const elementToDelete = selected.findIndex(
(x) => e.target.id === x.elementId
);
selectedList.removeChild(selectedList.childNodes[elementToDelete + 1]);
selected = selected.filter((x) => x.elementId !== e.target.id);
return;
}
onSelectDiv(e.target);
e.target.className += " selected";
};
for (let i = 0; i < divs; i++) {
const div = document.createElement("div");
div.innerHTML += i;
div.className += "div";
div.id = i;
div.addEventListener("click", function (event) {
onClick(event);
});
list.appendChild(div);
}
.view {
display: flex;
flex-direction: 'column';
}
#list {
display: flex;
width: 400px;
max-width: 500px;
flex-wrap: wrap;
}
.div {
padding: 5px;
background-color: black;
cursor: pointer;
color: white;
border-radius: 10px;
margin: 10px;
}
.selected {
background-color: red;
color: white;
}
<div class="view">
<div>
<p>Elements:</p>
<div id="list">
</div>
</div>
<div>
<p>Selected:</p>
<div id="selectedList">
</div>
</div>
</div>

Can't access the style using DOM [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
For some reason, the error keeps being thrown at me whenever I hover over the selected element. It seems like every time I use the .style property, it gives me this error. The problem is how I'm accessing the CSS element using .style. Is there another way of doing it?
Uncaught TypeError: Cannot read property 'style' of undefined
var image = document.getElementsByClassName("image");
var move = document.getElementsByClassName("link");
var description = document.getElementsByClassName("description");
for(var i = 0; i < move.length; i++){
move[i].addEventListener("click", function(){
if (move[i].style.marginLeft === "500px") {
move[i].style.marginLeft = "0";
} else {
move[i].style.marginLeft = "500px";
}
})
};
for(var i = 0; i<description.length;i++){
image[i].addEventListener("mouseover", function(){
description[i].style.visibility = visible;
description[i].style.opacity = 0;
var last = +new Date();
var tick = function(){
despcription[i].style.opacity = +despcription[i].style.opacity + (new Date() - last)/700;
last = +new Date();
if (+despcription[i].style.opacity < 1) {
(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
}
};
tick();
});
}
You have a typo: despcription
despcription[i].style.opacity = +despcription[i].style.opacity + (new Date() - last)/700;
last = +new Date();
if (+despcription[i].style.opacity < 1) {
And I don't know if you are trying to do more than this, but are you attempting to fade in an image on hover? If so, then setting this in CSS works well:
EDIT: I updated the sample to show a title under the image when you hover over the image. The key is the ~ (sibling) selector right here:
.image:hover~.image-title {
opacity: 1;
}
It says when the user hovers over the image class, then select the sibling element with class of .image-title and set its opacity to 1.
.image {
background-image: url('https://amazingslider.com/wp-content/uploads/2012/12/dandelion.jpg');
height: 300px;
width: 300px;
background-size: cover;
background-position: center;
}
.image:hover~.image-title {
opacity: 1;
}
.image-title {
opacity: 0;
transition: opacity 1s ease;
display: inline-block;
width: 300px;
text-align: center;
margin: 0;
}
<h1>Hover Over Image</h1>
<div class="image"></div>
<h3 class="image-title">Image Title</h3>

Firefox OS - BuildingBlock drawer usage

I am developing a Firefox OS based application what uses the building block drawer component. My problem is when I click the top-left corner icon - the drawer shows up properly - but the content of the main page disappears. Could you suggest me a solution?
Thanks.
If your intent is to clear each list (Projects, Users, Plugins) when someone clicks on them, you could remove line visibility attribute from the tablist in tabs.css
[role="tablist"] [role="tabpanel"] {
position: absolute;
top: 4rem;
left: 0;
/*visibility: hidden;*/
width: 100%;
height: calc(100% - 4rem);
z-index: -1;
display: block;
overflow: auto;
}
And then clear the list in your code. You will need to do this for each of the functions:
function clearLists(){
$("#resultsProjects").empty();
$("#resultsUsers").empty();
$("#resultsPlugins").empty();
}
function processProjects() {
return function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var obj = jQuery.parseJSON(xhr.responseText);
clearLists();
for (var i = 0; i < obj.length; i++) {
$('#resultsProjects').append("<li><p>" + obj[i].name + "</p><p>" + obj[i].lang + "</p></li>");
}
}
}
}

Trying to make these divs not reset position when I add new one with jquery

I have tried changing the keyup part of the code to a button and I have also tried some code to get the draggable element to store its position in the cookie but to no avail. When I change the empty tag to ready it repeats the previous lines every time. Any help would be much appreciated.
jsFiddle for original code
jsFiddle for my attempt at a button
HTML
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<textarea></textarea>
<div id="opt"></div>
CSS
d {
position: relative;
left: 0;
top: 0;
width: 60px;
height: 60px;
background: #ccc;
float: left;
font-family: arial;
font-size: 10px;
}
JavaScript
$(document).ready(function() {
$("textarea").keyup(splitLine);
function splitLine() {
$("#opt").empty();
var lines = $("textarea").val().split(/\n/g);
for (var i = 0; i < lines.length; i++) {
var ele = $("<d>");
ele.html(lines[i]);
$("#opt").append($(ele).draggable());
}
}
});
I think you shouldn't remove all your <d> and start over every time. I have made some changes in the code to reuse the old <d> so that it's position is preserved
$(document).ready(function () {
$("textarea").keyup(splitLine);
function splitLine() {
//$("#opt").empty();
var lines = $("textarea").val().split(/\n/g);
for (var i = 0; i < lines.length; i++) {
var ele;
if ($("d:eq(" + i + ")").get(0)) {
ele = $("d:eq(" + i + ")");
ele.html(lines[i]);
} else {
ele = $("<d>");
ele.html(lines[i]);
$("#opt").append($(ele).draggable());
}
}
}
});

Categories