MaxCfasman
(Max Levinson)
November 29, 2010, 8:45pm
1
Hi Yiiers
I am using standard CListView widget to show all elements of ActiveRecord model:
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
)); ?>
Standard paging only shows one element per line. What if I want to customize paging, so at least three elements will be shown per line, in that case I will be able to show more elements on one page, it’s already implemented here:
http://www.yiiframework.com/extensions/?page=6&sort=comments.desc
Thanks for your help.
MaxCfasman
(Max Levinson)
November 29, 2010, 10:30pm
2
up in the air Quite keen to know how to do that, wasn’t able to find it in documentation.
tri
(tri - Tommy Riboe)
November 29, 2010, 10:58pm
3
There was a tip about this but I couldn’t find it today.
Anyway, I tried it
Select a customized css class for items instead of ‘items’
'itemsCssClass'=>'items-float',
CSS file (I use a copy of framework/zii/widgets/assets/listview/styles.css plus three image files needed by the CSS)
.list-view .items-float .view
{
width: 200px;
height: 200px;
float:left; /* <--- this will make the items float */
}
You might also need this to place the pager on it’s own line:
clear: both;
(not a CSS expert)
/Tommy
MaxCfasman
(Max Levinson)
November 30, 2010, 9:25am
4
tri:
There was a tip about this but I couldn’t find it today.
Anyway, I tried it
Select a customized css class for items instead of ‘items’
'itemsCssClass'=>'items-float',
CSS file (I use a copy of framework/zii/widgets/assets/listview/styles.css plus three image files needed by the CSS)
.list-view .items-float .view
{
width: 200px;
height: 200px;
float:left; /* <--- this will make the items float */
}
You might also need this to place the pager on it’s own line:
clear: both;
(not a CSS expert)
/Tommy
Hi Tommy,
Thanks for your CSS tip, but it looks like not CSS issue to me, I know how to position all elements to the left, it’s more like a pager issue. Look what I am after:
Let’s imagine I have 18 elements in CListView. If I am showing nine per page according to your css solution pagie will look like this:
element-1 element-2 element-3 element-4 element-5 element-6 element-7 element-8 element-9
But what I need is this:
element-1 element-2 element-3
element-4 element-5 element-6
element-7 element-8 element-9
This is exactly why I pointed out on this link with Yii extensions. It’s implemented there.
Thanks for your reply anyway.
zaccaria
(Matteo Falsitta)
November 30, 2010, 12:18pm
5
What max pointed out is exaclty what you need.
You have to create a div contaner for example of 610 pixel:
<div style="width: 600px;">
<... CListWiew ...>
<div style="clear:both;"></div>
</div>
This container will make so that the fourth div will not have place on the left and will authomatically go to new line.
Don’t forget a clear div after the list view.
MaxCfasman
(Max Levinson)
November 30, 2010, 1:27pm
6
zaccaria:
What max pointed out is exaclty what you need.
You have to create a div contaner for example of 610 pixel:
<div style="width: 600px;">
<... CListWiew ...>
</div>
This container will make so that the fourth div will not have place on the left and will authomatically go to new line.
Don’t forget a clear div after the list view.
I can understand how CSS part should work in this case, but I want to know how CListView will know where to put this <div style="clear:both;"></div>,because it should run through 3 elements and put this cler:both div, then run through another three elements and put this div again. Do you understand what I am saying?
Here is my code
Controller:
public function actionIndex()
{
$dataProvider=new CActiveDataProvider('model');
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
index.php View:
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'template'=>'{sorter}<br />{pager}{items}{pager}',
'enableSorting' => true,
'sortableAttributes'=>array(
'name'=>'By name',
),
)); ?>
CListView view file(_view.php) - representing each element
<div class="listing_container">
<span class="listing_profile_pic">
<img alt="<?=$data->name?>" class="img3" src="<?php echo Yii::app()->request->baseUrl; ?>/images/<?php echo $data->image_name; ?>" title="<?=$data->name?>" height="<?=$data->image_height?>" width="<?=$data->image_width?>">
</span>
<?php echo CHtml::link(CHtml::encode($data->name), array('view', 'id'=>$data->id),array('class'=>'listing_artist')); ?>
</div>
I can’t put <div class=“clear”> </div> into _view file because it represents each element and this clear div will be after each element. Any ideas?
zaccaria
(Matteo Falsitta)
November 30, 2010, 2:28pm
7
you don’t have to put each 3 elements, the magic of float will do the trick.
The idea is that You have an external div with fixed width, and this width is exactly 3 times the width of the inner div.
In your index php you should do something like:
<div style="width: 600px;">
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'template'=>'{sorter}<br />{pager}{items}{pager}',
'enableSorting' => true,
'sortableAttributes'=>array(
'name'=>'By name',
),
)); ?>
<div style="clear:both;"></div>
</div>
And in your view something like:
<div class="listing_container" style="width: 200px; float: left;">
<span class="listing_profile_pic">
<img alt="<?=$data->name?>" class="img3" src="<?php echo Yii::app()->request->baseUrl; ?>/images/<?php echo $data->image_name; ?>" title="<?=$data->name?>" height="<?=$data->image_height?>" width="<?=$data->image_width?>">
</span>
<?php echo CHtml::link(CHtml::encode($data->name), array('view', 'id'=>$data->id),array('class'=>'listing_artist')); ?>
</div>
That’s all.
You simply need:
A container 3 times bigger than the inner div
Each div with a fixed width
A clear both at the end
Try.
MaxCfasman
(Max Levinson)
November 30, 2010, 4:19pm
8
zaccaria:
you don’t have to put each 3 elements, the magic of float will do the trick.
The idea is that You have an external div with fixed width, and this width is exactly 3 times the width of the inner div.
In your index php you should do something like:
<div style="width: 600px;">
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'template'=>'{sorter}<br />{pager}{items}{pager}',
'enableSorting' => true,
'sortableAttributes'=>array(
'name'=>'By name',
),
)); ?>
<div style="clear:both;"></div>
</div>
And in your view something like:
<div class="listing_container" style="width: 200px; float: left;">
<span class="listing_profile_pic">
<img alt="<?=$data->name?>" class="img3" src="<?php echo Yii::app()->request->baseUrl; ?>/images/<?php echo $data->image_name; ?>" title="<?=$data->name?>" height="<?=$data->image_height?>" width="<?=$data->image_width?>">
</span>
<?php echo CHtml::link(CHtml::encode($data->name), array('view', 'id'=>$data->id),array('class'=>'listing_artist')); ?>
</div>
That’s all.
You simply need:
A container 3 times bigger than the inner div
Each div with a fixed width
A clear both at the end
Try.
Dude, it’s working, perefect, and I undersood the logic behind that, thank you for the explanation.
I was always saying that: Русские программисты лучшие в мире.
paejan
(Paejan)
September 20, 2011, 3:21pm
9
I already tried but the pager still join the list if it not full… actually i want to create thumbnail and what was happen is like this…
if my list: thumb1 thumb2 thumb3 thumb4
thumb5 thumb6 thumb7 thumb8
[pager appear here]
but if my list : thumb1 thumb2 thumb3 thumb4
thumb5 thumb6 [pager appear here]
this is my code :
<?php
$dataProvider = new CActiveDataProvider(Picture, array(
'criteria'=>array(
'condition'=>'ajaran_id='.$model->id,
'order'=>'id ASC',
),
'pagination'=>array(
'pageSize'=>12,
),
));
?>
<div style="width: 600px;">
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_picView',
));
?>
<div style="clear:both;"></div>
</div>
and this is my view :
<div style="width: 150px; float: left;">
<span>
<img alt="<?php echo $data->filename; ?>" src="<?php echo Yii::app()->baseUrl; ?>/images/gallery/ajaran/<?php echo $data->ajaran_id; ?>/tmb/t_<?php echo $data->filename; ?>" title="<?php echo $data->filename; ?>">
</span>
</div>
anything i left…? thanks in advance…
madand
(Dev Madand)
September 20, 2011, 3:56pm
10
Hi all,
some time ago i’ve solved similar issue by extending CListView class to build a table with needed number of columns.
My solution is old and not very elegant, but maybe it will be usfeul for you as example.
<?php
Yii::import('zii.widgets.CListView');
/**
* Extension for CListView for displaying items in table columns.
*
*/
class MColumnListView extends CListView {
/**
* @var integer number of columns to display items in.
*/
public $columns=2;
public $itemsTagName='table';
public $itemsCssClass='items-table';
public $emptyText='';
/**
* Renders the data item list.
*/
public function renderItems() {
echo CHtml::openTag($this->itemsTagName,array('class'=>$this->itemsCssClass, 'cellspacing'=>'0'))."\n";
$data=$this->dataProvider->getData();
if(($n=count($data))>0) {
$owner=$this->getOwner();
$render=$owner instanceof CController ? 'renderPartial' : 'render';
$cellWidth = floor(100 / $this->columns) . '%';
$j=0;
foreach($data as $i=>$item) {
//first item in row
if ( ($j % $this->columns) === 0 ) {
echo CHtml::openTag('tr');
}
$data=$this->viewData;
$data['index']=$i;
$data['data']=$item;
$data['widget']=$this;
echo CHtml::openTag('td', array('width'=>$cellWidth));
$owner->$render($this->itemView,$data);
echo CHtml::closeTag('td');
//last item in row
if( ($j % $this->columns) === ($this->columns-1) ) {
echo CHtml::closeTag('tr');
}
//last item in list
elseif ( $j === ($n-1) ) {
//output needed amount of empty td-tags
$columnsLast = $j % $this->columns + 1;
for ($z=$columnsLast; $z<$this->columns; $z++) {
echo CHtml::tag('td');
}
echo CHtml::closeTag('tr');
}
$j++;
}
}
else {
$this->renderEmptyText();
}
echo CHtml::closeTag($this->itemsTagName);
}
}
nights
(Ola Nordqvist)
December 12, 2011, 9:00am
11
Hm, looks like you took a very long and as you mentioned not very elegant way to achive the same thing just putting something like
<?php
$column_count = 2;
if( ($index % $column_count) == 0 && $index!=0)
{
echo '</tr><tr style="border: 0px">';
}
echo '<td style="border: 0px; width: '.floor(100.0/$column_count).'%">';
?>
in the listview page. This way you dont need to extend (break imp) the CListView class.
This works really well, however it would be nice to know how to pass a variable such as the column_count to the CListView.
does anyone know how to do this?
nights
(Ola Nordqvist)
December 12, 2011, 9:02am
12
nights:
Hm, looks like you took a very long and as you mentioned not very elegant way to achive the same thing just putting something like
<?php
$column_count = 2;
if( ($index % $column_count) == 0 && $index!=0)
{
echo '</tr><tr style="border: 0px">';
}
echo '<td style="border: 0px; width: '.floor(100.0/$column_count).'%">';
?>
in the listview page. This way you dont need to extend (break imp) the CListView class.
This works really well, however it would be nice to know how to pass a variable such as the column_count to the CListView.
does anyone know how to do this?
To answer my own question, seems like viewData can be used to pass additional arguments!