what i am trying to do is make the first 12 elements hidden and show the next 12 elements and reverse, its like a next page and previous page in a search result.
Got this code from Jquery hide first 12 elementes, show next 12 elements
DEMO
<div class="inner-content">
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">151</div>
<div class="front-pro">152</div>
<div class="front-pro">152</div>
etc...
</div>
<div>next</div>
var x = $(".inner-content div").hide();
$("div:contains(next)").click(function() {
var cnt = $(this).data("cnt") || 0;
if((cnt * 12) > x.length){ cnt = 0; }
x.hide().filter(":eq("+ (cnt * 12) + "), :lt(" + ((cnt * 12) + 12) + "):gt(" + (cnt * 12) + ")").show();
$(this).data("cnt", ++cnt);
});
This code works but i want to reverse it with a previous button
You could try this :
JQuery
$(".next").click(function() {
var childEls = $('.inner-content').find('.front-pro').not(".visible") ; // array
var count = 1;
$.each(childEls, function() {
if (count <= 12) {
$(this).toggleClass('visible');
}
count++;
});
});
$(".prev").click(function() {
var count = 1;
$($('.inner-content').find('.visible').get().reverse()).each(function() {
if (count <= 12) {
$(this).toggleClass('visible');
}
count++;
});
})
Here's a link to demonstrate - JsFiddle
Something along these lines would have been my approach.
Since you retrieve all of the elements that you are working with in x.
I would look into the Jquery Slice() method where you can ask for a subset of the selector results. Not complete per say, but I hope it helps you get to where you want.
var x = $(".inner-content div").hide();
var $nextdiv = $("div:contains(next)");
var $previousdiv = $("div:contains(previous)");
var pageNum = 0;
var numOfPages = Math.ceil(x.length / 12);
$nextdiv.click(function() {
if (pageNum < numOfPages) {
var toshow = x.slice(pageNum * 12, pageNum * 12 + 12).show(); // show next 12
x.not(toshow).hide(); // hide all others
pageNum++;
}
});
$previousdiv.click(function() {
if (pageNum > 0) {
pageNum--;
var toshow = x.slice((pageNum - 1) * 12, (pageNum - 1) * 12 + 12).show(); // show last pages 12 records
x.not(toshow).hide(); // hide all others
}
});
https://jsfiddle.net/3rk53h7L/5/
Related
I'm trying to display Open or Closed based on a shift (two Shifts daily) using Javascript. I want to be able to use that data which is stored within a span and then determine if the business is open or closed and display that. for me only one shift is working during second shift its displaying We are now closed.
Might be something better to do the same but only in HTML.
any other suggestion is appreciated.
Here is the code I have so far:
function isOpen(timeRangeEl, date) {
var day = '' + date.getDay();
var hhmm = ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
var days = timeRangeEl.getAttribute('data-days');
var openTime = timeRangeEl.getAttribute('data-open');
var closeTime = timeRangeEl.getAttribute('data-close');
return days.indexOf(day) >= 0 && openTime <= hhmm && hhmm < closeTime;
}
function openClose() {
var date = new Date();
var display = document.getElementById('open-display');
var els = display.getElementsByClassName('timerange');
var anyActive = false;
for (var i = 0; i < els.length; i++) {
if (isOpen(els[i], date)) {
anyActive = true;
els[i].className = els[i].className.replace(/ *inactive\b/g, '');
} else if (els[i].className.indexOf('inactive') < 0) {
els[i].className += ' inactive';
}
}
if (anyActive) {
display.className = 'open';
} else {
display.className = 'closed';
}
}
setInterval(openClose, 5000);
openClose();
#open-display.open > .timerange.inactive,
#open-display.open > .timerange2.inactive,
#open-display.open .days {
display: none;
}
#open-display.open > .openclosed::before {
content: 'We are now Open';
}
#open-display.closed > .openclosed::before {
content: 'We are now Closed';
}
<div class="text">
<h3>Working Hours</h3>
<div id="open-display">
<div class="openclosed"></div>
<div class="timerange" data-days="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31" data-open="12:30" data-close="15:30"><span class="days">Noon</span> 12:30pm - 3:30pm</div>
<div class="timerange2" data-days="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31" data-open="18:00" data-close="00:30"><span class="days">Dine</span> 6:00pm - 12:30am</div>
</div>
</div>
Successfully done after trying and doing trial and error method.
I am trying to make a counter which starts at 0 and ends at 12 What I have right now is a counter that I can't cap. So basically, I am having trouble setting a max and min. Here is my code:
<div class="counter8">
<label id="blank"></label>
<div class="operations">
⇦
<span class="count8">0</span>
⇨
</div>
</div>
<script>
var add=document.querySelector(".inc");
var sub=document.querySelector(".dec");
let counter8=document.querySelector(".count8");
function inc_num8(){
var temp8=parseInt(counter8.innerText) >> 0;
counter8.innerText=temp8+1;
if (temp8 > 12) {
counter8.value = 12;
} else {
counter8.value = temp8;
}
}
function dec_num8(){
var temp8=parseInt(counter8.innerText) >> 0;
counter8.innerText=temp8-1;
}
</script>
The increase button was one of my attempt at making this work but failed.
You can use Math.max and Math.min to cap the values.
<div class="counter8">
<label id="blank"></label>
<div class="operations">
⇦
<span class="count8">0</span>
⇨
</div>
</div>
<script>
var add=document.querySelector(".inc");
var sub=document.querySelector(".dec");
let counter8=document.querySelector(".count8");
function inc_num8(){
var temp8=parseInt(counter8.innerText) >> 0;
counter8.innerText=Math.min(12,temp8+1);
}
function dec_num8(){
var temp8=parseInt(counter8.innerText) >> 0;
counter8.innerText=Math.max(0,temp8-1);
}
</script>
If you wanted to fix your code using if branching you could do:
if (temp8 >= 12) {
temp8 = 12;
} else {
temp8++;
}
counter8.innerText=temp8;
Or on one line: temp8 = temp8 >= 12 ? temp8 : temp8+1
For the minimum one just the flipped version
You didn't really limit min counter on your minus button. And also you only increment it after you check for condition.
So for you examples:
function inc_num8(){
var temp8=parseInt(counter8.innerText) >> 0;
if (temp8 >= 12) { // here changed to >=
counter8.innerText = 12; //also use innerText, not value
} else {
counter8.innerText=temp8+1;
}
}
function dec_num8(){
var temp8=parseInt(counter8.innerText) >> 0;
if(temp8 <= 0){ //here changed to <=
counter8.innerText = 0;
}else{
counter8.innerText=temp8-1;
}
}
I work with big quantity of data, and all data are not fering in screen, was decided to change data depends of time interval. When my page is load in array i received 18 items, which i put in to div's.
So i need show in page first 8 items, after 10 second, another 8 items, and in the end show 2 items (because i have only 18 items.).
So i create script which show one by one div's, but i need show 8 in 10 second
var current = 0;
setInterval(function () {
var divs = $(".cards").hide();
divs.eq(current).fadeIn("normal");
console.log(divs.eq(current))
if (current < divs.length - 1)
current++;
else
current = 0;
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="cards">1</div>
<div class="cards">2</div>
<div class="cards">3</div>
<div class="cards">4</div>
<div class="cards">5</div>
<div class="cards">6</div>
<div class="cards">7</div>
<div class="cards">8</div>
<div class="cards">9</div>
<div class="cards">10</div>
<div class="cards">11</div>
<div class="cards">12</div>
<div class="cards">13</div>
<div class="cards">14</div>
<div class="cards">15</div>
<div class="cards">16</div>
<div class="cards">17</div>
<div class="cards">18</div>
So how it's must works:
First 10 sec show div's from 1-8
After 10 sec show items from 9-16
And in the end show rest 2 div's
But for this exmple i have 18, but this data will be dynamicaly, and i dont know how many div's i will have
A solution:
var current = 0;
$(".cards").hide();
setInterval(function () {
var divs = $(".cards").hide();
var i = 0;
while (i < 8) {
divs.eq(current).fadeIn("normal");
console.log(divs.eq(current))
if (current < divs.length) {
i++;
current = current + 1;
} else {
i = 0;
current = 0;
}
}
}, 10000);
Solution was found:
script:
$(document).ready(function () {
var elements = $(".cards");
var index = 0;
var showNext = function (index) {
if (index >= elements.length) {
index = 0;
}
console.log(index);
elements.hide().slice(index, index + 8).show();
setTimeout(function () {
showNext(index + 8)
}, 10000);
}
showNext(0);
});
I'm trying to set up horizontal slider. I have div with overflow: hidden and inside I have 16 divs with height of 60px. Parent div has height so you can see only 4 childs at the time.
Now I want to change childs top: css to make them slide up and 4 new come from bottom.
Here's what I've done so far
lastAddedService.getLastAdded()
.then(function (response) {
$scope.lastAddedElements = response.data;
var i = 0, g = 0, c = 0, p = 0;
var k = 1, b = 1, h = 1;
var slider = {
step: 1,
positionTop: 0,
init: function (step) {
var that = this;
el[0].querySelectorAll('.a').forEach(function (element) {
if(step === 1) {
if(i < 16) {
that.positionTop = i * 60;
i++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 2) {
if(i < 4) {
that.positionTop = k * 60 * -1;
i++; k++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 4) {
k = 0;
that.positionTop = g * 60;
i++; g++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 3) {
if(i < 8) {
that.positionTop = b * 60 * -1;
i++; b++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 8) {
that.positionTop = c * 60;
i++; c++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 4) {
if(i < 12) {
that.positionTop = h * 60 * -1;
i++; h++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 12) {
that.positionTop = p * 60;
i++; p++;
return angular.element(element).css('top', that.positionTop);
}
}
});
},
changeSlide: function (step) {
this.step = step;
this.init(this.step);
}
};
$timeout(function () {
slider.changeSlide(1);
});
setTimeout(function () {
setInterval(function () {
var q = 1;
q++;
slider.changeSlide(q);
if(q === 4) {
q = 1;
}
}, 5000);
}, 5000);
}, function (err) {
console.log('error getting last added');
});
}
So I'm gathering records from backend and then there is this slider object which has logic which I explained above.
Backend call works fine, I did console response and it's 16 records which I display in layout layer later on. Question is mainly about the logic for this sliding object.
I'm using $timeout to start code work because this code is indeed in angularJS directive and NodeList which I get by querySelectorAll would be empty otherwise because it's evaluated after async backend call finish and then DOM is fully loaded. But it's not really relevant to real logic of this script, it's just additional info.
This code looks very bad to me. How I can improve it?
It's starting to update top after around 20 seconds and 1 div has 960px I don't know why.
It's not reseting this variables values so it doesn't loop but it increase top further and further.
I add HTML from my directive if anyone want to reproduce issue
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
<div class="row u-no-margin">
<div class="col-lg-11 col-xs-11">
<h2 class="main__heading">
Ostatnio dodane
</h2>
<div class="main__last-added-field">
<div class="main__last-added a" data-ng-repeat="n in lastAddedElements">
<div class="row u-no-margin main__last-added-container">
<div class="col-lg-3 col-md-2 col-sm-2 col-xs-2">
<h4 class="main__last-added-heading">
{{ n.data.attributes.price }}
</h4>
</div>
<div class="col-lg-7 col-xs-8 u-no-padding">
<h4 class="main__last-added-heading u-no-padding">
{{ n.data.attributes.name }}
</h4>
</div>
<div class="col-lg-2 col-xs-2">
<button type="button" class="btn btn__primary">
Zobacz
</button>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-1 col-xs-1">
<div class="main__last-added-dot-container">
<span class="main__last-added-dot main__last-added-dot--active"></span>
<span class="main__last-added-dot"></span>
<span class="main__last-added-dot"></span>
<span class="main__last-added-dot"></span>
</div>
</div>
</div>
</div>
JS code is within directive link: function and the templateUrl is above HTML code.
** EDIT **
I update question I add plunker showing issue and I explain one more, step by step what I want to accomplish.
Step1: all element has top: x css so they are align vertically. I'm using overflow: hidden on parent so you see only 4 and 12 are hidden below like this
Step2 I move first 4 element to top: -x so you don't see first 4 and element 5,6,7,8 take their place so elements 5,6,7,8 now slide to the top and first 4 are hidden.
step 3 same as Step2: elements 5,6,7,8 move to negative top and you now see elements 9,10,11,12
step 4 same as Step3: elements 9,10,11,12 move to negative top and you now see elements 13,14,15,16
here's demo
I don't know why but in plunker it doesn't udpate css top of elements at all.
First of all I recommend that you use a bootstrap only solution for your html/css view because its responsive, tested and you will have cleaner code.
I have made some modification to your slider logic in a way that the logic is the as if your slider were a pagination directive.
Basically, you divide your data into pages and then you keep track of the current page to be displayed on the view.
In your elements directive you use two filters on the data (startFrom, limitTo). The 'limitTo' is a built-in filter in Angular and 'startFrom' is a custom filter that you have to create.
<div class="" data-ng-repeat="n in elements | startFrom:currentPage*pageSize | limitTo:pageSize">
This is just an ideia that might help you refactor you code such that you won't need css positioning to determine which items will be displayed. Here is my demo:
https://plnkr.co/edit/IROsQWr5z4oYgZzmR2GF?p=preview
I hope this helps!
I've done it with this code:
<div class="main__last-added a"
data-ng-repeat="n in lastAddedElements"
data-order="{{ $index+1 }}">
(function () {
'use strict';
angular
.module('igt')
.directive('lastAdded', Directive);
Directive.$inject = ['$timeout', 'lastAddedService'];
function Directive($timeout, lastAddedService) {
return {
restrict: 'E',
scope: {
destiny: '='
},
templateUrl: 'html/directives/lastAdded.html',
link: function ($scope, el) {
lastAddedService.getLastAdded()
.then(function (response) {
$scope.lastAddedElements = response.data;
$scope.slider = {
increment: 0,
step: 1,
positionTop: 0,
init: function (step) {
var that = this;
var elements = el[0].querySelectorAll('.a');
if(step === 1) {
console.log('run step 1 ..............');
this.step = 1;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if(order <= 16) {
that.positionTop = order * 60 - 60;
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 2) {
console.log('run step 2 ..............');
this.step = 2;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 4) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 4) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 12) {
that.increment = 0;
console.log('reset inc in step 2');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 3) {
console.log('run step 3 ..............');
this.step = 3;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 8) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 8) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 8) {
that.increment = 0;
console.log('reset inc in step 3');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 4) {
console.log('run step 4 ..............');
this.step = 4;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 12) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 12) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 4) {
that.increment = 0;
console.log('reset inc in step 4');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
},
changeSlide: function (step) {
this.step = step;
this.init(this.step);
}
};
$timeout(function () {
var i = 1;
$scope.slider.changeSlide(i);
setInterval(function () {
i++; if(i === 5) i = 1;
$scope.slider.changeSlide(i);
}, 5000);
});
}, function (err) {
console.log('error getting last added: ' + err);
});
}
}
}
})();
But this code still look very lame although it's a bit better than first version. I feel like it can be done in much much simplier way.
i need to show number of list and loop the remain number when i click on see more appear 6 of list and slice the rest and back to slice when i click prev button ..
https://codepen.io/hesham-farag/pen/Ngadvj
<div class="comment-box-container">
<div class="comment-box">
<div class="user-comment-box">0</div>
<div class="user-comment-box">1</div>
<div class="user-comment-box">2</div>
<div class="user-comment-box">3</div>
<div class="user-comment-box">4</div>
<div class="user-comment-box">5</div>
<div class="user-comment-box">6</div>
<div class="user-comment-box">7</div>
<div class="user-comment-box">8</div>
<div class="user-comment-box">9</div>
<div class="user-comment-box">10</div>
<div class="user-comment-box">11</div>
<div class="user-comment-box">12</div>
<div class="user-comment-box">13</div>
<div class="user-comment-box">14</div>
<div class="user-comment-box">15</div>
<div class="user-comment-box">16</div>
<div class="user-comment-box">17</div>
<div class="user-comment-box">18</div>
<div class="user-comment-box">19</div>x">
<button class="see-more">See More...</button>
</div><!--comment-box end-->
</div><!-- comment-box-container end-->
.user-comment-box { display:none;
}
$(function(){
// select the first 5 hidden divs
$( ".comment-box" ).each(function( index ) {
$(this).children(".user-comment-box").slice(-5).show();
});
$(".see-more").click(function(e){ // click event for load more
e.preventDefault();
var done = $('<div class="see-more=done">done</div>');
$(this).siblings(".user-comment-box:hidden").slice(-5).show(); // select next 5 hidden divs and show them
if($(this).siblings(".user-comment-box:hidden").length == 0){ // check if any hidden divs
$(this).replaceWith(done); // if there are none left
}
});
});
Thanks!
Here's the working code:
$(function(){
// select the first 5 hidden divs
var count = 5;
var currentCount = 0;
$( ".comment-box" ).each(function( index ) {
$(this).children(".user-comment-box").slice(0,count).show();
currentCount = count;
});
$(".see-more").click(function(e){ // click event for load more
e.preventDefault();
$( ".comment-box" )children(".user-comment-box").slice(0,count).hide();
var done = $('<div class="see-more=done">done</div>');
$(this).siblings(".user-comment-box").hide();
$(this).siblings(".user-comment-box:hidden").slice(currentCount,currentCount + count).show(); // select next 5 hidden divs and show them
currentCount +=count;
if($(this).siblings(".user-comment-box").length == currentCount){ // check if any hidden divs
$(this).replaceWith(done); // if there are none left
}
});
});
i found the answer and put in this link for anyone search for
link
$(document).ready(function() {
var $pagination = $(".pagination");
var $lis = $pagination.find("li:not(#prev, #next)");
$lis.filter(":gt(3)").hide();
$lis.filter(":lt(5)").addClass("active");
var $next = $("#next").click(function() {
var idx = $lis.index($lis.filter(".active:last")) || 0;
var $toHighlight = $lis.slice(idx + 1, idx + 6);
$(".prev").show();
if ($toHighlight.length == 0) {
$prev.show();
return;
}
$next.show();
$lis.filter(".active").removeClass("active").hide();
$toHighlight.show().addClass("active");
});
var $prev = $("#prev").click(function() {
var idx = $lis.index($lis.filter(".active:first")) || 0;
var start = idx < 4 ? 0 : idx - 3;
var $toHighlight = $lis.slice(start, start + 5);
if ($toHighlight.length == 0) {
$prev.hide();
return;
}
$next.show();
$lis.filter(".active").removeClass("active").hide();
$toHighlight.show().addClass("active");
});
}); // close jquery