Yii - CListView - External Sorting Links and Pagination - php

I'm using 'CListView' in my View page. I need to sort the CListView by external links like 'A-Z' or 'Z-A'. These links are present above the list.
Here is the code in my View page -
$model = new Whisky();
$dataProvider = $model->dashboard_whisky_list();
$this->widget('zii.widgets.CListView', array(
'id'=>'whisky-grid',
'dataProvider'=>$dataProvider,
'itemView'=>'_whisky_list',
'template'=>'{pager}{items}{pager}',
'ajaxUpdate'=>true,
'beforeAjaxUpdate' => 'js:function(id) {showLoader();}',
'afterAjaxUpdate' => 'js:function(id, data) {hideLoader();}',
));
My view contains 2 more CListViews.
Is it possible to sort by this way ? Also my pagination is not working by Ajax.
Click Here to see the screenshot.
Please help.

Related

yii dataprovider pagination after post

I have a search form. I would like to pagination the result.
$criteria something like this:
if($_POST["tipus"] != 4){
$criteria->compare('t.tipus',$_POST["tipus"],true);
}
if($_POST["varos"] != 0){
$criteria->compare('`apartman`.`city`', $_POST["varos"], true);
}
if($_POST["ferohely"] != 0){
$criteria->compare('t.ferohely', $_POST["ferohely"], true);
}
My dataprovider:
$dataProvider= new CActiveDataProvider('UserAndApartman', array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'t.id DESC',
),
'pagination'=>array(
'pageSize'=>2,
),
));}
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'kereses_eredmenyek_view',
));
So if i click on the second page, the post doesn't come again. How can i post it automatic?Can i get the $dataprovider with pagination?
You're using $_POST, the $_POST['tipus'] and other data is lost when
you're navigating to the next page, since you're not posting it to
page 2, 3 etc. You can do two things:
Store the $_POST['tipus'] in a session, so the next page 'knows' what year it has to use.
Store it in the url as a $_GET parameter, so instead of $_POST['tipus'] use $_GET['tipus']. When you navigate to page 2, the $_GET['tipus'] is available in the url on the next page.
The last one is the easiest one i think, and that's how i usually use it.
IF you use the get method, change the CActiveForm line to this:
<?php $this->beginWidget('CActiveForm', array(
'id'=>'fromid',
'method' => 'get'
)); ?>

how to run yii widget when button clicked

I have this widget:
<?php
class Search extends CWidget
{
public $dataProvider = null;
public function init()
{
$criteria = new CDbCriteria();
if ( isset($_GET['file']) ) {
$criteria->compare('fileName', $_GET['file'], true, 'OR');
$criteria->compare('tags', $_GET['file'], true, 'OR');
}
$this->dataProvider = new CActiveDataProvider("Files", array(
'criteria' => $criteria,
//'countCriteria' => $criteria,
'pagination'=>array(
// results per page
'pageSize'=>1,
),
));
}
public function run(){
$this->render('site/result', array(
'dataProvider' => $this->dataProvider,
'pages' => $this->dataProvider->pagination,
));
}
}
?>
how I can run this widget only when the search button is clicked, and how to view its result in the view reuslt that is located in the folder site
Maybe I misunderstood you, but I think you have a little confusion about widget. Avoid making a
lengthy answer, I made a model in below
Question 1: How I can run this widget only when the search button is clicked?
The idea is that you put the widget content into hidden div, and then add a jQuery script to show it after the search button is clicked
<div id='search-result' style="display:none"><?php $this->widget(...) ?></div>
<script>
$('#search-button-id').click({
// do something
$('#search-result').show();
})</script>
Question 2: how to view its result in the view reuslt that is located in the folder site?
Imao, I recommend you don't do this. The widget is independant part, you can use it for many specific purposes & many locations of your project, so just put a simple view for widget to render in its own, instead of trying to render a view outside widget's scope. It should look like below
/your-app/protected/extensions/widgets/search/Search.php
/your-app/protected/extensions/widgets/search/views/result.php // view for rendering

Yii CGridView - Custom Columns

been looking for a solution to add a feature for "Custom Columns"... Meaning, I present a list of columns that I can show the user and he selects the ones he wants to see and after the selection the table is updated and add/removes the needed columns.
Didn't find anything on Google (perhaps it has a different name than what I was looking for...)
Anyone has an Idea on how it can be accomplished?
Thanks in advance!
This is not a complete sample, but can give you some clues on how to implement it. You've to define some kind of form to collect the data about how your grid has to be rendered. I recommend you to create a CFormModel class if there are more than 3 input fields. Create a view file with the form and a div or renderPartial of a file containing a grid:
$form = $this->beginWidget('CActiveFormExt');
echo $form->errorSummary($model);
echo $form->labelEx($model,'column1');
echo $form->dropDownList($model
echo $form->error($model,'column1');
echo CHtml::ajaxSubmitButton('UpdateGrid',array('controller/grid'),
array('update'=>'#grid'),
$this->endWidget();
// you can render the 'default options' before any ajax update
$this->renderPartial('_grid',array($customColumns=>array('id','name'),'dataProvider'=>$dataProvider));
In the _grid.php view file:
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'grid',
'dataProvider'=>$dataProvider,
'columns' => $customColumns;
));
In the controller:
function actionGrid(){
// recover the form data, and build the custom columns array
$customColumns = array();
$customColumns[] = '.....';
$dataProvider = ...;
$this->renderPartial('_formTrabajo', array('customColumns' => $idSiniestro, 'dataProvider' => $dataProvider'), false);
}
When you click the ajaxSubmitButton, the form is sent to the url specified through ajax, and the reply from the controller must contain the renderPartial of the view containing the grid, so the jQuery call can replace the html correctly. You must pass an array from your controller to the partial view of the grid, with the custom list of columns you want to display.

CJUIDialog doesnt work with CListView pager Controller

I have CListView and inside im redering a view that has a button, when clicked it opens a CJUIDialog.
But when i go through to the next page with the page controller. The CJUIDialog content loads to the page without clicking the button.
Any idea why it's coming like that?
It'll be great if anyone can help me out.
Thanks!
Ok, Yii generate the ids for lot of controls in an automatic way, so to avoid collision with events I recommend you to take out the interaction handling out of the item view in the following way:
In the page where the CListView is generated:
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_post', // refers to the partial view named '_post'
'sortableAttributes'=>array(
'title',
'create_time'=>'Post Time',
),
));
$this->beginWidget('zii.widgets.jui.CJuiDialog', array(
'id'=>'dialog',
'options'=>array(
'title'=>'Dialog',
'autoOpen'=>false,
),
));
$this->endWidget('zii.widgets.jui.CJuiDialog');
In the item view page:
echo CHtml::htmlButton('Button',array('onclick' => '$("#dialog").dialog("open");'));
In case you need to do something with the data row (like using the id property of that data), you can create a custom javascript function that will receive the data when the button is clicked.
echo CHtml::htmlButton('Button',array('onclick' => 'myFunction('.$data->id.')'));
And the previous example then would be:
<?php
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_post', // refers to the partial view named '_post'
'sortableAttributes'=>array(
'title',
'create_time'=>'Post Time',
),
));
$this->beginWidget('zii.widgets.jui.CJuiDialog', array(
'id'=>'dialog',
'options'=>array(
'title'=>'Dialog',
'autoOpen'=>false,
),
));
$this->endWidget('zii.widgets.jui.CJuiDialog');
?>
<script type="text/javascript">
function myFunction(id) {
// you can put whatever you need inside the dialog
$("#dialog").html(id);
// open the dialog
$("#dialog").dialog("open");
}
</script>

change CakePhp1.3 paginator destination url?

I'm new to cakephp...and I have a page with a url this:
http://localhost/books/filteredByAuthor/John-Doe
so the controller is ´books´, the action is ´filteredByAuthor´ and ´John-Doe´ is a parameter.. but the url looks ugly so i've added a Route like this:
Router::connect('/author/:name', array( 'controller' => 'books','action' => 'filteredByAuthor'), array('pass'=>array('name'),'name'=>".*"));
and now my link is:
http://localhost/author/John-Doe
the problem is that the view has a paginator and when i change the page (by clicking on the next or prev button).. the paginator won't consider my routing... and will change the url to this
http://localhost/books/filteredByAuthor/John-Doe/page:2
the code on my view is just:
<?php echo $this->Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
the documentation doesn't say anything about avoiding this and i've spent hours reading the paginators source code and api.. and in the end i just want my links to be something like this: (with the sort and direction included on the url)
http://localhost/author/John-Doe/1/name/asc
Is it possible to do that and how?
hate to answer my own question... but this might save some time to another developper =) (is all about getting good karma)
i found out that you can pass an "options" array to the paginator, and inside that array you can specify the url (an array of: controller, action and parameters) that the paginator will use to create the links.. so you have to write all the possible routes in the routes.php file. Basically there are 3 possibilities:
when the "page" is not defined
For example:
http://localhost/author/John-Doe
the paginator will assume that the it's the first page. The corresponding route would be:
Router::connect('/author/:name', array( 'controller' => 'books','action' => 'filteredByAuthor'),array('pass'=>array('name'),'name'=>'[a-zA-Z\-]+'));
when the "page" is defined
For example:
http://localhost/author/John-Doe/3 (page 3)
The route would be:
Router::connect('/author/:name/:page', array( 'controller' => 'books','action' => 'filteredByAuthor'),array('pass'=>array('name','page'),'name'=>'[a-zA-Z\-]+','page'=>'[0-9]+'));
finally when the page and the sort is defined on the url (by clicking on the sort links created by the paginator).
For example:
http://localhost/author/John-Doe/3/title/desc (John Doe's books ordered desc by title)
The route is:
Router::connect('/author/:name/:page/:sort/:direction', array( 'controller' => 'books','action' => 'filteredByAuthor'),
array('pass'=>array('name','page','sort','direction'),
'name'=>"[a-zA-Z\-]+",
'page'=>'[0-9]*',
'sort'=>'[a-zA-Z\.]+',
'direction'=>'[a-z]+',
));
on the view you have to unset the url created by the paginator, cause you'll specify your own url array on the controller:
Controller:
function filteredByAuthor($name = null,$page = null , $sort = null , $direction = null){
$option_url = array('controller'=>'books','action'=>'filteredByAuthor','name'=>$name);
if($sort){
$this->passedArgs['sort'] = $sort;
$options_url['sort'] = $sort;
}
if($direction){
$this->passedArgs['direction'] = $direction;
$options_url['direction'] = $direction;
}
Send the variable $options_url to the view using set()... so in the view you'll need to do this:
View:
unset($this->Paginator->options['url']);
echo $this->Paginator->prev(__('« Précédente', true), array('url'=>$options_url), null, array('class'=>'disabled'));
echo $this->Paginator->numbers(array('separator'=>'','url'=>$options_url));
echo $this->Paginator->next(__('Suivante »', true), array('url'=>$options_url), null, array('class' => 'disabled'));
Now, on the sort links you'll need to unset the variables 'sort' and 'direction'. We already used them to create the links on the paginator, but if we dont delete them, then the sort() function will use them... and we wont be able to sort =)
$options_sort = $options_url;
unset($options_sort['direction']);
unset($options_sort['sort']);
echo $this->Paginator->sort('Produit <span> </span>', 'title',array('escape'=>false,'url'=>$options_sort));
hope this helps =)

Categories