PDA

View Full Version : Lightbox no longer works after jQuery pagination is triggered



flash_noob
07-08-2011, 04:57 AM
We are using two scripts at the same time: prettyPhoto and jQuery pagination. When the page first loads, both of the scripts are working. However, when I click on Page 2 of the pagination, the lightbox no longer shows but I can still go from one page to the next. These are the initialization scripts for both:

jQuery Pagination:


<script type="text/javascript">

// This is a very simple demo that shows how a range of elements can
// be paginated.
// The elements that will be displayed are in a hidden DIV and are
// cloned for display. The elements are static, there are no Ajax
// calls involved.

/**
* Callback function that displays the content.
*
* Gets called every time the user clicks on a pagination link.
*
* @param {int} page_index New Page index
* @param {jQuery} jq the container with the pagination links as a jQuery object
*/
function pageselectCallback(page_index, jq){
var new_content = jQuery('#hiddenresult div.result:eq('+page_index+')').clone();
$('#Searchresult').empty().append(new_content);
return false;
}

/**
* Initialisation function for pagination
*/
function initPagination() {
// count entries inside the hidden content
var num_entries = jQuery('#hiddenresult div.result').length;
// Create content inside pagination element
$("#Pagination").pagination(num_entries, {
callback: pageselectCallback,
items_per_page:1 // Show only one item per page
});
}

// When document is ready, initialize pagination
$(document).ready(function(){
initPagination();
});
</script>

prettyPhoto:


<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$("a[rel^='prettyPhoto']").prettyPhoto();
});
</script>

Anyone knows where the conflict lies? Thanks.

jscheuer1
07-08-2011, 06:07 AM
It's not a conflict. Pretty Photo was initialized on the document when it was ready. Later, using the pagination script the document is changed. The initialized elements no longer exist, new ones that are qualified are perhaps introduced, but they aren't initialized by Pretty Photo, so would act as ordinary links.

This depends to a degree upon how robust Pretty Photo is. But if it's as robust as most jQuery based Lightbox type scripts, you could probably use the pageselectCallback function to initialize the new content, additions highlighted:


/**
* Callback function that displays the content.
*
* Gets called every time the user clicks on a pagination link.
*
* @param {int} page_index New Page index
* @param {jQuery} jq the container with the pagination links as a jQuery object
*/
function pageselectCallback(page_index, jq){
var new_content = jQuery('#hiddenresult div.result:eq('+page_index+')').clone();
$('#Searchresult').empty().append(new_content);
$("a[rel^='prettyPhoto']").prettyPhoto();
return false;
}

flash_noob
07-08-2011, 06:38 AM
It worked and your explanation makes sense. Thanks a lot!

Amok
06-28-2013, 12:07 PM
I have similar problem and want to ask if this solve a problem with numbering of images in PrettyPhoto popup window. Now i use the same libraries (prettyPhoto, jquery_pagination ) to show thumbnails on few pages with 6 images on each. And when i click on page 2 (for example) and open first image in prettyPhoto popup numbering of images starts from 1 instead of 7.
Here is a simple screenshot.
51195120
It seems the re initializing of prettyphoto reset counter and i don't know how to fix this :confused:
Thanks in advance.

jscheuer1
06-28-2013, 02:51 PM
From what information you supply I can see that you are using the feature of PrettyPhoto that allows for a group of images to be seen. The original question only asked if individual images could be shown. If you want to preserve the original order of the images, you have to copy them in that order and use those, not the ones that show in the pagination 'pages'. The ones in the 'pages' must be able to trigger the ones in the original order though.

So you would do something like, on document ready copy (clone) all the links in the group to a hidden div at the beginning of the page, remove the rel from the links in the 'pages' and replace it with a class. Then initialize the hidden links to PrettyPhoto. Then add a live() or on() event (which depends upon the version of jQuery you're using) to the document, something like (requires jQuery 1.7 or later):


jQuery(function($){
var $origorder = $('<div></div>').css({visibility: 'hidden', position: 'absolute', top: -10000, left: -10000}).prependTo('body'),
$ppas = $("a[rel^='prettyPhoto']");
$ppas.each(function(i, a){
var $ppa = $ppas[i];
$ppa.clone(true).appendTo($origorder);
a.removeAttribute('rel');
$ppa.addClass('prettyphotoproxy');
});
$ppas = $("a[rel^='prettyPhoto']");
$ppas.prettyPhoto();
$(document).on('click', '.prettyphotoproxy', function(e){
var href = this.href;
$ppas.each(function(i, a){
if(a.href === href){
$ppas[i].trigger('click');
e.preventDefault();
return false;
}
});
});
});



Since I cannot know what your setup is like, I would have to make my own demo up from scratch and hope that it was close enough to what you're doing to work for it and to even just to test my code for syntax, basic workability. That's a waste of my time. If I could see your page, I could use developer tools to determine a good way to copy the links and activate them as I describe. What I just wrote in the above code block might work 'as is' though, so try it. And get rid of the highlighted line in the callback:


/**
* Callback function that displays the content.
*
* Gets called every time the user clicks on a pagination link.
*
* @param {int} page_index New Page index
* @param {jQuery} jq the container with the pagination links as a jQuery object
*/
function pageselectCallback(page_index, jq){
var new_content = jQuery('#hiddenresult div.result:eq('+page_index+')').clone();
$('#Searchresult').empty().append(new_content);
$("a[rel^='prettyPhoto']").prettyPhoto();
return false;
}



The browser cache may need to be cleared and/or the page refreshed to see changes.

If you want more help, please include a link to the page on your site that contains the problematic code so we can check it out.

Amok
07-02-2013, 06:46 AM
Thanks for the quick answer and your help. I will try to use your fix (it will take some time because i'm newbie in javascript:) ) but i got the idea. Here is my page where i'm trying to set up 4 galleries with pagination: http://mal.comule.com/lt/gallery.php
I know the initPagination and callbacks can be made better, but i'm still learning.
Thanks again - i will try now to fix order of images.

edit:
Now i realized that the numbering is not the only problem :( When i'm on page 2 and open last image, the NEXT button open first image of page 1, instead of first image on page 3. It seems i can't use this pagination with gallery and must manage it with php somehow :( Thanks again for reply and sorry for wasting your time!

jscheuer1
07-02-2013, 07:55 AM
If you want only the items on a given 'page' to be in a group, all you need to do is:


function pageselectCallback1(page_index, jq){
var new_content1 = $("#hiddenresult1 a.result").slice(page_index * ITEMS_PER_PAGE, (page_index + 1) * ITEMS_PER_PAGE).clone();
$("#Searchresult1").html(new_content1);
$("#Searchresult1 a[rel^='prettyPhoto']").prettyPhoto({social_tools:false, slideshow:4000});
return false;
}
function pageselectCallback2(page_index, jq){
var new_content2 = $("#hiddenresult2 a.result").slice(page_index * ITEMS_PER_PAGE, (page_index + 1) * ITEMS_PER_PAGE).clone();
$("#Searchresult2").html(new_content2);
$("#Searchresult2 a[rel^='prettyPhoto']").prettyPhoto({social_tools:false, slideshow:4000});
return false;
}
function pageselectCallback3(page_index, jq){
var new_content3 = $("#hiddenresult3 a.result").slice(page_index * ITEMS_PER_PAGE, (page_index + 1) * ITEMS_PER_PAGE).clone();
$("#Searchresult3").html(new_content3);
$("#Searchresult3 a[rel^='prettyPhoto']").prettyPhoto({social_tools:false, slideshow:4000});
return false;
}
function pageselectCallback4(page_index, jq){
var new_content4 = $("#hiddenresult4 a.result").slice(page_index * ITEMS_PER_PAGE, (page_index + 1) * ITEMS_PER_PAGE).clone();
$("#Searchresult4").html(new_content4);
$("#Searchresult4 a[rel^='prettyPhoto']").prettyPhoto({social_tools:false, slideshow:4000});
return false;
}



The browser cache may need to be cleared and/or the page refreshed to see changes.

jscheuer1
07-03-2013, 05:18 AM
I think you might like this version (right click and 'Save As'):

5126

Amok
07-04-2013, 08:27 AM
WOW, this is amazing :) Just what i wanted to make. Thank you very much!

jscheuer1
07-04-2013, 09:04 AM
Great! I have a slightly more streamlined version which adds a cookie to keep track of which page the visitor is on in each gallery:

5127

I made one modification you might want to reverse. I used the Google hosted version of jQuery:


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>


Since your server is probably not very close to the Google server, going back to your hosted copy:


<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>


might be a good idea. However, if your target audience might be closer to the Google servers, using the Google hosted version might be a good thing. And it may already be cached by many of your visitors, which would cut down a little on load time.

About load time. It might be a good idea to figure out a way to not have the thumbnail images load until they're made visible. I'll have a look at that. And, since they're only thumbnails, consider cutting down on their byte load by optimizing them. That will also speed loading of the page. And some of the larger images are so large they take over the screen and more when expanded, they don't really need to be that large.

Amok
07-05-2013, 09:11 AM
Thanks for this new version. I'm working now on php script + jQuery plugin (imgAreaSelect) and all images will be resized on upload so they will become smaller. Definitely it is good idea thumbnails to be loaded when are displayed - i will try to manage this. Because i work on my local computer and the speed of loading is not a problem yet :) i will test how long it takes to load everything. Probably Google servers are far away from common visitor's ISP, but trying to use cached jQuery from Google is also good idea. I have much work to do on this project, but your help was invaluable and i learned many new things. Thanks!

jscheuer1
07-05-2013, 10:31 AM
OK, here's the latest version, probably my last unless you have a request or there's some problem with it:

5131

I worked out a fairly simple way to only load the thumbnails when they're made visible. It involves adding a little code to the pageselectCallback function:


function pageselectCallback(page_index, jq){
jq.prevAll('div[id^="Searchresult"]:last').empty().append(
jq.next('div').find("a.result").slice(page_index * this.items_per_page, (page_index + 1) * this.items_per_page).clone()
).find('img').each(function(i, im){im.src = $(im).data('src');});
pageobj[jq.attr('id')] = page_index;
window.opera && setcookieobj(cookiename, pageobj);
return false;
}



adding this style (from the updated on page stylesheet):


.portfolio_item img, .portfolio_item:hover img {
display: inline-block;
background: white url(images/prettyPhoto/default/loader.gif) center no-repeat;
}



and rewriting the hard coded images to, for example:


<img src='images/transparent.gif' data-src='./images/gallery/1/thumb_1291736206_4.jpg' />

That requires a small 1px by 1px transparent GIF image (right click and 'Save As'):

http://home.comcast.net/~jscheuer1/side/transparent.gif

Put it in the images folder. While the image is loading, the loading image from PrettPhoto will show in its place.

I also found a way to format the title/description in the PrettyPhoto Box a little better so that, in smaller browser windows, it doesn't get squeezed in with the navigation/close and counter elements. You can see how that's done in the updated on page style section.

Just to see, I downloaded the thumbnails and optimized them using optimizer pro's batch mode to 72% quality, 50% "magic compression", a proprietary method that automatically identifies areas of less detail in an image and applies greater compression to those areas. The thumbnail images, which were averaging about 20K or more then averaged 4K with little perceptible loss in quality.

Amok
07-10-2013, 12:02 PM
Everything is perfect :) The gallery, navigation, slideshow and cookies. Thanks a lot!!! Thanks to your advice i have increased the compression on images and thumbnails so i hope the loading will be fast enough at the end. I will work later on different ways to reduce image size with minimal quality loss.
Thank You for your time! Hope this code will be helpful for others too.

jscheuer1
07-10-2013, 03:18 PM
Great! I don't know how you got those thumbnails to begin with, but I found that if I started over from scratch from the larger images, I could get a better resolution after compression and better cropping. However, this did require individual attention, and resulted in slightly larger thumb file size ~ 5K.

Here's an example (click to see the image):

5139

I don't have an optimizing batch program that can both resize and crop. I do, but it crops first before resizing, so the image that remains is not what is desired.

I looked into alternatives but found none that seem to fit the bill, one or two that might though. When I have more time I may investigate those. They say they do both cropping and resizing, but not in which order.

Amok
07-11-2013, 12:07 PM
I use http://phpthumb.gxdlabs.com/ for thumbnails and image cropping (on client side is jQuery imgAreaSelect).

I made a simple php function where i will try to set optimal jpeg quality. The result is not as good as yours so i will try other libraries.
5141



function resize_picture($path, $filename, $action, $percent=100, $x1=0, $y1=0, $width=0, $height=0)
{//require_once './include/phpthumb/ThumbLib.inc.php';
$image = $path . $filename;
$options = array('jpegQuality' => 85);
try
{
$resized = PhpThumbFactory::create($image, $options);
}
catch (Exception $e)
{
print_r("ERROR: Image resizing problem!");
}
if ( ($action == "crop") && ($width+$height > 0) ) $resized->crop($x1, $y1, $width, $height)->save($image); //coords from imgAreaSelect
if ($action == "fixed_size") $resized->adaptiveResize($width, $height)->save($image);
if ($percent < 100) $resized->resizePercent($percent)->save($image);

$resized->adaptiveResize(150, 150)->save( $path."thumb_".$filename);
return getimagesize($image);
}

jscheuer1
07-11-2013, 02:41 PM
OK, I may play with that. But I think a program might be better, one that allows you to tell it to resize the image and then crop it to certain dimensions. It would have to calculate in advance what dimensions to shrink to so that there would be enough left to crop in width or height, whichever were smaller. It might even be worth it, if there were such an option, to have it let you select the crop individually. Like if you could set it to center crop, but have each image come up one by one during the process, you could either hit an accept button, or drag the crop where you wanted it. For most of those images a center crop would be fine. With that one it needs to be higher up. I think I settled for about 3 pixels from the top. That's 3px from the top after the resizing. Others would benefit from off center cropping as well.

The advantage that a program has is that it can (if well written) be much more sophisticated in the compression algorithms that it applies. If I can just find one with that level of sophistication and the features I was mentioning at the beginning of this post, it would be fairly simple to get some real nice thumbs.

Even with my current program, through only a little trial and error one could determine which images need to be resized to 150 height, which to 150 width, it's the optional cropping feature that it lacks. It can crop, but there's no control over where the crop goes in batch mode. The Gimp (a free image editing program like Photoshop) has a command line mode that allows for batch processing of images. It can be quite complicated, but I'm not sure if it can be made to do what I'm after or not.

I'm also interested in two or more programs from this:

http://www.smashingmagazine.com/2008/10/02/15-useful-batch-image-processors/

listing. Most do not do cropping, but some look like they might even have the feature set I want or be able to be tweaked to have it - some can be programmed.

Amok
07-18-2013, 12:13 PM
This is interesting idea - i will try to make something with html5 (http://www.html5rocks.com/en/tutorials/file/dndfiles/) and imgAreaSelect. I will make a web page where i can drag and drop multiple files from computer and display them with some max-width/height (400x400) before uploading to php server. Then user can move a centered predefined selected area optionally (plase see Setting Initial Selection (http://odyniec.net/projects/imgareaselect/examples.html#setting-initial-selection) or Live Example: fixed width and height of thumb (http://odyniec.net/projects/imgareaselect/)). Then i can send coordinates and files to php and i can have good thumbs (with some calculation because of max-width) :) The only problem is that images are not very good compressed and thumbs are ~3KB bigger than yours. Maybe at some time i must run some batch with better compression to reduce size of thumbs if is required. Because i need my thumbs to be fixed to 150x150 my job is easier :) but will try to play with different options. All this seems to be a good tool for uploading images with options :)