I have an application that takes a value from a dropdown list and uses it to filter an index view. Here is the controller code for that:
public function browse() {
$this->loadModel('ReqMissionId');
$missions = $this->ReqMissionId->find('list', array('fields' => array('mission_id', 'mission_id')));
$this->set(compact('missions'));
}
This is the Controller code for the index:
public function index() {
if($this->request->is('post')) {
$options = array('Requirement.mission_id' => $this->request->data['Requirement']['mission_id']);
$this->set('mission_id', $this->request->data['Requirement']['mission_id']); //Used to display the mission_id on the index page.
$this->Paginator->settings = $this->paginate;
$this->set('requirements', $this->Paginator->paginate('Requirement', $options));
}
}
The dropdown in the View is simple:
<?php
echo $this->Form->input('mission_id', array('label' => 'Mission ID'));
echo $this->Form->submit(__('View'));
echo $this->Form->end();
?>
My problem is pagination. Since Cake does a postback when it sorts the columns, the value of 'Requirement.mission_id' gets lost and I get a "Call to member function sort() on null" error. I feel like I can take care of this with a session variable, but I'm unclear on the implementation. Is that correct, or is there something else I should be doing?
Check the session for the model that you're paginating. Try something like this:
Try something like this:
if(!empty($this->request->data['Requirement']))
$this->Session->write('Requirement', $this->request->data['Requirement']);
else
$this->request->data['Requirement'] = $this->Session->read('Requirement');
To get it into your $options. Try use array merge like this:
$options = array_merge($options, $this->getOptions($this->request->data));
Implement getOptions under:
function getOptions($data = null){
$options = array();
if(!empty($data['Requirement']['mission_id']))
$options = array_merge($options, array('mission_id' => $data['Requirement']['mission_id']));
return $options;
}
Related
I need to use the function in my view/template page.
My code:
public function getAppNumber($id = null){
$aPPLICATIONINFO = $this->AppEstLto->APPLICATIONINFO->find('all', [
'fields'=>['application_number'],
'conditions'=>['application_id'=>$id],
'limit' => 200
]);
foreach($aPPLICATIONINFO as $aPPLICATIONINFO){
$aPPLICATIONINFOx = $aPPLICATIONINFO;
}
return $aPPLICATIONINFOx;
}
You can use set() to use the function variables in your view as given in cookbook:https://book.cakephp.org/3/en/views.html#setting-view-variables
public function get_app_number($id = null){
$applicationInfo = $this->AppEstLto->APPLICATIONINFO->find('all',
[
'fields'=>['application_number'],
'conditions'=>['application_id'=>$id],
'limit' => 200
]);
//Create an array
$applicationArray = new array();
//Store all results in array
foreach($applicationInfo as $application){
$applicationArray = $application;
}
// Pass the array to view
$this->set(compact('applicationArray'));
}
Now, you can use it in your view:
get_app_number.ctp:
<?php
foreach($applicationArray as $application)
{
echo $application['application_number'];
}
?>
You should be doing something like this in your routes.php file inside your Config folder:
Router::connect('/get-app-number', array('controller' => 'yourController', 'action' => 'get_app_number'));
That way you will be able to connect the url that will be used for your view.
Your action corresponds and sends data to your view.
The action is the function that is inside your controller in which you developed for setting the data and variables.
The example of the slug which would be generated:
http://localhost/get-app-number
I am using cake php scroll pagination to paging products.
I am using group of check boxes in view part to set manual condition by user to paginate.
I used following code to set a condition after ajax request.
class SearchController extends AppController {
public $helpers = array('Html', 'Form', 'Session','Paginator','Js' => 'Jquery');
public $components = array('RequestHandler','Session','Cookie','Paginator');
public function index() {
$this->loadModel("Bangsworkinghrs");
$agetworkinghrs = $this->Bangsworkinghrs->getworkinghrs();
$this->set('agetworkinghrs', $agetworkinghrs);
$this->loadModel("Gig");
$options = array('Gig.subcategory' => 'Logo Design');
if(!empty($this->request->data['filter']['workinghrs'])) {
$options = array('Gig.subcategory' => 'Logo');
}
$this->Paginator->settings = $options;
$agetGigsItem = $this->Paginator->paginate('Gig', $options);
$this->set('agetGigsItem', $agetGigsItem);
}
}
via this code i am able to change condition of paging but server explodes only default 20 records next records is not exploding by server and there is no error message my cakephp version is 2.6.8
$('#filter').submit(); try submit form and remove ajax refresh data from your jquery part replace filter with your form name.
You are missing 'page' and 'limit' attribute of Cakephp default pagination.
In your options array you need to pass page number and no of records per page.
Something like this but in dynamic way.
$options = array('conditions' => array('Gig.subcategory' => 'Logo Design'),'page'=>2,'limit'=>20);
using action="get" in the form where $this->request->query['filter']['workinghrs'] data is come.
Coding:
public $paginate = array(
'limit' => 20
);
public function index()
{
$this->loadModel("Gig");
$options = array('Gig.subcategory' => 'Logo Design');
if(!empty($this->request->query['filter']['workinghrs'])) {
$options = array('Gig.subcategory' => 'Vector Design');
}
$this->Paginator->settings = $options;
$agetGigsItem = $this->Paginator->paginate('Gig', $options);
$this->set('agetGigsItem', $agetGigsItem);
}
I'm using a custom datasource to consume webservice.
Create, Read and Update work well but Delete doesn't works.
Here is my code calling the delete method in my controller.
public function delete($id){
$this->autoRender = false;
debug($this->Article->delete($id));
}
And here the code in my datasource
public function delete(Model $Model, $id = null) {
echo "Display a message if this method is called";
$json = $this->Http->post(CakeSession::read('Site.url') . '/webservice/delete/', array(
'id' => $id,
'apiKey' => $this->config['apiKey'],
'model' => $Model->name
));
$res = json_decode($json, true);
if (is_null($res)) {
$error = json_last_error();
throw new CakeException($error);
}
return true;
}
But when I want to delete an item, the debug(); display false.
I have no other displays.
I don't understand why my delete method isn't called correctly.
Is there something wrong in my code ?
Thanks
Let's check: you're only passing a parameter to your method:
$this->Article->delete($id)
According to the method that you created, the first parameter, which is required, is the Model. The second is $id:
public function delete(Model $Model, $id = null)
During the method you want to use both parameters. Here:
'id' => $id
And here:
'model' => $Model->name
Based on this, you need to review how this method will be called. BTW, if you want override delete() method, according the book, you need something like this: delete(int $id = null, boolean $cascade = true).
Our Yii Framework application has the following defined as part of the UserProfileImages model:
public function getProfileImages($param, $user_id) {
if(isset($param['select']) && $param['select']=='all'){
$profile_images = UserProfileImages::model()->findAllByAttributes( array( 'user_id'=>$user_id) );
} else {
$profile_images = UserProfileImages::model()->findByAttributes( array( 'user_id'=>$user_id) );
}
return $profile_images;
}
How would I wire up the above snippet to a widget in my view to return all the images for a given user?
Bonus Question: Which image rotator do you suggest to render the above?
In your view file, add something like this, assuming that your controller specified $user_id:
$this->widget('UserProfileImagesWidget', array(
"userProfileImages" => UserProfileImages::getProfileImages(
array("select" => "all"),
$user_id
),
"user_id" => $user_id
));
Depending on your MVC philosophy, you could also retrieve the userProfileImages data in the controller and pass that data to your view.
Define a widget like this:
class UserProfileImagesWidget extends CWidget {
public $user_id;
public $userProfileImages = array();
public function run() {
$this->render("userProfileImage");
}
}
Finally, in the userProfileImages.php view file, you can do something like this:
if(!empty($this->userProfileImages)) {
// Your display magic
// You can access $this->user_id
}
As a side note: You might want to change the order of your parameters in getProfileImages. If $user_id is the first parameter, you can leave out $params completely in case you don't want to specify any.
I'm setting up pagination to display a list of images belonging to the user in their account. This is what I have in my controller:
class UsersController extends AppController {
public $paginate = array(
'limit' => 5,
'order' => array(
'Image.uploaded' => 'DESC'
)
);
// ...
public function images() {
$this->set('title_for_layout', 'Your images');
$albums = $this->Album->find('all', array(
'conditions' => array('Album.user_id' => $this->Auth->user('id'))
));
$this->set('albums', $albums);
// Grab the users images
$options['userID'] = $this->Auth->user('id');
$images = $this->paginate('Image');
$this->set('images', $images);
}
// ...
}
It works, but before I implemented this pagination I had a custom method in my Image model to grab the users images. Here it is:
public function getImages($options) {
$params = array('conditions' => array());
// Specific user
if (!empty($options['userID'])) {
array_push($params['conditions'], array('Image.user_id' => $options['userID']));
}
// Specific album
if (!empty($options['albumHash'])) {
array_push($params['conditions'], array('Album.hash' => $options['albumHash']));
}
// Order of images
$params['order'] = 'Image.uploaded DESC';
if (!empty($options['order'])) {
$params['order'] = $options['order'];
}
return $this->find('all', $params);
}
Is there a way I can use this getImages() method instead of the default paginate()? The closest thing I can find in the documentation is "Custom Query Pagination" but I don't want to write my own queries, I just want to use the getImages() method. Hopefully I can do that.
Cheers.
Yes.
//controller
$opts['userID'] = $this->Auth->user('id');
$opts['paginate'] = true;
$paginateOpts = $this->Image->getImages($opts);
$this->paginate = $paginateOpts;
$images = $this->paginate('Image');
//model
if(!empty($opts['paginate'])) {
return $params;
} else {
return $this->find('all', $params);
}
Explanation:
Basically, you just add another parameter (I usually just call it "paginate"), and if it's true in the model, instead of passing back the results of the find, you pass back your dynamically created parameters - which you then use to do the paginate in the controller.
This lets you continue to keep all your model/database logic within the model, and just utilize the controller to do the pagination after the model builds all the complicated parameters based on the options you send it.