Hello!
The newest thing that’s caught my attention has been a jquery infinite scroll plugin. Infinite scroll plugins like that allow the page to populate with new content as the user scrolls down, instead of having to go through next page/previous page buttons. I believe this to be an enhanement in usability and a good idea to employ in a web application. The particular website includes a wordpress plugin as well, but I will show you the jquery plugin.
Although the examples just read text content from a database, you can use them with any HTML element. Images, video, anything!
If you want to read up in the plugin’s documentation, it’s available in the github.
Most options aren’t required, however. These are the options that you have to use:
/* Call this where your dynamic entries will be. */ $('#posts').infinitescroll({ /* The CSS selector of your regular next/previous page navigation. This will be hidden when the script loads */ navSelector : "#pages", /* The CSS selector of the 'next page' link */ nextSelector : "#next", /* The CSS selector of each item that will be appended while scrolling (e.g. your posts)*/ itemSelector : ".post", });
Note: The plugin also expects a specific URL format, but it’s pretty flexible: something like /page/2, /page=2 etc will work. However, you need to increase pages by one like that (instead of just giving the server the id of the next record it should load, like page=5 for the second 5 items). I used to do it lazily like that, but it didn’t work out for me ;)
With a configuration like that, your HTML should be something like that:
Now, of course you have to write a backend for it, of course. (Or modify your current backend). I actually wrote two examples, in PHP and Catalyst
A PHP Example
prepare ("SELECT COUNT(*) FROM posts"); $statement->execute(); $statement->bind_result($count); $statement->fetch(); #The result is now in the $count variable. $statement->close(); # Get the posts in that 'page' $statement = $mysqli->prepare ("SELECT post_title, post_content FROM posts LIMIT ?, ?"); $statement->bind_param('ii', $page, $limit); $statement->execute(); $result = $statement->get_result(); # And start outputting HTML... echo ''; while ( $row = $result->fetch_array() ) { # And output one .post per database row :) echo ''; # #posts echo ''; } $statement->close(); echo '' . $row['post_title'] . '
' . $row['post_content'] . '
'; if ($page != 0) { echo 'Previous Page '; } if ($page + $limit < $count) { echo 'Next Page'; } echo ""; # Output the JS too echo " "; $mysqli->close(); ?>
And now you see how to implement the plugin in your PHP backend!
A Catalyst Example
I assume here that you use DBIx::Class in Model::DB and View::TT as your view. You can use other things but you’ll have to change the corresponding parts ;)
Oh, and that your controller Test::Controller::Post.
package Test::Controller::Post; use Moose; use namespace::autoclean; BEGIN { extends 'Catalyst::Controller' } # We'll make a base method for every valid link in /post. # Here we'll just find our post resultset. sub base :Chained('/') :PathPart('post') :CaptureArgs(0) { my ($self, $c) = @_; my $posts_rs = $c->model('DB::Post'); $c->stash->{posts_rs} = $posts_rs; } # Handle /page/[argument] # The client will load for example /page/5, and our backend # will get it in the $page variable sub page :Chained('base') :PathPart('page') :CaptureArgs(1) { my ($self, $c, $page) = @_; my $posts_rs = $c->stash->{posts_rs}; # DBIx makes this so simple my $result_rs = $posts_rs->search( undef, { page => $page, rows => 5 } ); # Get the required data that our template will need to render. # The current page, first and last page, previous and next page, # And of course, the rows in the result set (posts) my $pager = $result_rs->pager; $c->stash->{current_page} = $pager->current_page; $c->stash->{first_page} = $pager->first_page; $c->stash->{last_page} = $pager->last_page; $c->stash->{previous_page} = $pager->previous_page; $c->stash->{next_page} = $pager->next_page; my @posts = $result_rs->all; if (!scalar @posts) { $c->detach('/default'); } $c->stash->{posts} = \@posts; } # This will just choose the template for /page/NN sub view_page :Chained('page') :PathPart('') :Args(0) { my ($self, $c) = @_; $c->stash->{template} = 'post.tt'; } # And finally, if someone just goes to /post, redirect them to the first page. sub index :Chained('base') :PathPart('') :Args(0) { my ( $self, $c ) = @_; $c->response->redirect($c->uri_for('/post/page/1')); }
Now you just need a template for it:
[% FOREACH post IN posts %][% END %][% post.post_title | html %]
[% post.post_content | html %]
[% IF current_page != first_page %] Previous Page [% END %] [% IF current_page != last_page %] Next Page [% END %]
And now you should have a controller and view for it :]
Note that I’m still learning catalyst, so may not be the best solution. I like any improvement comments!
Until next time, bye bye.