cakephp two paginations on one controller and one view - cakephp

I have a controller that has two paginations which is reflected in my view but anytime I want to click on page 2, the controller doesnt know which page it is clicking on and I get an error.
class AsController extends AppController
{
public function view ($id = null)
{
$data1 = $this->paginate('Post','Post.foriegn_id' => $id);
$data1 = $this->paginate('Author','Author,foreign_id' => $id);
// rest of the code goes here
}
}
I have two sections in my view page
<div class="post view"> and div class="author view"
And in each of tehse sections I have the following code:
<div class="paging">
<?php
echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
?>
</div>
Please assist me in any way to rectify this issue
Cheers

It looks like its more of a structure/design issue. You are using the same id to get posts and authors. Do you have a relationship between posts and authors you can just paginate through one of the models? From what I know the pagination built into cake is meant to work with one model per request. Especially due to how the pagination helper uses the url params. Do you have a case where you want to show page 1 of posts and page 2 of authors? Also in your view action you have your second paginate() saving to the same $data1 var which is overwriting the previous. Not sure if this is a typo.
I would suggest only using one main section of pagination per page. If the data of the authors relates to the posts I would suggest containing and displaying it in the same paginated section.

Related

CakePHP outputting redundant pagination link on last page

I'm using a custom pagination template with CakePHP 3.7
The template is in config/infinite-scroll-paginator.php. I want to use this with the Infinite Scroll jquery plugin. Therefore all that's required is 1 link per paginated page which contains the URL to the "next" page (i.e. next set of results).
So in the file above I have:
$config = [
'nextActive' => '<a class="pagination__next" aria-label="Next" href="{{url}}">{{text}}</a>'
];
In my Controller I start by telling it to use the custom pagination template:
public $helpers = [
'Paginator' => ['templates' => 'infinite-scroll-paginator']
];
Then when I want to paginate my data I use a custom finder (findFilters() which is in Model/Table/FiltersTable.php):
public $paginate = [
'finder' => 'filters',
];
I can then use this to get paginated data:
$this->loadModel('Filters');
$rf_keywords = trim($this->request->getQuery('rf_keywords'));
// Pagination
$page = $this->request->getQuery('page') ? (int)$this->request->getQuery('page') : 1;
$this->paginate = ['page' => $page, 'limit' => 100];
$finder = $this
->Filters
->find('filters', [
'rf_keywords' => $rf_keywords
]);
$data = $this->paginate($finder);
$this->set('data', $data);
Then in my template I output the paginator HTML:
<?= $this->Paginator->next(); ?>
All of this works fine. I get a "next" link for each page. Say if I have 10 pages I get URL's:
/get-filters/?page=1
/get-filters/?page=2
...
/get-filters/?page=10
The issue is that on the 10th page there is a "next" link and the URL of it is just
/get-filters
There are no more pages to output but I still get a link, albeit an invalid one.
How can I stop it from outputting the link on the last page? I thought that the paginator component would take care of this since it's aware how many pages there are based on my limit value in $this->paginate?
Use $this->Paginator->hasNext() which returns true or false depending on whether there is a "next page".
In the template:
<?php if ($this->Paginator->hasNext()): ?>
<?= $this->Paginator->next(); ?>
<?php endif; ?>

Cakephp breadcrumb

I am a Cakephp beginner
I am creating breadcrumbs from my website, I am not sure what is the difference between using HTML helper and Breadcrumb helper, Html helper seems easier to use, but it seems like I have to add each crumb to each page manually, please correct me if i am wrong.
When I was trying to use the Html helper, I put
<?php echo $this->Html->getCrumbs(' > ', array( 'text' => 'Customers', 'url' => array('controller' => 'customers', 'action' => 'index'), 'escape' => false)); ?>
in my index.ctp
then, i put
<?php $this->Html->addCrumb('Add customer', 'Customers/add'); ?>
in add.ctp
the breadcrumb "Customer" appears on the index.ctp, but when i go to the add.ctp page, no breadcrumb is shown.
I tried putting
echo $this->Html->getCrumbs(' > ', 'Home');
in default.ctp, then the "Add customer" appears after the Home crumb
How can I make it so that, on the add.ctp , the breadcrumb shows like this:
Customers > Add customer
You should take a better look at the documentation in the cookbook, usually it's all there.
Steps are:
Create a place for cakePHP to display the breadcrubs in your layout template, not index.ctp using something like echo $this->Html->getCrumbs(' > ', 'Home');. You should find your default layout in View/Layout/default.ctp.
Add a trail in each page with something like $this->Html->addCrumb('Add customer', 'Customers/add'); for View/Customers/add.ctp
This is all done by the HTML helper, there isn't any different (official) breadcrumb helper.

Deleting Multiple selected items from table

In my table I have a column with a check box for each row. I want to be able to delete all the selected items. I found the code from this website and modified it for my own stuff.
Link
I followed the website's naming convention for the check boxes and it is as follows:
<td> <?php echo $this->Form->checkbox('LocalClocks.id.['.$LocalClock['LocalClock']['id'].']', array('value' => $LocalClock['LocalClock']['id'])); ?></td>
This is the code in my controller for the deleteSelected() function:
public function deleteSelected()
{
foreach($this->data['LocalClocks'] as $key => $value)
{
if($value != 0)
{
$this->LocalClock->del($value);
}
}
$this->redirect($this->referer());
}
This is the code for the actual delete button (just in case it is needed):
<?php echo $this->Form->postLink('Delete Selected', array('action' => 'deleteSelected'), array('confirm' => 'Are you sure?')); ?>
There are a couple things I think might be the problem:
The code was written for an older version of cake, I think the website said 1.3, but I don't know what to update/correct in the existing code to make it work.
The delete button is the same as the one on cakephp's website on the blog tutorial. The only change I made was removing the id of the item to delete, because im not deleting a single item but multiple items.
Any help would be great.
Your checkbox input should be something like this
echo $this->Form->checkbox('LocalClocks.'.$LocalClock['LocalClock']['id'], array(
'value' => $LocalClock['LocalClock']['id'],
'hiddenField' => false
));
This will create a data array that will look like this
array(
'LocalClocks' => array(
1 => 1,
42 => 1
)
);
And will omit any unchecked ones from the data array because we're not using the hidden field. Finally, just a couple changes to your action
public function deleteSelected()
{
foreach($this->request->data['LocalClocks'] as $key => $value)
{
$this->LocalClock->delete($key);
}
$this->redirect($this->referer());
}
I prefer using Model::delete() to Model::deleteAll() because it runs the callbacks, where deleteAll does not.
Finally, your link will actually be a submit button. This will POST the data to the controller.
echo $this->Form->end('Submit');
If you want to use ajax, use the JsHelper to submit it instead. The following creates an Ajax submission that updates the dom element #mytable with the results of the action (in this case the referer that you redirect to).
echo $this->Js->submit('Submit', array(
'update' => '#mytable'
));
echo $this->Form->end();
once you got the list of your checked boxes; rather than using foreach loop to delete your ids one by one try this:
$this->Model->deleteAll(array('Model.column' => array($keys)));

cakePHP paginator not passing passedargs

I am using cakePHP and I am trying to get the paginator component to pass the get variables, or passedargs, when you click through to different pages. I have a variety of different search input selectors which "filters" the results returned. This works on first view, but the moment I click on a different page, it shows all of the results.
I have the following setup for my paginator:
// In my controller class:
public $paginate = array('maxLimit' => 10, 'paramType' => 'querystring');
// Within my action method:
$this->paginate = array('conditions' => array(...),
order => array('Model.field ASC'),
'limit' => 20
);
// Calling the paginator:
$results = $this->paginate('Model');
$this->set(compact('results'));
In my view file:
<div class="paging">
<?php
echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
?>
</div>
EDIT:
From my understanding it's better to use the passedArgs, but I am a little unsure as to how to do this. My $this->passedArgs returns no results, so I am creating the passed parameters within my controller example. I also changed my form from Get to Post:
$this->passedArgs["searchfield"] = $_POST["value"];
It passes the passedArgs now correctly in the pagination strip, but I am unsure as to how to build the paging conditions array now. In most cases users will not select default values example, one of the filters is date from and date to, and then a search input box, if I leave the dates it will still created the argumens and not return any results so in essence my url would be something like:
http://localhost/site/controller/action/page:3/datefrom:0/dateto:0/searchFor:survey
Any assistance?
You can pass by all parameters in the view with:
$this->Paginator->options(array('url' => $this->passedArgs));
or assign the params manually:
$this->Paginator->options(array('url' => array("0", "1")));
befor echoing the paginator
See the CakePHP Cookbook for further Examples

How to create a static page in cakephp?

Currently am creating one auction website using cakephp. It have a menu bar like about us, contact us. I have created only the default page. So i want to create those pages. advice me how to create.
Old thread, but I found it while trying to do the same in 2.x.
Jack's answer is correct, with a small typo. It should be
Router::connect('/about', array('controller' => 'pages', 'action' => 'display', 'about'));
Hopefully this helps someone else, as it did me.
Create an about.ctp in the /app/views/pages/ folder.
Then add Router::connect('/about', array('controller' => 'pages', 'action' => 'display', 'about')); in the /app/config/routes.php file. You should be able to access it at www.yoursite.com/about
Since the new version of cakephp is freshly out, I'm adding this answer to deal with the newer version (3.x).
To link to a static page you still use the PageController but the code slightly changed.
Here the code you would need in the 3.x version
$routes->connect('/about', ['controller' => 'Pages', 'action' => 'display', 'about']);
You can read more about the new routing system here.
I have no affiliation with cakephp. I added this answer since I found this post while searching how to do this in 3.0
Read more here
Method 1: if you want to create content pages like about us, privacy policy which contents can be changed by an admin interface follow these steps
Step1: Change pagesController
class PagesController extends AppController {
function beforeFilter() {
$this->Auth->allow('content');//to allow to be visible for non-logged in users, if you are using login system
parent::beforeFilter();
}
public function content($id = null, $layout = null, $theme=null) {
if ($layout) $this->layout = $layout;//if you are using mulitple layouts and themes and want to change it dynamicaly
if ($theme) $this->theme = $theme;
$this->set('content', $this->Page->find('first', array('conditions' => array('Page.id' => $id))));
$this->Page->id= $id;
$this->set('title_for_layout', $this->Page->field('title'));
}
}
Step 2: add a table content with fields you need like id, title, content, image, theme,layout etc.
Step 3: In View/Pages add content.ctp
<div class="row innerPage">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="row userInfo">
<div class="col-xs-12 col-sm-12">
<h1 class=" text-left border-title"> <?php echo $content['Page']['title'];?> </h1>
<div class="w100 clearfix">
<?php echo $content['Page']['content'];?>
</div>
</div>
</div>
However you can change html according to your need, I prefer bootstrap framework.
Then you can use it as
<?php echo $this->html->link("Terms of Services", array("controller" => "pages", "action" => "content", 5), array("class" => 'themeprimary','target'=>'_blank')) ?>
This will generate a link yoursite/pages/content/5. 5 is the id of row you want to show the details of.
If you want your link like yoursite/terms then you need one more step to go. In routes.php add this line.
Router::connect('/terms', array('controller' => 'pages', 'action' => 'content',5));
Method 2: You simply need to display content without any database
Step1 :Just create a about.ctp under View/Pages and put the content you want to display
Step 2: Change your pagesController. add a method about
public function about($layout = null) {
$this->set('title_for_layout', 'About');
}
Thats it.
You can use the pages controller for this purpose.
Creating views at APP/views/pages/ with names such as about_us.ctp and contact_us.ctp will allow you to access them at the url:
www.site.com/pages/about_us
you can then change how these URIs look with routing.

Resources