YiinfiniteScroller pagination repeated rows - php

I am using yii YiinfiniteScroller. There are 260 records. i have displayed 12 records per page. Initially it loads first 12 records correctly. when i scroll the page, it loads the same 12 records (duplicate) And it repeats continuously when i scrolling only 12 records are repeated every time
Here is the code for view page
<?php
$this->widget('ext.yiinfinite-scroll.YiinfiniteScroller', array(
'contentSelector' => '#Load_addcont',
'itemSelector' => 'ul.wlist',
'loadingText' => 'Loading next 12 rows...',
'donetext' => 'Loading finish.',
'pages' => $pages,
));
?>
Here is the code for controller site
$pages = new CPagination($row_count);
$pages->setPageSize(12);
$pages->applyLimit($criteria);
$Wineries = Wineries::model()->findAll($criteria);
$flags = array();
Yii::log("Pagination Wineries row_count = $row_count page # = " . $pages->getCurrentPage(), 'error', 'actionSelectwineries.end');
Yii::log("Pagination Wineries GET = " . CVarDumper::dumpAsString($_GET), 'error', 'actionSelectwineries.end');
What is the problem? why same records are repeating? Pls help me if you know

Related

CakePHP 3 giving wrong pagination output when limit is changed for a custom finder

CakePHP 3.7.7
I'm using the Paginator (https://book.cakephp.org/3.0/en/views/helpers/paginator.html) to display pagination for a query that has 972 rows.
In my Controller method I am loading the Paginator component and using a custom finder called findFilters() to return the data that I want paginated.
public function initialize()
{
parent::initialize();
$this->loadComponent('Paginator');
}
public $paginate = [
'finder' => 'filters', // uses custom finder, findFilters() in src/Model/Table/FiltersTable.php
];
/*
* Called via ajax. Renders the data and pagination to a template.
*/
public function getFilters()
{
$this->viewBuilder()->setLayout('ajax');
$this->loadModel('Filters');
$rf_keywords = '';
$rf_keywords = trim($this->request->getData('rf_keywords'));
// Pagination settings (relevant to the question).
$page = $this->request->getData('page') ? (int)$this->request->getData('page') : 1;
$this->paginate = ['limit' => 200, 'page' => $page];
$finder = $this
->Filters
->find('filters' , [
'rf_keywords' => $rf_keywords
]);
$data = $this
->paginate($finder)
->toArray();
$this->set('data', $data);
}
In my template (get_filters.ctp) I have the following to output the pagination numbers (links to be clicked to go between pages) and the total counts:
<?= $this->Paginator->numbers(); ?>
<?= $this->Paginator->counter([
'format' => 'Page {{page}} of {{pages}}, showing {{current}} records out of
{{count}} total, starting on record {{start}}, ending on {{end}}'
]) ?>
The problem is that changing the limit in the Controller...
$this->paginate = ['limit' => 200];
... is not updating the output of the Pagination correctly. See examples below:
'limit' => 20:
Shows page numbers 1 - 9 and:
Page 1 of 49, showing 20 records out of 972 total, starting on record 1, ending on 20
'limit' => 100:
Shows page numbers 1 - 9 and:
Page 1 of 10, showing 100 records out of 972 total, starting on record 1, ending on 100
'limit' => 500:
Shows page numbers 1 - 9 and:
Page 1 of 10, showing 100 records out of 972 total, starting on record 1, ending on 100
'limit' => 1000 (more than there are rows in the DB!):
Shows page numbers 1 - 9 and:
Page 1 of 10, showing 100 records out of 972 total, starting on record 1, ending on 100
So there are 2 problems:
It doesn't work with any limit value >100. Nothing changes in terms of the pagination output in the template. The behaviour is as though it is ignoring anything supplied as the limit and defaulting to 100.
The page number links ($this->Paginator->numbers();) are always 1 - 9 when the limit is >100. That is to say they stay the same irrespective of whether I use a limit of 100, 200, 500, 1000. I'm guessing this is due to problem (1) where it seems to ignore the actual limit set if it's >100.
I thought this was some caching issue. The ajax requests to getFilters() are being made via jquery so I have set cache: false on them to ensure each request appends a timestamp to the URL to ensure it's not using some old cached response.
I have cleared the files in tmp/cache/models/*
I've a force refresh in the browser. Tried an incognito/private browsing window to make sure it's not some session issue.
None of these things solve the problem.
The issue is also consistent if the page part of Pagination is altered. For example using page => 3 will give the correct rows from the database for page 3. But the Pagination HTML will still be exactly the same as where the problem occurs.
Why isn't this working?
Edit - the custom Finder returns the correct data so I don't think this is an issue. The signature is below and it returns a Query object which is executed via Pagination:
// src/Model/Table/FiltersTable.php
public function findFilters(Query $query, array $options)
{
// $query->find() ...
// ...
return $query;
}
Bit late, but the problem is with default maxLimit settings for CakePHP 3 pagination, what is set to 100 by default (reference below).
https://book.cakephp.org/3/en/controllers/components/pagination.html#limit-the-maximum-number-of-rows-per-page
When you update settings in Controller to, it should do the trick.
public $paginate = [
// Other keys here.
'maxLimit' => 1000
];

Laravel Pagination the data not change with the render() in the blade

I have this problem, when i manually create a paginator in laravel for show 100 products, in the view the page displays the data and it is fine, but if i put a limit , example i want 10 element per page, he show the ten elements in the firs page, when i click in next the second page show me the same ten elements, the data don't changes , why?
Controller:
public function show()
{
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'http://www.mocky.io/v2/59bec4d926000046015261a7',
// You can set any number of default request options.
'timeout' => 2.0,
]);
$response = $client->request('GET', '');
$code = $response->getStatusCode()
$products = json_decode($response->getBody()->getContents());
}
$products = new Paginator($products, 10 ,
Paginator::resolveCurrentPage(),
['path' => Paginator::resolveCurrentPath()]);
return view('products/list', compact('products'));
}
View
#extends('layout.master')
#section('content')
<h2> Products</h2>
<ul>
#if($products)
#foreach($products as $product)
<li> {{ $product->name}} - {{ $product->value}}</li>
#endforeach
#endif
</ul>
{{$products->render()}}
#endsection
Example of Result with array of ten element , 3 per page
// this is a example with invented information.
array {0,1,2,3,4,5,6,7,8,9}
Page 1
0 - 0
1 - 1
2 - 2
Page 2 // the data dont change , why ?
0 - 0
1 - 1
2 - 2
No magic, paginators will call your controller function for every page. The request will have the pagination information in it. It is your job to actually select and slice the page. The paginator simply presents it... which is a big part of the work...
// DB::select returns an array, thus we have to build the paginator ourselves...
$comm = DB::select('select bla bla bla from comments where this and that...
order by approved ASC');
// this basically gets the request's page variable... or defaults to 1
$page = Paginator::resolveCurrentPage('page') ?: 1;
// Assume 15 items per page... so start index to slice our array
$startIndex = ($page - 1) * 15;
// Length aware paginator needs a total count of items... to paginate properly
$total = count($comm);
// Eliminate the non relevant items...
$results = array_slice($comm, $startIndex, 15);
$comments = new LengthAwarePaginator($results, $total, 15, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => 'page',
]);
return view('backend/comments', compact('comments'));
You need to add your page name (the name of the request param denoting the page number) like so:
$products = new Paginator($products, 10, null,
['path' => Paginator::resolveCurrentPath(),
'pageName' => 'page']);
I had the same problem, where the data was not changing. I solved it by passing a page number to my guzzle call. Whenever a link is clicked, a request is sent therefore, you can get the page number from the request object. Pass the page number to the guzzle call so that the page number changes. Hope It helps

CakePHP find count of records from associated Models

I have a Job model and a Visit model, a Job can have many Visit's. I have set up the relationships appropriately in my Models.
A Visit also belongs to a Supplier, so a Supplier can have many visits.
A subcontractor is a Supplier who has an engineer value of 0 in the database.
I want to return an associative array with the amount of Jobs raised per subcontractor, something like this:
$supplier_job_count = array(
'Subcontractor1' => 23,
'Subcontractor2' => 3,
'Subcontractor3' => 7,
'Subcontractor4'=> 0
);
Here is what I have:
$conditions = array();
// get all the visits in the database
$visits = $this->Job->Visit->find('all');
// extract all the visit id's
$visit_supplier_ids = Hash::extract($visits, '{n}.Visit.supplier_id'); // 11612 records
// get all the subcontractors in the database
$subcontractors = $this->Job->Visit->Supplier->find('all', array('order' => 'id ASC', 'conditions' => array('Supplier.engineer' => 0)));
// extract all the subcontractor id's
$subcontractor_ids = Hash::extract($subcontractors, '{n}.Supplier.id'); // 1288 records
// intersect arrays so we only want matching values from both, i.e. only want visits whose supplier is a subcontractor
$visit_subcontractors = array_values(array_intersect($visit_supplier_ids, $subcontractor_ids));
// find all visits who is a subcontractor id
$visits = $this->Job->Visit->find('all', array('conditions' => array('Visit.supplier_id' => $visit_subcontractors)));
// extract out the job id's for the subcontractor visits
$visit_jobs_ids = Hash::extract($visits, '{n}.Visit.job_id');
// pass the job id's to the conditions for the jobs
$conditions['Job.id'] = $visit_jobs_ids;
// get all subcontractor jobs
$subcontractor_jobs = $this->Job->find('all', array('conditions' => $conditions));
$subcontractor_job_count = array();
foreach ($subcontractors as $key => $value) {
// this is where I am getting stuck
$subcontractor_job_count[$value['Supplier.name']] = ));
}
I am sort of half way there, just struggling to get a count of how many jobs raised per subcontractor, any ideas?

cakePHP, page to a certain record

Is there a way to open directly the page in which a record appears?
Example:
function index($id){
$this->paginate = array(
'limit'=>12,
'page' => ????
);
$items = $this->Item->paginate();
/**
How can i calculate the page number, by the $id?
*/
}
If you got the ID, and you are auto_incrementing the ID in your database, you can count row before this ID:
$nbRow = $this->Item->find('count', array('conditions' => array('id <=' => $id))) ;
Then to find the page, you just have to divide (int division) by the number of item per page:
$page = ceil($nbRow / 12) ; // 12 or whatever item per page you have

Zend Framework 1, Bvb Grid, resultset is filtered only for the current page

I have reached very strange problem using Zend Framework 1 and binding the resultset to BvbGrid.
We have a method which queries an external API. You need to specify the following params: methodName, params.
So the controller recieves a resultset as an array from the external API.
The resultset (in the database) is 4 columns - 1 string, 2 DateTime, 3 int, 4 int. And is with about 3000 rows.
When I recieve the resultset in the controller I bind it to Bvb Grid, which should evaluate in the view as columns with search boxes.
So far, so good, when I search in the first or in the last column (string, int), it searches in the whole resultset.
But when I search 2, 3 (DateTime, int) it searches only in the current page.
I don't understand why is that. There is no difference in data binding, or something.
The code is as follows
public function indexAction() {
$pagesize = $this->_request->getPost('rows');
$pagenum = $this->_request->getPost('page');
$pagesize = ($pagesize) ? $pagesize : 30;
$pagenum = ($pagenum) ? $pagenum : 1;
$params = array();
$params['page_num'] = $pagenum;
$params['page_limit'] = $pagesize;
if ($this->_request->isXmlHttpRequest()) {
// additional search filter
if ($this->_request->getPost('username')) {
$params['username'] = $this->_request->getPost('username');
}
if ($this->_request->getPost('lastlogin')) {
$params['lastlogin'] = $this->_request->getPost('lastlogin');
}
if ($this->_request->getPost('type')) {
$params['type'] = $this->_request->getPost('type');
}
if ($this->_request->getPost('level')) {
$params['level'] = $this->_request->getPost('level');
}
}
if (($order_by = $this->_request->getPost('sidx')) && ($order_type = $this->_request->getPost('sord'))) {
$params['order_by'] = $order_by;
$params['order_by_type'] = $order_type;
}
$resultset = $this->web_service->_apiRequest('SearchUsers', $params);
/**
* The resultset is like
* array(
'found_rows' => 3000,
'body' => array(
'username' => 'blabla',
'lastlogin' => '2014-02-25 13:33:38.1234',
'type' => 1,
'level' => 199
)
);
*/
$this->view->count = $resultset['found_rows'];
if ($resultset['found_rows'] > 0 || $this->_request->isXmlHttpRequest()) {
$grid = new Bvb_Grid_Deploy_JqGrid($this->_gridconfig);
$grid->setSource(new Bvb_Grid_Source_Array($resultset['body']));
$grid->getSource()->setTotalRecords($resultset['found_rows']);
$grid->updateColumn('username', array('width' => '110',));
$grid->updateColumn('lastlogin', array('width' => '110',));
$grid->updateColumn('type', array('width' => '110',));
$grid->updateColumn('level', array('width' => '110',));
$grid->setJqgParams(array('caption' => 'resultset'
, 'forceFit' => true
, 'viewrecords' => true
, 'rowList' => array(15, 30, 50)
, 'altRows' => false
)
);
$grid->ajax(get_class($grid));
$grid->setNumberRecordsPerPage(30);
$grid->setExport(array());
$this->view->grid = $grid->deploy();
}
I have tried to examine the BvbGrid's code, but found nothing strange.
In another project the same code is used, and it works fine, without any problems on searching in any column. I have dump'd the API response to be sure it gives me 3000 records, and it actually is and they are in the way as in the comment. I really cannot find the reason why i.e. the lastlogin column searches only on the current page.
If someone can help me, or give me directions where to look at to fix the issue (maybe somewhere in the BvbGrid's code?) I will appreciate it.
Thank you in advance.

Categories