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
Related
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.
I'm having this issue where the previous button of the paginator is disabled (have disabled class) by default, even if I am in to second or third or any page. If I remove the 'id => prevPage' and 'id => nextPage' then it works fine but I have to use it to make another ajax request.
I'm using this in my ajax view..
echo $this->Paginator->prev('< ' . __('Zur'), array('id' => 'prevPage'), null, array('class' => 'prev disabled'));
echo $this->Paginator->next(__('Vor') . ' >', array('id' => 'nextPage'), null, array('class' => 'next disabled'));
while in my controller, I have;
if($this->RequestHandler->isAjax()) {
$this->autoRender = false;
$this->set('products',$this->paginate('Product'));
$this->set('page',$page);
$this->render('ajaxView');
}
I did a little googling which suggested me it might be bug.. is it? How do I solve?
I wasn't able to find the error, but I fixed the error by going through other way. I was using 'offset' while I was paginating in the controller before which had introduced the error, but using the other way around by requesting to '.../page:3?q=' on the ajax call, did solved the problem. Thanks to #hereshem for the quick fix.
I'm using CakePHP 2.2. I'm adapting a method of dynamically updating a selectbox which I got from: http://www.willis-owen.co.uk/2011/11/dynamic-select-box-with-cakephp-2-0/#comment-10773 which works without issue. It updates the 'hotels' selectbox contents when the users selects a 'region' from another select box.
On the same form, I want to automatically populate multiple 'team' fields with address details from the 'hotels' model when a user selects a 'hotel' from the selectbox.
The user can then modify the address ... all of this before the user clicks submit on the 'team' add view.
In Team\add.ctp view I have the following code:
echo "<div id='address'>";
echo $this->Form->input('address_1');
echo $this->Form->input('address_2');
echo $this->Form->input('address_3');
echo $this->Form->input('city');
echo $this->Form->input('postcode');
echo $this->Form->input('country');
echo "</div>";
...
$this->Js->get('#TeamHotelId')->event('change',
$this->Js->request(array(
'controller'=>'hotels',
'action'=>'getAddress'
), array(
'update'=> '#address',
'async' => true,
'method' => 'post',
'dataExpression' => true,
'data'=> $this->Js->serializeForm(array(
'isForm' => true,
'inline' => true))
)
)
);
In my HotelsController.php I have:
public function getAddress() {
$hotel_id = $this->request->data['Team']['hotel_id'];
CakeLog::write('debug', print_r($hotel_id, true));
$address = $this->Hotel->find('first', array(
'recursive' => -1,
'fields' => array('hotel.address_1', 'hotel.address_2', 'hotel.address_3', 'hotel.city', 'hotel.postcode', 'hotel.country'),
'conditions' => array('Hotel.id' => $hotel_id)
));
CakeLog::write('debug', print_r($address, true));
$this->set('hotels', $address);
$this->set(compact('address'));
$this->layout = 'ajax';
}
hotels\get_address.ctp:
<?php
echo $this->Form->input('Team.address_1', array('value'=> $address['Hotel']['address_1']));
echo $this->Form->input('Team.address_2', array('value'=> $address['Hotel']['address_2']));
echo $this->Form->input('Team.address_3', array('value'=> $address['Hotel']['address_3']));
echo $this->Form->input('Team.city', array('value'=> $address['Hotel']['city']));
echo $this->Form->input('Team.postcode', array('value'=> $address['Hotel']['postcode']));
echo $this->Form->input('Team.country', array('value'=> $address['Hotel']['country'])); ?>
This now works and the code has been updated.
You can not do in that way as you are trying to accomplish. However, there is a way in which you can update as you want by passing an id from dropdown using ajax and populating all the other fields on the basis of that id. Please make sure in 'update'=>#id you should put the div id of a div containing all the fields you want to show on the page where you want your contents to appear on ajax request.
Note: Please follow the Richard link which you have given i.e. www.willis-owen.co.uk, it will definitely help you that you are trying to do.
Short version
I have some HABTM checkboxes on a form. Validation is working correctly (at least one checkbox needs to be checked for validation to pass) but the CakePHP error message divs aren't being generated as they should be.
Long Version
I have a from which allows users to fill in their name and email address and then choose from a list of brochures (checkboxes) they'd like to receive.
The form looks like this:
<?php
echo $this->Form->create('Request',array('action' => 'index'));
echo $this->Form->input('id');
echo $this->Form->input('name');
echo $this->Form->input('email');
echo $this->Form->input('Brochure',array(
'label' => __('Information Required:',true),
'type' => 'select',
'multiple' => 'checkbox',
'options' => $list,
'selected' => $this->Html->value('Brochure.Brochure'),
));
echo $this->Form->submit('Submit');
echo $this->Form->end();
?>
In my controller, $list is set as like this:
$this->Request->Brochure->find('list',array('fields'=>array('id','name')));
After reading the 2nd answer (posted by user448164) in HABTM form validation in CakePHP on Stack Overflow, I set my Request model up like this:
<?php
class Request extends AppModel {
var $name = 'Request';
function beforeValidate() {
foreach($this->hasAndBelongsToMany as $k=>$v) {
if(isset($this->data[$k][$k]))
{
$this->data[$this->alias][$k] = $this->data[$k][$k];
}
}
}
var $validate = array(
'name' => array(
'rule' => 'notEmpty',
'message' => 'Please enter your full name'
),
'email' => array(
'rule' => 'email',
'message' => 'Please enter a valid email address'
),
'Brochure' => array(
'rule' => array('multiple', array('min' => 1)),
'message' => 'Please select 1'
),
);
?>
This actually works 99% well. If none of the checkboxes are checked, validation fails as it should do. However, the only problem is that Cake isn't setting the "error" class on the <div>, nor is it creating the <div class="error-message">Please select 1</div> as it should.
For name and email, there is no problem - the error divs are being created properly.
So, to clarify, validation is working for my HABTM checkboxes. The only problem is that the error divs aren't being generated.
I'm posting this here as this is actually a much better question than the related question you found.
I was banging my head against a wall trying to handle the same problem of getting the validation error to show up in the page. I'm using CakePHP v1.2 and I hit a similar problem although I have actually split out the HABTM into the individual tables i.e. Request->BrochuesRequest->Brochure. This is because I can't have it deleting and re-adding the joining table rows at will.
Firstly I think the accepted answer from your linked question assumes that you are doing a save / saveAll when the beforeValidate call is triggered, however I was doing it through a validates call. The difference is that you need to call the Request->set method first. It was an article by Jonathan Snook on Multiple Validation Sets pointed me to that issue.
The second issue is actually getting the error message to appear was down to the $field value you use when calling invalidate. For ages I was including the model as well as the field assuming that this was how it matched the invalidate call to the input, i.e. you have $form->input('BrochuresRequest.brochures_id') so you need $this->BrochuresRequest->invalidate('BrochuresRequest.brochures_id').
However that is wrong you just want $this->BrochuresRequest->invalidate('brochures_id').
<?php
// requests/add view
echo $form->input('BrochuresRequest.brochures_id', array('multiple' => true));
// requests_controller
function add() {
if (!empty($this->data)) {
$this->Request->create();
// critical set to have $this->data
// for beforeValidate when calling validates
$this->Request->set($this->data);
if ($this->Request->validates()) {
$this->Request->saveAll($this->data);
}
}
}
// request model
function beforeValidate() {
if (count($this->data['BrochuresRequest']['brochures_id']) < 1) {
$this->invalidate('non_existent_field'); // fake validation error on Project
// must be brochures_id and not BrochuresRequest.brochures_id
$this->BrochuresRequest->invalidate('brochures_id', 'Please select 1');
return false;
}
return true;
}
?>
A few of the other things that I picked up on the way through:
You don't need a separate $form->error in the view
I couldn't for the life of me get the 'multiple' validation rule to work in the model
The accepted answer checks for an isset but I believe that this isn't required and masked the problem of there being no $this->data being passed through.
The beforeValidate should return false if you want it to prevent any save action.
I have a page which returns results that are filtered on an organization_id. The URL looks like this:
nameofview/organization_id:1/page:2/
I'm using the built in Paginator controls and I pass $this->PassedArgs into it like this:
<div class="paging">
<?php echo $paginator->prev('<< '.__('previous', true), array('url' => $this->PassedArgs), null, array('class'=>'disabled'));?>
| <?php echo $paginator->numbers(array('url' => $this->passedArgs));?>
<?php echo $paginator->next(__('next', true).' >>', array('url' => $this->passedArgs), null, array('class'=>'disabled'));?>
</div>
The links look good for the "numbers" but don't work for Next and Previous. The links for both are taking me back to the same page. I think it is because it is passing the "Page" param.
Anyone have an idea how I can pass the correct args to $paginator->numbers?
I tried $this->passedArgs['organization_id'] but that returns errors.
Try this at the top of your view:
$paginator->options(array('url' => $this->passedArgs));
That way, you can drop array('url' => $this->passedArgs) from your prev/next/numbers lines, it should work just fine.