jbowman99's avatar

Pagination Problems, using Query Builder results

Pagination is currently working on my index page, but when you search for an Item, and return results with pagination, the pagination breaks.

postSearch Method looks like this:

public function postSearchItems(ItemSearchRequest $request, $limit = 5)
    {
        if (\Request::has('itemID')) {
            // Since the item search select can only accommodate the ItemID but we want to be able to do a like search
            // on the ItemName, we still use the ItemID to get the item name and then do a search on it.
            $itemQuery = Item::where('ItemName', 'LIKE', '%' . Item::where('ItemID',\Request::get('itemID'))->first()->ItemName . '%');
        }

        if (\Request::has('itemPOSID')) {
            $itemQuery = \Request::has('itemID') ? $itemQuery->where('POSID', \Request::get('itemPOSID')) :
                Item::where('POSID', \Request::get('itemPOSID'));
        }

        $filterStatus = \Request::get('itemStatus');
        $filterIsCombo = \Request::get('isComboItem');
        $filterIsModifier = \Request::get('isModifier');

        if ($filterStatus != static::SHOW_ALL) {
            $itemQuery = $itemQuery->where('ItemActive', $filterStatus);
        }

        if ($filterIsCombo != static::SHOW_ALL) {
            $itemQuery = $itemQuery->where('IsComboItem', $filterIsCombo);
        }

        if ($filterIsModifier != static::SHOW_ALL) {
            $itemQuery = $itemQuery->where('isModifier', $filterIsModifier);
        }

        return view("admin::menus.items.itemsIndex", [
            'items' => $itemQuery->where('RestaurantID',
                $this->restaurantService->restaurant->RestaurantID)->with('categories')->paginate($limit),
            'mainMenu' => 'Manage Menus',
            'subMenu' => 'Items'
        ]);
    }

tried to set up manual pagination and i get a trying to get a undefined property error in the blade.

$pageStart = \Request::get('page', 1);
        $perPage = 10;

        $offSet = ($pageStart * $perPage) - $perPage;

        $itemsForCurrentPage = array_slice($itemQuery, $offSet, $perPage, true);

                $items = new LengthAwarePaginator($itemsForCurrentPage, count($itemQuery), $perPage, Paginator::resolveCurrentPage(), array('path' => Paginator::resolveCurrentPath()));

array_slice breaks with $itemQuery being an object so i can add toArray() thats when the undefined property hits.

0 likes
18 replies
andremellow's avatar

Are you not passing "pageStart" with your filters?

I mean, if you are at page 10 and search, maybe after filtering you will have less then 10 pages. When search you nessd to clear the pageStart.

andremellow's avatar

If you have just on page in your result, but try to access page number 2...

try to hold $pageStart to 1.

Just to be sure.

d3xt3r's avatar

the pagination breaks.

What happens ?

jbowman99's avatar

@premsaurav

controller method not found restaurant/items/search-items works fine restaurant/items/search-items?page=2 comes back as a controller method not found

d3xt3r's avatar

Can i see your routes? Are you using $paginator->render() in view. I see that you are using post request for initial page i.e. page = 1, but the links generated will correspond to get request for subsequent requests and 1. your search query will be lost. 2. You will hit the wrong (unintended route)

jbowman99's avatar

@premsaurav

{!! $items->render() !!} route:

            'restaurant/items' => 'Restaurant\Menus\ItemsController',
d3xt3r's avatar

Can i see your routes? All the routes for your ItemsController?

jbowman99's avatar

@premsaurav

that is the only route specified into the routes.php file for ItemsController everything else is built into a service or inside the controller itself

jbowman99's avatar

@premsaurav

this is the get method which leads to the initial index page

public function getIndex($limit = 10)
    {
        $restaurant = $this->restaurantService->restaurant;

        return view("admin::menus.items.itemsIndex", [
            'items' => Item::where('RestaurantID', $restaurant->RestaurantID)->paginate($limit),
            'mainMenu' => 'Manage Menus',
            'subMenu' => 'Items'
        ]);
    }
d3xt3r's avatar

So what is the controller method that's not found ? getSearchItems() ?

I see that you are using post request for initial page i.e. page = 1, but the links generated will correspond to get request for subsequent requests and 1. your search query will be lost. 2. You will hit the wrong (unintended route)

Use search functionality with get request and remove the _token?

jbowman99's avatar

@premsaurav

yes that seems to be the method not being found.

so this postSearchItems should be a get method?

d3xt3r's avatar

Yes and all the filters needs to be appended to the pagination links.

As an example,

$items = $itemQuery->where('RestaurantID',
                $this->restaurantService->restaurant->RestaurantID)->with('categories')->paginate($limit)

$filter= [];

if (\Request::has('itemID')) {
    $filter['itemID'] = \Request::get('itemID');
}

// so on and so forth

$items->appends($filter);

return view("admin::menus.items.itemsIndex", [
            'items' =>  $items
            'mainMenu' => 'Manage Menus',
            'subMenu' => 'Items'
        ]);
jbowman99's avatar

@premsaurav

should i be changing the filters from individual ones like this:

$filterStatus = \Request::get('itemStatus');

and create an array instead

$filter = [];

if (\Request::has('itemStatus')) {
    $filter['itemStatus'] = \Request::get('itemStatus');
}

if ($filter['itemStatus'] != static::SHOW_ALL) {
            $itemQuery = $itemQuery->where('ItemActive', $filter['itemStatus']);
        }

something like that?

d3xt3r's avatar

the implementation depends all upto you, but yes this seems like a nice way to read and keep all your filters at one place and finally use it to generate query and later pass it to paginator.

jbowman99's avatar

@premsaurav

here's what i have so far,

public function getSearchItems(ItemSearchRequest $request, $limit = 5)
    {
        if (\Request::has('itemID')) {
            // Since the item search select can only accommodate the ItemID but we want to be able to do a like search
            // on the ItemName, we still use the ItemID to get the item name and then do a search on it.
            $itemQuery = Item::where('ItemName', 'LIKE', '%' . Item::where('ItemID',\Request::get('itemID'))->first()->ItemName . '%');
        }

        if (\Request::has('itemPOSID')) {
            $itemQuery = \Request::has('itemID') ? $itemQuery->where('POSID', \Request::get('itemPOSID')) :
                Item::where('POSID', \Request::get('itemPOSID'));
        }

        $items = $itemQuery->where('RestaurantID',
            $this->restaurantService->restaurant->RestaurantID)->with('categories')->get();

        $filter= [];

        if (\Request::has('itemStatus')) {
            $filter['itemStatus'] = \Request::get('itemStatus');
        }

        if ($filter['itemStatus'] != static::SHOW_ALL) {
            $itemQuery = $itemQuery->where('ItemActive', $filter['itemStatus']);
        }

        if (\Request::has('isComboItem')) {
            $filter['isComboItem'] = \Request::get('isComboItem');
        }

        if ($filter['isComboItem'] != static::SHOW_ALL) {
            $itemQuery = $itemQuery->where('IsComboItem', $filter['isComboItem']);
        }

        if (\Request::has('isModifier')) {
            $filter['isModifier'] = \Request::get('isModifier');
        }

        if ($filter['isModifier'] != static::SHOW_ALL) {
            $itemQuery = $itemQuery->where('ItemActive', $filter['isModifier']);
        }

        $items->appends($filter);

        return view("admin::menus.items.itemsIndex", [
            'items' => $items,
            'mainMenu' => 'Manage Menus',
            'subMenu' => 'Items'
        ]);
    }

by the way the assistance is much much appreciated.

d3xt3r's avatar
d3xt3r
Best Answer
Level 29

Try this, have refactored it a bit. appends() works on paginator and not collection

public function getSearchItems(ItemSearchRequest $request, $limit = 5)
    {
        $filter= [];
        
        if (\Request::has('itemID')) {
            
            $filter ['itemID']= \Request::get('itemID');
            
            // Since the item search select can only accommodate the ItemID but we want to be able to do a like search
            // on the ItemName, we still use the ItemID to get the item name and then do a search on it.
            $itemQuery = Item::where('ItemName', 'LIKE', '%' . Item::where('ItemID',\Request::get('itemID'))->first()->ItemName . '%');
        }

        if (\Request::has('itemPOSID')) {
            
            $filter ['itemPOSID']= \Request::get('itemPOSID');
            
            $itemQuery = \Request::has('itemID') ? $itemQuery->where('POSID', \Request::get('itemPOSID')) :
                Item::where('POSID', \Request::get('itemPOSID'));
        }
        
        if (\Request::has('itemStatus')) {
        
            $filter['itemStatus'] = \Request::get('itemStatus');
            
            if ($filter['itemStatus'] != static::SHOW_ALL) {
                $itemQuery = $itemQuery->where('ItemActive', $filter['itemStatus']);
            }
            
        }

        

        if (\Request::has('isComboItem')) {
        
            $filter['isComboItem'] = \Request::get('isComboItem');
            
            if ($filter['isComboItem'] != static::SHOW_ALL) {
                $itemQuery = $itemQuery->where('IsComboItem', $filter['isComboItem']);
            }
        }

        

        if (\Request::has('isModifier')) {
        
            $filter['isModifier'] = \Request::get('isModifier');
            
            if ($filter['isModifier'] != static::SHOW_ALL) {
                $itemQuery = $itemQuery->where('ItemActive', $filter['isModifier']);
            }
        }

      
        $items = $itemQuery->where('RestaurantID',
            $this->restaurantService->restaurant->RestaurantID)->with('categories')->paginate($limit);
 
        $items->appends($filter);

        return view("admin::menus.items.itemsIndex", [
            'items' => $items,
            'mainMenu' => 'Manage Menus',
            'subMenu' => 'Items'
        ]);
    }

Please or to participate in this conversation.