I want to add prev and next li's to my pagination function. The function itself works perfectly and shows the amount of pages by the amount of rows you want to view received from a dropdown .val();
function pagination() {
$('table[data-provide=pagination]').each(function () {
var $table = $('#foo');
var $pager = $('<ul></ul>');
var currentPage = 0;
var numPerPage = $("#bar").val();
var numRows = $table.find('.someclass').length;
var numPages = Math.ceil(numRows / numPerPage);
$table.unbind('repaginate');
$table.bind('repaginate', function () {
$table.find('.someclass').hide().slice(currentPage * numPerPage, (currentPage + 1) * numPerPage).show();
});
for (var page = 0; page < numPages; page++) {
var link = '' + page + '';
$('<li></li>').html(link).on('click', {
newPage: page
}, function (event) {
currentPage = event.data['newPage'];
$table.trigger('repaginate');
$(this).addClass('active').siblings().removeClass('active');
}).appendTo($pager);
};
var prev = '<li id="pagiprev">«</li>';
var next = '<li id="paginext">»</li>';
$pager.append(next);
$pager.prepend(prev);
$pager.find("li:first-child").addClass('active');
$($table.data('pager')).html($pager);
$table.trigger('repaginate');
});
};
Now Ive added:
var prev = '<li id="pagiprev">«</li>';
var next = '<li id="paginext">»</li>';
$pager.append(next);
$pager.prepend(prev);
But apparently it is not that easy as I thought. Of course making the next and prev li's work so it jumps to the next of prev page is step 1. It should also add or remove the 'active' class based on the last or first page as it does not make sense to be able to click on the prev button if you are on the first page.
Related
I got a no. of pages but I want to restrict it by showing 5 pages on load with next and previous buttons which shows pages number.
My code is:
<script>
$(document).ready(function() {
var totalRows = $('#MyTable').find('tbody tr:has(td)').length;
var recordPerPage = 10;
var totalPages = Math.ceil(totalRows / recordPerPage);
var $pages = $('<div id="pages"></div>');
var $previous = $('<span class="previous"><<</spnan>');
var $next = $('<span class="next">>></spnan>');
for (i = 0; i < totalPages; i++) {
$('<span>' + (i + 1) + '</span>').appendTo($pages);
}
$pages.appendTo('#MyTable');
$('#MyTable').find('tbody tr:has(td)').hide();
var tr = $('#MyTable tbody tr:has(td)');
for (var i = 0; i <= recordPerPage-1; i++) {
$(tr[i]).show();
}
$('span').click(function(event) {
$('#MyTable').find('tbody tr:has(td)').hide();
var nBegin = ($(this).text() - 1) * recordPerPage;
var nEnd = $(this).text() * recordPerPage - 1;
for (var i = nBegin; i <= nEnd; i++)
{
$(tr[i]).show();
}
});
});
</script>
I've made my pagination like:
"first previous 1 2 3 4 5 next last"
I hope you guys understand?
Thanks in advance.
Hi, You can create simple pagination using the TWBS pagination JS
library. here is a quick example of pagination on codepen it might
help you.
example code on codepen
https://codepen.io/SitePoint/pen/WprNwa/
My goal is to get each job link of a job site, go to each Job detail page by following Job link, download and save the detail in html through CASPERJS.
As id of each Job link change each time we back & forth between job link and job detail page, I need to get all the Job id each time under casper.repeat . But NoOfLink array is become empty outside of repeat function [I comment that part in code]. What is the problem?
var casper = require('casper').create();
var noOfRecordsToLoop = 0;
var TotalNoofNullElement = 0;
var NoOfLink = [];
var x = require('casper').selectXPath;
casper.echo('\nStart loding site......');
//---------------------------------------------Load and Scroll the site---------------------------------------//
casper.start('https://........../...../.......Careers/');
casper.wait(10000, function () {
//---------Total no of Job posting------//
var noOfRecords = this.fetchText(x('//*[#id="...........................jobProfile......"]'));
noOfRecordsToLoop = noOfRecords.replace(/[^0-9]/g, "");
var totalNoOfPage = Math.ceil(parseInt(noOfRecords) / 50);
casper.echo('\nStart scrolling site......');
casper.repeat(totalNoOfPage, function () {
this.scrollToBottom(); //-----------------------Scroll down
casper.wait(10000, function () {})
})
})
//------------------------------------------------Load and Scroll the site---------------------------------------//
casper.then(function () {
//-----------------------------------------Get all the link elements --------------------------//
var countForLink = 0;
var numTimesForRpt = noOfRecordsToLoop;
var numTimes = noOfRecordsToLoop;
casper.repeat(numTimesForRpt, function () {
RetElement = this.evaluate(function () {
var startingRow = '//*[contains(#id, "...-uid-")]'
var element = __utils__.getElementByXPath(startingRow).getAttribute('id');
return element;
});
var count = RetElement.replace(/[^0-9]/g, "");
casper.repeat(numTimes, function () {
var MatchElements = this.evaluate(function (count) {
var xp = '//*[contains(#id, "...-uid-' + count + '")]'
var element = __utils__.getElementByXPath(xp).getAttribute('id');
return element;
}, count++);
if (!MatchElements) {
TotalNoofNullElement = TotalNoofNullElement + 1
} else {
NoOfLink.push(MatchElements);
}
//**Here array elements are accessible**
for (var k = 0; k < NoOfLink.length; k++) {
this.echo(NoOfLink[k]);
}
});
//**But here array elements are not accessible outside of repeat** function
this.echo("Size of array is" + NoOfLink.length);
for (var q = 0; q < NoOfLink.length; q++) {
this.echo(NoOfLink[q]);
}
//-----------------------------------------Get all the link elements----------------------------//
//------------------------------------Go to the Job Detail Page Extract HTML and Save---------------------------//
this.echo("\n Inside repeat to Generate HTML");
var num = NoOfLink[countForLink];
this.echo("\nLink id is " + NoOfLink[countForLink]);
num = parseInt(num.replace(/[^0-9]/g, ""));
this.echo("\nNum is " + num);
//-----------------Click to go to the Job Detail Page------------------//
casper.thenClick(x('//*[#id="..-uid-' + num + '"]/div/div'));
casper.wait(5000, function getJobDetail() {
var content = this.getElementInfo(x(".//*[contains(#id,'......t-uid-')]")).html;
var divStart = '<div id="extrdHtml">'
var divEnd = '</div>'
var body = divStart + content + divEnd
this.echo("\nContent of Job detail :" + body);
var fs = require('fs');
fs.write('extractedJob' + NoOfLink[countForLink] + '.html', body, 'w');
this.echo("\nFile saved");
//------------------------------------Go to the Job Detail Page Extract HTML and Save---------------------------//
}); //casper.wait
casper.back();
casper.wait(5000);
countForLink++
}); //casper.repeat
}); //casper.then
//-------------------------------------------Get all the link elements------------------------------//
casper.run();
There are two repeat loops.
casper.repeat(numTimesForRpt, function () { - This is main outer loop , where the 2nd loop resides.
casper.repeat(numTimes, function () – Where I am getting the link and populating NoOfLink array. I am trying to get the array element value outside of this 2nd loop(within main outer loop) but it is not working.
All then* and wait* functions are asynchronous step functions. If you call them, you're scheduling a step that is executed at the end of the current step. casper.repeat() is a function that uses casper.then() and is therefore also asynchronous. Every synchronous code that comes after casper.repeat() will be executed before the contents of the repeat callback.
You have two options:
Wrap everything that comes after casper.repeat() in a casper.then() to make it asynchronous or
Use a normal synchronous loop instead of repeat, if the callback of repeat doesn't need to be evaluated asynchronously like in your case.
By the way, you can oftentimes reduce your code a bit by utilizing the helper functions that CasperJS provides. For example, you don't need to use evaluate() only to get the id attributes of some elements by XPath. You can do that with casper.getElementsAttribute().
Example:
var count = RetElement.replace(/[^0-9]/g, "");
for(var i = count; i < (numTimes + count); i++) {
var MatchElements = this.getElementsAttribute(x('//*[contains(#id, "...-uid-' + i + '")]'), 'id');
if (!MatchElements) {
TotalNoofNullElement = TotalNoofNullElement + 1
} else {
NoOfLink.push(MatchElements);
}
//**Here array elements are accessible**
for (var k = 0; k < NoOfLink.length; k++) {
this.echo(NoOfLink[k]);
}
}
previous and Next buttons don't have limitations, ie: can move before and after first and last pages... cant seem to limit this.
I've created if statements to try and stop the button from executing but it wont work. any ideas?
jsFiddle: https://jsfiddle.net/s7ac8aq3/
$(function() {
$(document).ready(function(){
//amount of items on page
var num = $('.post').length;
//set items per page
var itemsPerPage = 1;
var nav = false;
//array of all items
var items = $(".post");
//rounds up to the nearest whole number -- number of pages needed to display all results
var numOfPages = Math.ceil((num / itemsPerPage));
//container div
var paginationContainer = $("#pagination-container");
//initial link num
var linkNum = 1;
paginationContainer.prepend("<button class='pagination' id='btn-prev' value='prev'>Prev</button>");
//creates all pagination links as input buttons (can be anything... li, a, div, whatever)
for(i = 0; i < numOfPages; i++)
{
paginationContainer.append("<button class='pagination' id='btn-" + (i + 1) +"' " + "value='" + (i + 1) + "'>" + (i + 1) + "</button>");
}
paginationContainer.append("<button class='pagination' id='btn-next' value='next'>Next</button>");
//does the initial filtering of the items, hides anything greater than page 1
items.filter(":gt(" + (itemsPerPage -1) + ")").hide();
//finds the input feilds and executes onclick
paginationContainer.find('button').on('click', function(){
//REQUIRED RESETS NAV BOOL SO CLICKS WILL REGISTER
nav = false;
//stores the value of the link in this var
var val = $(this).val();
//if value is next or prev
if(val == "prev")
{
if(linkNum > 1)
{
nav = true;
linkNum = linkNum - 1;
var currentBtn = paginationContainer.find("#btn-" + linkNum);
var otherButtons = paginationContainer.find('button');
otherButtons.attr('class', "pagination");
currentBtn.attr('class', "current");
currentBtn.focus();
}
}
else if (val == "next")
{
if(linkNum < numOfPages)
{
nav = true;
linkNum = linkNum + 1;
var currentBtn = paginationContainer.find("#btn-" + linkNum);
var otherButtons = paginationContainer.find('button');
otherButtons.attr('class', "pagination");
currentBtn.attr('class', "current");
currentBtn.focus();
}
}
if(nav == false)
{
//reoves the current class from all buttons before reassigning
var otherButtons = paginationContainer.find('button');
linkNum = $(this).val();
otherButtons.attr('class', "pagination");
//assigns current class to current button
$(this).attr("class", "current");
}
//creates an array of items to hide based on if the set results are less than the link num
var itemsToHide = items.filter(":lt(" + ((linkNum-1) * itemsPerPage) + ")");
// adds any items that are greater than the set results from the link num to the hide array
$.merge(itemsToHide, items.filter(":gt(" + ((linkNum * itemsPerPage) -1) + ")"));
// hides the items in hide array
itemsToHide.hide();
//shows all items NOT in the hide array
var itemsToShow = items.not(itemsToHide);
itemsToShow.show();
});
});
});
A little debugging of your jsFiddle identified the problem. In this part of the code:
} else if (val == "next") {
if (linkNum < numOfPages) {
nav = true;
linkNum = linkNum + 1;
the value of linkNum is sometimes being stored as a string. As a result, adding "3"+1 produces "31" in JavaScript.
The trivial solution is to convert it to an integer before the addition:
linkNum = parseInt(linkNum,10) + 1; // always use a radix
https://jsfiddle.net/mblase75/s7ac8aq3/3/
However, I would instead prefer to solve the problem at its source, a few lines down:
if (nav == false) {
var otherButtons = paginationContainer.find('button');
linkNum = $(this).val();
When you store linkNum in the first place, .val() returns a string. Parse it as an integer right away:
linkNum = parseInt($(this).val(),10);
https://jsfiddle.net/mblase75/s7ac8aq3/4/
and then you don't have to change it before performing the addition.
Your problem in linkNum variable, when you click on certain page number, variable gets a string value, after that when you trying to add 1 you receive a new string, for example "3" + 1 => "31", "4" + 1 => "41"
I have a page with a menu of categories and subcategories of products.
Categories have a class 'category' and subcategories have a class 'subcategory'. When either is clicked some AJAX sends the category to some php to compile the html which the AJAX then sends back to the page to populate a div. This part works fine.
There is a function in the code to split the returned records. So say there are 6 records and the page is to show 2 at a time then there are 3 pages. I get the correct amount of pages displayed(1 2 3) but all 6 records displayed on each!
Can anyone see the problem?
$('a.category, a.subcategory').click(function (e) {
// first stop the link to go anywhere
e.preventDefault();
// get the class of the link
var linkClass = $(this).attr("class");
//get the text of the link by converting the clicked object to string
var linkText = new String(this);
// the value after the last / is the category ID
var categoryValue = linkText.substring(linkText.lastIndexOf('/') + 1);
// put the post parameters into 'params' to pass through the AJAX post request
var params = {};
params[linkClass] = categoryValue;
// send the category ID to the getProductData.php script using jquery ajax post method
// send along a category ID
// on success insert the returned text into the chosen div
$.post('../inc/showproducts.php', params, function (data) {
//find total number of records
var totalRecords = $(data).length;
//define how many records shown per page
var pageSize = 2
//work out number of pages needed to hold records
var numOfPages = Math.ceil(totalRecords / pageSize);
//make page links
var i,
pageLinks = '<div class="pageLinks">';
for (i = 0; i < numOfPages; i++) {
pageLinks += '<a href="#" onclick="showProductPage(' + i + ');return false;">' + (i + 1) + '<\/a> ';
}
pageLinks += '<\/div>';
//display returned data and page links in chosen div (.showproduct)
$('.showproduct').html(pageLinks + data);
showProductPage(0);
});
});
//function to slice up records into pages
function showProductPage(pageNo) {
var perPage = 2;
var start = pageNo * perPage;
var end = start + perPage;
$('.image').hide().filter(function (index) {
return ((index > (start - 1)) && (index < end));
}).show();
}
//check out this line of your code
$('.showproduct').html(pageLinks + data);
The data var has all the records in it still. You have to get each data[position] with a for loop that iterates based on pageSize * pageNum. So page 1 would look like
var iterationSize = pageSize * pageNum; //(2 * 1 = 2)
var i;
var j = 0;
var pageData[];
for(i = pageNum - 1; i < iterationSize; i++, j++){
pageData[j] = data[i];
}
$('.showproduct').html(pageLinks + pageData.join(''));
EDIT: This question is apparently related to the jQuery Carousel Evolution plugin's UI.
How would I change the title and description on next and previous button?
Also, when i load the page and when carousal will display that time 1st title and description should display bydefault. Please solve my problem. I am shared the link also , please see below
$(document).ready(function () {});
var playListURL = 'http://gdata.youtube.com/feeds/api/playlists/0155DF7A9B0DF819?v=2&alt=json&callback=?';
var videoURL = 'http://www.youtube.com/watch?v=';
$.getJSON(playListURL, function (data) {
var list_data = "";
$.each(data.feed.entry, function (i, item) {
var feedTitle = item.title.$t;
var feedescription = item.media$group.media$description.$t;
var feedURL = item.link[1].href;
var fragments = feedURL.split("/");
var videoID = fragments[fragments.length - 2];
var url = videoURL + videoID;
var thumb = "http://img.youtube.com/vi/" + videoID + "/hqdefault.jpg";
list_data += '<div><a href= "#" ><img src="' + thumb + '" width="213px" height="141px"/></a></div>';
});
$(list_data).appendTo(".slides");
$('.carousel').carousel({
carouselWidth: 930,
carouselHeight: 330,
directionNav: true,
shadow: true,
buttonNav: 'bullets'
});
var cnt = 0;
$(".nextButton").click(function () {
var len = $(this).siblings(".slides").children(".slideItem").length;
var a = cnt++;
});
$(".prevButton").click(function () {
var len = $(this).siblings(".slides").children(".slideItem").length;
var a = cnt++;
});
});
Demo Link :- http://jsfiddle.net/4HSpH/4
Thanx in Advance ...
For question 1, you can use jQuery to add your title attributes after carousel initialization. The plugin you've selected doesn't seem to have a very robust API for that sort of thing.
http://jsfiddle.net/4HSpH/6
$('.prevButton').attr('title', 'My previous button');
$('.nextButton').attr('title', 'My next button');
To get your title to populate on load, try this after the code above:
$("#title").text($items.filter(function () {
return $(this).css("top") == "0px";
}).find("a").attr("title"));