Jamie000012 Jamie000012 - 2 months ago 25
jQuery Question

Laravel jQuery - Pagination and product filters, pagination URLs

I'm having some conflicting issues with my Laravel setup, specifically with the pagination and product filters.

Both pagination and product filters is being handled via jQuery so the page doesn't completely refresh.

This is my jQuery pagination code, working with the standard Laravel ->paginate functionality.

$(function() {
$('body').on('click', '.pagination a', function(e) {
e.preventDefault();
var url = $(this).attr('href');
var page_number = $(this).attr('href').split('page=')[1];
getProducts(page_number);
window.history.pushState("", "", url);
});
function getProducts(page_number) {
$.ajax({
url : '?page=' + page_number
}).done(function (data) {
$('.devices-holder').html(data);
}).fail(function () {
alert('Data could not be loaded.');
});
}
});


This works great, the issue is when we filter the products, and then try and go to another page on the filtered results.

Right after filtering, the paginate links are correct for example /devices/filter?filter=1&page2, however on clicking this the page loads all devices without the filter, even though if I copy that url and load that page, it succesfully goes to page 2 with the filters included.

Then the paginate URL's are completely ignoring the filter afterwards, and is /devices?&page=2. I figured it must be to do with me rendering and appending the paginate links in the view, but am unsure what I am doing wrong:

{!! $devices->appends(Input::all())->render() !!}


This is my controller:

public function devicesByFilter(Request $request) {

$type = 'devices';

$types = Input::get('types');

$devices = Device::where('type', '=', $type)->where('approved', '=', 1);

if(!empty($types)) {
$url = 'filter';
$check = 0;
foreach($types as $deviceType) {
if($check == 0) {
$devices = $devices->where('device_type', 'LIKE', $deviceType);
} else {
$devices = $devices->orWhere('device_type', 'LIKE', $deviceType);
}
$url = $url.'&types%5B%5D='.$deviceType;
$check++;
}
}
$devices = $devices->orderBy('match_order', 'asc')->paginate(10);

$devices->setPath('filter');

if ($request->ajax()) {
return view('devices.ajax.loadfilter', ['devices' => $devices, 'type' => $type, 'types' => $types])->render();
}

return View::make('devices.all', compact('devices', 'type'));
}


And this is my filter jQuery code:

$(document).ready(function () {

var types = [];

// Listen for 'change' event, so this triggers when the user clicks on the checkboxes labels
$('input[name="type[]"]').on('change', function (e) {


e.preventDefault();
types = []; // reset
if ( document.location.href.indexOf('filter') > -1 ) {
var url = '../devices/filter?type=device';
} else {
var url = 'devices/filter?type=device';
}

$('input[name="type[]"]:checked').each(function()
{
types.push($(this).val());
url = url+'&types%5B%5D='+$(this).val();
});

if ( document.location.href.indexOf('filter') > -1 ) {
$.get('../devices/filter', {type: 'devices', types: types}, function(markup)
{
$('.devices-holder').html(markup);
});
} else {
$.get('devices/filter', {type: 'devices', types: types}, function(markup)
{
$('.devices-holder').html(markup);
});
}
window.history.pushState("", "", url);
});


});

So at a poor attempt to clarify:


  • Pagination jQuery works perfect

  • Filtering works perfect

  • Trying to go another page after filtering displays all devices not just the filtered ones, even though the URL is correct and if I load this URL again on another tab, it has the right results.

  • After trying to go to another page of filtered results, the pagination links are missing the append input.



It's very difficult to debug this from here, anyone who can point in the right direction or something to try/test would be great.

Answer

Fixed it by changing

 $(function() {
    $('body').on('click', '.pagination a', function(e) { 
        e.preventDefault(); 
        var url = $(this).attr('href');  
        var page_number = $(this).attr('href').split('page=')[1];  
        getProducts(page_number);
        window.history.pushState("", "", url); 
    });
    function getProducts(page_number) {
        $.ajax({
            url : '?page=' + page_number  
        }).done(function (data) {
            $('.devices-holder').html(data);  
        }).fail(function () {
            alert('Data could not be loaded.');
        });
    }
});

to

 $(function() {
    $('body').on('click', '.pagination a', function(e) { 
        e.preventDefault(); 
        var url = $(this).attr('href');  
        getProducts(url);
        window.history.pushState("", "", url); 
    });
    function getProducts(url) {
        $.ajax({
            url : url
        }).done(function (data) {
            $('.devices-holder').html(data);  
        }).fail(function () {
            alert('Data could not be loaded.');
        });
    }
});
Comments