Pagination #9
4 changed files with 64 additions and 19 deletions
23
fotostore.pl
23
fotostore.pl
|
@ -9,6 +9,7 @@ use File::Basename 'basename';
|
|||
use File::Path 'mkpath';
|
||||
use File::Spec 'catfile';
|
||||
use Cwd;
|
||||
use POSIX;
|
||||
|
||||
use Imager;
|
||||
use DBI;
|
||||
|
@ -141,10 +142,21 @@ get '/' => sub {
|
|||
get '/get_images' => ( authenticated => 1 ) => sub {
|
||||
my $self = shift;
|
||||
|
||||
#Getting current user
|
||||
my $current_user = $self->current_user;
|
||||
my $user_id = $current_user->{'user_id'};
|
||||
|
||||
my $files_list = $db->get_files( $current_user->{'user_id'}, 20 );
|
||||
#Getting images list with paging
|
||||
my $page = $self->param('page') || 1;
|
||||
my $items = $self->param('per-page') || 20;
|
||||
|
||||
if (($page !~ /^\d+$/) || ($page <= 1)) { $page = 1}
|
||||
if (($items !~ /^\d+$/) || ($items <= 0)) { $items = 20}
|
||||
|
||||
# process images list
|
||||
my $req_result = $db->get_files( $current_user->{'user_id'}, $items , $page);
|
||||
my $files_list = $req_result->{'images_list'};
|
||||
my $pages_count = ceil($req_result->{'total_rows'}/$items);
|
||||
|
||||
my $thumbs_dir =
|
||||
File::Spec->catfile( $IMAGE_DIR, $current_user->{'user_id'},
|
||||
|
@ -157,6 +169,7 @@ get '/get_images' => ( authenticated => 1 ) => sub {
|
|||
for my $img_item (@$files_list) {
|
||||
my $file = $img_item->{'file_name'};
|
||||
my $img_hash = {};
|
||||
$img_hash->{'id'} = $img_item->{'file_id'};
|
||||
$img_hash->{'filename'} = $img_item->{'original_filename'};
|
||||
$img_hash->{'original_url'} =
|
||||
File::Spec->catfile( '/', $IMAGE_BASE, $current_user->{'user_id'},
|
||||
|
@ -185,10 +198,14 @@ get '/get_images' => ( authenticated => 1 ) => sub {
|
|||
$img_hash->{'scales'} = \@scaled;
|
||||
|
||||
push( @$images, $img_hash );
|
||||
|
||||
|
||||
}
|
||||
|
||||
my $reply_data = { current_page => $page, items_per_page => $items, pages_count => $pages_count, images_list => $images };
|
||||
|
||||
# Render
|
||||
return $self->render( json => $images );
|
||||
return $self->render( json => $reply_data );
|
||||
};
|
||||
|
||||
# Upload image file
|
||||
|
@ -201,7 +218,7 @@ post '/upload' => ( authenticated => 1 ) => sub {
|
|||
|
||||
my $user = $self->current_user();
|
||||
my $user_id = $user->{'user_id'};
|
||||
$self->app->log->debug( "user:" . Dumper($user) );
|
||||
# $self->app->log->debug( "user:" . Dumper($user) );
|
||||
|
||||
# Not upload
|
||||
unless ($image) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package FotoStore::DB;
|
||||
|
||||
use v5.20;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
@ -59,8 +60,17 @@ sub add_file($self, $user_id, $filename, $original_filename) {
|
|||
return $rows;
|
||||
}
|
||||
|
||||
sub get_files($self, $user_id, $count=20, $start_at=0) {
|
||||
return $self->{'dbh'}->selectall_arrayref(q~select * from images where owner_id=? order by created_time desc~, { Slice => {} }, $user_id );
|
||||
sub get_files($self, $user_id, $items_count=20, $page=1) {
|
||||
|
||||
# Calculate offset
|
||||
# Pages in UI starts from 1, but here we need it to start from 0
|
||||
$page = 1 if ($page < 1);
|
||||
my $start_at = --$page * $items_count;
|
||||
|
||||
my ($rows_count) = $self->{'dbh'}->selectrow_array(q~select count(*) from images where owner_id=? ~, undef , $user_id);
|
||||
my $images_list = $self->{'dbh'}->selectall_arrayref(q~select * from images where owner_id=? order by created_time desc LIMIT ? OFFSET ? ~, { Slice => {} }, $user_id, $items_count, $start_at );
|
||||
|
||||
return { total_rows => $rows_count, images_list => $images_list };
|
||||
}
|
||||
|
||||
1;
|
|
@ -39,7 +39,7 @@
|
|||
<div class="foto-block row" v-for="image in imagesList">
|
||||
<div class="image col-md-3">
|
||||
<img v-bind:src="image.thumbnail_url">
|
||||
<div class="image_title">{{ image.filename }}</div>
|
||||
<div class="image_title">{{ image.id }} - {{ image.filename }}</div>
|
||||
</div>
|
||||
<div class="foto-notes col-md-3">
|
||||
<ul>
|
||||
|
@ -50,7 +50,20 @@
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container paginator">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default">Prev</button>
|
||||
<button type="button" class="btn btn-default" v-for="pageNumber in pagesCount" v-on:click="fetchData(pageNumber)">{{ pageNumber }}</button>
|
||||
<button type="button" class="btn btn-default">Next</button>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="items-per-page-form">Fotos per page: <input v-model="imagesPerPage">
|
||||
<button type="button" class="btn btn-default" v-on:click="fetchData()">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
@ -60,27 +73,31 @@
|
|||
var demo = new Vue({
|
||||
|
||||
el: '#images_list',
|
||||
|
||||
data: {
|
||||
imagesList: null
|
||||
imagesList: null,
|
||||
pageNumber: 1,
|
||||
pagesCount: 5,
|
||||
imagesPerPage: 20,
|
||||
},
|
||||
|
||||
created: function () {
|
||||
this.fetchData()
|
||||
this.fetchData(1)
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetchData: function () {
|
||||
fetchData: function (pageNumber) {
|
||||
var xhr = new XMLHttpRequest()
|
||||
var self = this
|
||||
xhr.open('GET', apiURL)
|
||||
xhr.open('GET', apiURL+"?page="+pageNumber+"&per-page="+self.imagesPerPage)
|
||||
xhr.onload = function () {
|
||||
self.imagesList = JSON.parse(xhr.responseText)
|
||||
var result = JSON.parse(xhr.responseText);
|
||||
self.imagesList = result.images_list;
|
||||
self.pagesCount = result.pages_count;
|
||||
}
|
||||
xhr.send()
|
||||
},
|
||||
copyText(event) {
|
||||
//TODO: rewrite it to vue/JS from jquery
|
||||
//TODO: rewrite it to vue or pure JS from jQuery
|
||||
var $temp = $("<input>");
|
||||
$("body").append($temp);
|
||||
$temp.val("<img src="+$(event.target).text()+">").select();
|
||||
|
@ -89,5 +106,5 @@
|
|||
},
|
||||
}
|
||||
|
||||
})
|
||||
});
|
||||
</script>
|
|
@ -15,6 +15,7 @@
|
|||
<link rel="stylesheet" href="/css/main.css">
|
||||
|
||||
<script src="https://vuejs.org/js/vue.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/vuejs-paginator/2.0.1/vuejs-paginator.min.js"></script>
|
||||
|
||||
<style>
|
||||
.bar {
|
||||
|
|
Loading…
Reference in a new issue