Slide to Paginate
An underrated issue with web pagination is the amount of accessible pages: when dozens are available, the selector becomes too large (and unusable on mobile) or incomplete (as not all pages are rappresented and selectable; sometime, just the previous and the next pages are available).
So I tried to replace the classic pagination component with an interactive input range, which fits any width and contains any number of steps. Moving the slider, a tooltip suggests the page to jump to (useful on mobile interaction); releasing the slider, if the selected index differs the current page, a reload is triggered.
In the Blade template, the range pagination is used when the number of pages is more the 10:
@if($pages >= 10)
<nav>
<div id="range-paginator-wrap">
<div class="range-value" id="range-paginator-label"></div>
<input id="range-paginator" type="range" min="1" max="{{ $pages }}" value="{{ $current_page + 1 }}" step="1" data-url="{{ $url . '?page=XXX' }}" data-range-message="Go to page XXX">
</div>
</nav>
@else
<nav>
<!-- Here comes the classic pagination -->
</nav>
@endif
The Javascript:
let rangepaginator = $('#range-paginator');
if (rangepaginator.length) {
let current = parseInt(rangepaginator.val());
rangepaginator.on('input', function(e) {
/*
Most of this code comes from
https://codepen.io/onyx1812/pen/GRJxmva
*/
let val = parseInt($(this).val());
let min = parseInt($(this).attr('min'));
let max = parseInt($(this).attr('max'));
let newValue = Number((val - min) * 100 / (max - min) );
let newPosition = 10 - (newValue * 0.2);
let message = val;
if (val != current) {
message = $(this).attr('data-range-message').replace('XXX', val);
}
$('#range-paginator-label').html('<span>' + message + '</span>').css('left', 'calc(' + newValue + '% + (' + newPosition + 'px))');
})
.on('touchend mouseup', function(e) {
let val = parseInt($(this).val());
if (val != current) {
let url = $(this).attr('data-url').replace('XXX', val - 1);
window.location = url;
}
else {
/*
If the current page index is still selected,
the tooltip disappears and nothing happens
*/
$('#range-paginator-label').html('');
}
})
}
The Sass style (mostly inspired from this post):
#range-paginator-wrap {
width: 100%;
position: relative;
#range-paginator {
margin: 20px 0;
width: 100%;
&:focus {
outline: none;
}
}
#range-paginator-label {
position: absolute;
top: -50%;
span {
width: 100px;
height: 24px;
line-height: 24px;
text-align: center;
background: #03a9f4;
color: #fff;
font-size: 12px;
display: block;
position: absolute;
left: 50%;
transform: translate(-50%, 0);
border-radius: 6px;
&:before{
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 10px solid #03a9f4;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
top: 100%;
left: 50%;
margin-left: -5px;
margin-top: -1px;
}
}
}
}