Have the following script:
var CurrentPageTop = 0;
var PageHeight = 496;
var TotalPages = 9;
var CurrenPage = 1;
function Slide( control, panel ){
if ( control.name == "SlideDown" ){
if ( (CurrenPage >= 1) && (CurrenPage <= TotalPages-1) ){
CurrenPage++;
CurrentPageTop = ( CurrentPageTop - PageHeight );
}
}
if ( control.name == "SlideUp" ){
if ( (CurrenPage > 1) && (CurrenPage <= TotalPages) ){
CurrenPage--;
CurrentPageTop = (CurrentPageTop + PageHeight);
}
}
var PanelScroller = document.getElementById(panel);
PanelScroller.style.top = CurrentPageTop + 'px';
var CurrenPageId = document.getElementById("CurrenPageId");
CurrenPageId.innerHTML = "Page " + CurrenPage + " of 9";
}
which accompanies a single image gallery on a page:
<table cellpadding="0" cellspacing="0">
<tr>
<td>
<div class="SlidingPanel">
<div id="PanelScroller">
<div class="Page">
<img src="i/gal/g1.jpg">
</div>
How would I set this up to have multiple instances on one page?
Some galleries have 9 images, some have 6, etc.
Is there a way to count the number of <div class="Page"> within a <div id="PanelScroller"> ?
I want to avoid having to use 3 slightly different instances of this script for 3 different galleries. I just can't wrap my head around it because I'm a novice.
function number_of_elements_with_class_name(class_name) {
var elements = getElementsByClassName(class_name);
var count = 0;
for(var i in elements) {
count++;
}
return count;
}
node.getElementsByClassName()
http://www.quirksmode.org/blog/archives/2008/05/getelementsbycl.html
Related
I'm trying to add some pagination numbers in Javascript. I already achieved the pagination, I also can show all the pagination numbers but I would like to show only three numbers from all the numbers. Let my show you what I achieved until now:
var values = [{name : "a"}, {name : "b"}, {name : "c"}, {name : "d"}, {name : "e"}, {name : "f"}, {name : "g"}, {name : "h"}, {name : "i"}, {name : "j"}];
var current_page = 1;
var records_per_page = 6;
if (values.length <= 6) {
btn_prev.style.display = "none";
btn_next.style.display = "none";
}
function prevPage() {
if (current_page > 1) {
current_page--;
changePage(current_page);
}
}
function nextPage() {
if (current_page < numPages()) {
current_page++;
changePage(current_page);
}
}
function changePage(page) {
var btn_next = document.getElementById("btn_next");
var btn_prev = document.getElementById("btn_prev");
var listing_table = document.getElementById("poi-cat-id");
var page_span = document.getElementById("page");
var pageNum = document.getElementById("pageNum");
// Validate page
if (page < 1) page = 1;
if (page > numPages()) page = numPages();
listing_table.innerHTML = "";
var href = getRootWebSitePath();
for (var i = (page - 1) * records_per_page; i < (page * records_per_page) && i < values.length; i++) {
var nametoslug1 = values[i].name;
var slug1 = convertToSlug(nametoslug1);
listing_table.innerHTML += '<div class="event-desc"><p>' + values[i].name + '</p></div>';
}
if (page == 1) {
btn_prev.style.color = "#404141";
} else {
btn_prev.style.visibility = "visible";
btn_prev.style.color = "#0c518a";
}
if (page == numPages()) {
btn_next.style.color = "#404141";
} else {
btn_next.style.visibility = "visible";
btn_next.style.color = "#0c518a";
}
male();
maen();
}
//this is where I add all the numbers of the pagination
var totnum = numPages();
for (var i = 0; i < numPages() + 2; i++) {
// We do not want page 0. You could have started with i = 1 too.
$('#page-num-container').append('' + (i + 1) + '');
}
======EDIT=====
function newPage(){
$('.pageClick').on('click', function (e) {
e.preventDefault();
changePage($(this).index() + 1);
});
} //when I click the number the pages won't change
function numPages() {
return Math.ceil(values.length / records_per_page);
}
window.onload = function () {
changePage(1);
};
and this is my html :
<div>
<ul class="content-full" id="poi-cat-id"></ul>
<div class="pagination-poi-arrows">
<div class="prev">
<img src="~/img/left-arrow-pagination.svg" />
</div>
<div class="page-num-container" id="page-num-container">
</div>
<div class="nex">
<img src="~/img/right-arrow-pagination.svg" />
</div>
</div>
<div class="pagination-poi-arrows" id="pager"></div>
</div>
Can anybody help would be highly appreciated since I've been stuck with this for a while.
If you want to show the adjacent page numbers, then you have to start iterating at i=current_page until i=current_page + 2.
However, it seems that in your code, you start counting at 1 with your pages. I advise you to start at 0.
Now, back to your code. You need to replace the loop with the following (if you're counting from 1):
function updatePagination(page) {
for (var i = page - 1; i < page + 1; i++) {
$('#page-num-container').append('<a href="javascript:pagesNr()"
class="pageClick">' + (i + 1) + '</a>');
}
}
// you need to clear the element before you update it
function clearPagination() {
$('#page-num-container').empty();
}
You would call both of these methods at the end of the changePage() method.
I need a method that, taken as parameters two nodes (node1 and node2), returns the minimum path that leads to node2 from node1.
Ideally, it returns an array of nodes, but for the moment it's OK to a string. So for example:
P
/ \
#text U
/ \
B I
| |
#text #text
function foo(node1, node2) {
...
}
when I run it in this way, for example on the nodes P (root) and B:
var res = foo(P, B);
console.log(res);
I obtain:
res = Array[3] {
0: P (class=..., id=...)
1: U (class=..., id=...)
2: B (class=..., id=...)
}
or, in the form of string:
res = "P(class=..., id=...) > U(class=..., id=...) > B(class=..., id=...)";
If the nodes have attributes (such as id or class), then returns even those (as in the example).
I searched the internet methods that did similar things but I found only methods that return the full path of the entire document and not between two nodes.
For example, I tried this method doesn't work for me because it returns the full path of a single node.
function getDomPath(el) {
var stack = [];
while ( el.parentNode != null ) {
console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
if ( el.hasAttribute('id') && el.id != '' ) {
stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
} else if ( sibCount > 1 ) {
stack.unshift(el.nodeName.toLowerCase() + ':eq(' + sibIndex + ')');
} else {
stack.unshift(el.nodeName.toLowerCase());
}
el = el.parentNode;
}
return stack.slice(1); // removes the html element
}
Another thing, I would use pure JavaScript, no jQuery.
I have no idea how to do what I need, a your help would be greatly appreciated.
Thank you
<!DOCTYPE html>
<html>
<script>
window.onload = function() {
console.log(min_path(
document.getElementById("4"),
document.getElementById("9")
));
};
function min_path(node1, node2) {
if(node1 === node2) {
return node1;
}
var node_1_ancestors = get_ancestors(node1);
var node_2_ancestors = get_ancestors(node2);
var divergent_index = 0;
while(node_1_ancestors[divergent_index] === node_2_ancestors[divergent_index]) {
divergent_index++;
}
var path = [];
for(var i = node_1_ancestors.length - 1; i >= divergent_index - 1; i--) {
path.push(node_1_ancestors[i]);
}
for(var i = divergent_index; i < node_2_ancestors.length; i++) {
path.push(node_2_ancestors[i]);
}
return path;
}
function get_ancestors(node) {
var ancestors = [node];
while(ancestors[0] !== null) {
ancestors.unshift(ancestors[0].parentElement);
}
return ancestors;
}
</script>
</head>
<body>
<div id="0">
<div id="1">
<div id="2">
<span id="3"></span>
<span id="4">node1</span>
</div>
<div id="5">
<p id="6"></p>
<span id="7">
<div id="8">
<div id="9">node2</div>
<div id="10"></div>
</div>
</span>
</div>
</div>
<div id="11"></div>
</div>
</body>
</html>
Edit: It was going in to an infinite loop when the nodes were equal, so I added a check for that.
I have created a carousel in javascript to show multiple contents either by using page scroll or by clicking a button. I have used viewpager.js for this purpose. I have added a pagination at the bottom which works fine when the buttons are clicked. I am unable to figure out how to link it to the page scroll. Any help is appreciated. My code:
HTML
<div id='prev'>
<button id="btn-prev"><img src='img/orange-towards-left.png'></button>
</div>
<div class='pager'>
<div class='pager_items' id='info'>
</div>
</div>
<div id='next'>
<button id="btn-next"><img src='img/orange-towards-right.png'></button>
</div>
<div id='pagination'>
<ul></ul>
</div>
JS
item_container = document.querySelector('.pager_items');
view_pager_elem = document.querySelector('.pager');
w = view_pager_elem.getBoundingClientRect().width;
items = payerAccArr.length;
item_container.style.width = (items * 100)+ '%';
var child_width = (100 / items) + '%';
var html = "";
document.getElementById('monthInfo').innerHTML=payerAccArr[0].DateKey + " Bill Amount ";
for (var i = 0; i < items; i++) {
html += "<div class=toggle><h4>Payer Account Name</h4> <ul> <li>" + payerAccArr[i].PayerAccountName +
"</li></ul> _______________ <ul><li> "+(payerAccArr[i].TotalAmount).toFixed(2) +
" USD</li> </ul></div>";
}
item_container.innerHTML = html;
for(var i=0;i<items;i++)
item_container.children[i].style.width = child_width;
var htmlStr='<li class="current"></li>';
for(var i=0;i<items-1;i++){
htmlStr += '<li></li>';
}
$('#pagination ul').html(htmlStr);
vp = new ViewPager(view_pager_elem, {
pages: item_container.children.length,
vertical: false,
onPageScroll : function (scrollInfo) {
offset = -scrollInfo.totalOffset;
invalidateScroll();
},
onPageChange : function (page) {
document.getElementById('monthInfo').innerHTML=payerAccArr[page].DateKey + " Bill Amount ";
}
});
window.addEventListener('resize', function () {
w = view_pager_elem.getBoundingClientRect().width;
invalidateScroll();
});
document.getElementById('btn-prev').addEventListener('click', function (){
vp.previous();
if(index>0){
createDoughnutChart(index--);
}
var li = jQuery("li.current");
if (li.length){
var $prev = li.prev();
if($prev.length == 0)
$prev = $("#pagination li").last().addClass("current");
li.removeClass("current");
$prev.addClass("current");
}
});
Similar code for the next button also has been written.
This issue got solved. I made a change to the onPageChange function by adding the following code. I am now able to link it to both the page scroll and the buttons.
JS:
onPageChange : function (page) {
document.getElementById('monthInfo').innerHTML=payerAccArr[page].DateKey + " Bill Amount ";
// console.log('page', page);
var li = $("li.current");
var curIndex = li.index();
if(li.length){
var $prev = li.prev();
var $next = li.next();
if(page == $prev.index()){
li.removeClass("current");
$prev.addClass("current");
}
if(page==$next.index()){
li.removeClass("current");
$next.addClass("current");
}
}
}
Fiddle - http://liveweave.com/enRy3c
Here's what I'm trying to do.
Say my input number is 5. I want to dynamically append 5 divs to the class .enfants. However I haven't figured out how to do that. I been searching and searching and I haven't came across anything.
jQuery/JavaScript:
var counter = 1;
// Value number = .enfants children
$(".ajouter-enfants").on('keyup change', function() {
var yourChildren = "<div>" + counter++ + "</div>";
var CallAppend = function() {
$(".enfants").append( yourChildren );
};
// If 0 or empty clear container
if ( $.inArray($(this).val(), ["0", "", " "]) > -1 ) {
$(".enfants").html("");
// If only add/have 1 div in container
} else if ($(this).val() === "1") {
$(".enfants").html("").append( yourChildren );
// If > 0 add as many divs as value says
} else {
$(".enfants").html("");
CallAppend();
}
});
HTML:
<div class="contenu" align="center">
<div>
Value number = .enfants children
</div>
<input type="number" min="0" class="ajouter-enfants" value="0" />
<div class="enfants">
</div>
</div>
How about a simple loop? If you just want to append, try something like this:
$(".ajouter-enfants").on('change', function() {
var numDivs = $(this).val();
var i;
for (i = 1; i <= numDivs; i += 1) {
$('.enfants').append('<div>' + i + '</div>');
}
});
EDIT:
If you want to replace instead of append the newly-created <div>'s, try something like:
$(".ajouter-enfants").on('keyup change', function() {
var content = '';
var numDivs = $(this).val();
var i;
for (i = 1; i <= numDivs; i += 1) {
content += '<div>' + i + '</div>';
}
$('.enfants').html(content);
});
This will replace the entire content of any elements using the class ajouter-enfants with the number of <div>'s specified in the input box.
Try this:
$(".ajouter-enfants").on('keyup change', function() {
var num = +$.trim($(this).val()), target = $(".enfants"), i = 0, s = '';
target.empty();
if (!isNaN(num) && num > 0) {
for (; i < num; i++) {
s += '<div>' + (i + 1) + '</div>';
}
target.html(s);
}
});
How would you get it to only append the value amount? It appends more when the value is (2 becomes 3, 3 becomes 6, 4 becomes 10 and repeats even when I'm decreasing the numeric value) –
#Michael Schwartz
Here is another code example that might be helpfull.
$(".ajouter-enfants").on('change', function() {
var numDivs = $(this).val();
var i;
var html ='';
for (i = 1; i <= numDivs; i += 1) {
html += '<div>' + i + '</div>';
}
$('.enfants').empty().append(html);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="contenu" align="center">
<div>
Value number = .enfants children
</div>
<input type="number" min="0" class="ajouter-enfants" value="0" />
<div class="enfants">
</div>
</div>
I have some divs in the page that show different things of the same kind, for example offers, now offers have ending time, and also posted time, if the user wants to order by ending time, or posted time, they should be re ordered.
I'm looking for a javascript solution that could do that, any particular libraries under Ext JS , or JQuery would work
Here is how these divs look like
<div data-sortunit="1" data-sort1="40" data-sort2="156" data-sort3="1"
data-sort4="1317620220" class="item">
</div>
<div data-sortunit="2" data-sort1="30" data-sort2="116" data-sort3="5"
data-sort4="1317620220" class="item">
</div>
<div data-sortunit="3" data-sort1="10" data-sort2="157" data-sort3="2"
data-sort4="1317620220" class="item">
</div>
So I wanna be able to sort these divs based on data-sortN, N being an integer
Edit: OK, now that you've supplied some HTML, here's javascript code that will sort that specific HTML by the desired column number:
function sortByDataItem(containerID, dataNum) {
var values = [];
$("#" + containerID + " .item").each(function(index) {
var item = {};
item.index = index;
item.obj = this;
item.value = $(this).data("sort" + dataNum);
values.push(item);
});
values.sort(function(a, b) {return(b.value - a.value);});
var container = $("#" + containerID);
for (var i = 0; i < values.length; i++) {
var self = $(values[i].obj);
self.detach();
container.prepend(self);
}
return;
}
$("#sort").click(function() {
var sortValue = $("#sortColumn").val();
if (sortValue) {
sortValue = parseInt(sortValue, 10);
if (sortValue && sortValue > 0 && sortValue <= 3) {
sortByDataItem("container", sortValue);
return;
}
}
$("#msg").show(1).delay(5000).fadeOut('slow');
});
You can see it work here in a jsFiddle: http://jsfiddle.net/jfriend00/JG32X/
Since you've given us no HTML to go on, I've made my own HTML and shown you how you can use jQuery to sort:
HTML:
<button id="sort">Sort</button><br>
<div id="productList">
<div class="row"><div class="productName">Popcorn</div><div class="price">$5.00</div></div>
<div class="row"><div class="productName">Peanuts</div><div class="price">$4.00</div></div>
<div class="row"><div class="productName">Cookie</div><div class="price">$3.00</div></div>
<div class="row"><div class="productName">Beer</div><div class="price">$5.50</div></div>
<div class="row"><div class="productName">Soda</div><div class="price">$4.50</div></div>
</div>
Javascript (run after page is loaded):
$("#sort").click(function() {
var prices = [];
// find all prices
$("#productList .price").each(function(index) {
var str = $(this).text();
var item = {};
var matches = str.match(/\d+\.\d+/);
if (matches && matches.length > 0) {
// parse price and add it to the prices array
item.price = parseFloat(matches[0]);
item.row = $(this).closest(".row").get(0);
item.index = index;
prices.push(item);
}
});
// now the prices array has all the prices in it
// sort it using a custom sort function
prices.sort(function(a, b) {
return(a.price - b.price);
});
// now pull each row out and put it at the beginning
// starting from the end of the prices list
var productList = $("#productList");
for (var i = prices.length - 1; i >= 0; i--) {
var self = $(prices[i].row);
self.detach();
productList.prepend(self);
}
});
And, a jsFiddle that shows it in action: http://jsfiddle.net/jfriend00/vRdrA/.
I made a tiny jqueryPlugin out of jfriend00's answer:
(function($){
$.fn.sortChildrenByDataKey = function(key, desc){
var i, els = this.children().sort(function(a, b) {return (desc?1:-1)*($(a).data(key) - $(b).data(key));});
for (i = 0; i < els.length; i++) {
this.prepend($(els[i]).detach());
}
return this;
};
})(jQuery);
Your HTML:
<div id="myContainer">
<div data-myKey="4"> ... </div>
<div data-myKey="2"> ... </div>
...
</div>
Usage:
$('div#myContainer').sortChildrenByDataKey('myKey', true_or_false);
The children of the container can be any Elements. Its only important, that they are immediate children and have data-X key.
Thank you, jfriend00!!