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::Path 'mkpath';
|
||||||
use File::Spec 'catfile';
|
use File::Spec 'catfile';
|
||||||
use Cwd;
|
use Cwd;
|
||||||
|
use POSIX;
|
||||||
|
|
||||||
use Imager;
|
use Imager;
|
||||||
use DBI;
|
use DBI;
|
||||||
|
@ -141,10 +142,21 @@ get '/' => sub {
|
||||||
get '/get_images' => ( authenticated => 1 ) => sub {
|
get '/get_images' => ( authenticated => 1 ) => sub {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
|
#Getting current user
|
||||||
my $current_user = $self->current_user;
|
my $current_user = $self->current_user;
|
||||||
my $user_id = $current_user->{'user_id'};
|
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 =
|
my $thumbs_dir =
|
||||||
File::Spec->catfile( $IMAGE_DIR, $current_user->{'user_id'},
|
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) {
|
for my $img_item (@$files_list) {
|
||||||
my $file = $img_item->{'file_name'};
|
my $file = $img_item->{'file_name'};
|
||||||
my $img_hash = {};
|
my $img_hash = {};
|
||||||
|
$img_hash->{'id'} = $img_item->{'file_id'};
|
||||||
$img_hash->{'filename'} = $img_item->{'original_filename'};
|
$img_hash->{'filename'} = $img_item->{'original_filename'};
|
||||||
$img_hash->{'original_url'} =
|
$img_hash->{'original_url'} =
|
||||||
File::Spec->catfile( '/', $IMAGE_BASE, $current_user->{'user_id'},
|
File::Spec->catfile( '/', $IMAGE_BASE, $current_user->{'user_id'},
|
||||||
|
@ -185,10 +198,14 @@ get '/get_images' => ( authenticated => 1 ) => sub {
|
||||||
$img_hash->{'scales'} = \@scaled;
|
$img_hash->{'scales'} = \@scaled;
|
||||||
|
|
||||||
push( @$images, $img_hash );
|
push( @$images, $img_hash );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $reply_data = { current_page => $page, items_per_page => $items, pages_count => $pages_count, images_list => $images };
|
||||||
|
|
||||||
# Render
|
# Render
|
||||||
return $self->render( json => $images );
|
return $self->render( json => $reply_data );
|
||||||
};
|
};
|
||||||
|
|
||||||
# Upload image file
|
# Upload image file
|
||||||
|
@ -201,7 +218,7 @@ post '/upload' => ( authenticated => 1 ) => sub {
|
||||||
|
|
||||||
my $user = $self->current_user();
|
my $user = $self->current_user();
|
||||||
my $user_id = $user->{'user_id'};
|
my $user_id = $user->{'user_id'};
|
||||||
$self->app->log->debug( "user:" . Dumper($user) );
|
# $self->app->log->debug( "user:" . Dumper($user) );
|
||||||
|
|
||||||
# Not upload
|
# Not upload
|
||||||
unless ($image) {
|
unless ($image) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package FotoStore::DB;
|
package FotoStore::DB;
|
||||||
|
|
||||||
|
use v5.20;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
|
@ -59,8 +60,17 @@ sub add_file($self, $user_id, $filename, $original_filename) {
|
||||||
return $rows;
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_files($self, $user_id, $count=20, $start_at=0) {
|
sub get_files($self, $user_id, $items_count=20, $page=1) {
|
||||||
return $self->{'dbh'}->selectall_arrayref(q~select * from images where owner_id=? order by created_time desc~, { Slice => {} }, $user_id );
|
|
||||||
|
# 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;
|
1;
|
|
@ -39,7 +39,7 @@
|
||||||
<div class="foto-block row" v-for="image in imagesList">
|
<div class="foto-block row" v-for="image in imagesList">
|
||||||
<div class="image col-md-3">
|
<div class="image col-md-3">
|
||||||
<img v-bind:src="image.thumbnail_url">
|
<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>
|
||||||
<div class="foto-notes col-md-3">
|
<div class="foto-notes col-md-3">
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -50,7 +50,20 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -60,27 +73,31 @@
|
||||||
var demo = new Vue({
|
var demo = new Vue({
|
||||||
|
|
||||||
el: '#images_list',
|
el: '#images_list',
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
imagesList: null
|
imagesList: null,
|
||||||
|
pageNumber: 1,
|
||||||
|
pagesCount: 5,
|
||||||
|
imagesPerPage: 20,
|
||||||
},
|
},
|
||||||
|
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchData()
|
this.fetchData(1)
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
fetchData: function () {
|
fetchData: function (pageNumber) {
|
||||||
var xhr = new XMLHttpRequest()
|
var xhr = new XMLHttpRequest()
|
||||||
var self = this
|
var self = this
|
||||||
xhr.open('GET', apiURL)
|
xhr.open('GET', apiURL+"?page="+pageNumber+"&per-page="+self.imagesPerPage)
|
||||||
xhr.onload = function () {
|
xhr.onload = function () {
|
||||||
self.imagesList = JSON.parse(xhr.responseText)
|
var result = JSON.parse(xhr.responseText);
|
||||||
}
|
self.imagesList = result.images_list;
|
||||||
xhr.send()
|
self.pagesCount = result.pages_count;
|
||||||
|
}
|
||||||
|
xhr.send()
|
||||||
},
|
},
|
||||||
copyText(event) {
|
copyText(event) {
|
||||||
//TODO: rewrite it to vue/JS from jquery
|
//TODO: rewrite it to vue or pure JS from jQuery
|
||||||
var $temp = $("<input>");
|
var $temp = $("<input>");
|
||||||
$("body").append($temp);
|
$("body").append($temp);
|
||||||
$temp.val("<img src="+$(event.target).text()+">").select();
|
$temp.val("<img src="+$(event.target).text()+">").select();
|
||||||
|
@ -89,5 +106,5 @@
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
|
@ -15,6 +15,7 @@
|
||||||
<link rel="stylesheet" href="/css/main.css">
|
<link rel="stylesheet" href="/css/main.css">
|
||||||
|
|
||||||
<script src="https://vuejs.org/js/vue.min.js"></script>
|
<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>
|
<style>
|
||||||
.bar {
|
.bar {
|
||||||
|
|
Loading…
Reference in a new issue