CListView widget YII formatting

756 Views Asked by At

I know this could be a silly question.. but I am trying to align the filter and the CListView widget to show it appropriately as below

Here is the code

<div class="row-fluid span12">
 <div class="span4">

<?php $box = $this->beginWidget(
    'bootstrap.widgets.TbBox',
    array(
        'title' => 'Advanced Search',
        'headerIcon' => 'icon-th-list',
        'htmlOptions' => array('class' => 'bootstrap-widget-table')
        )
    );?>
<?php $this->renderPartial('_search',array('model'=>$model,)); ?>

<?php $this->endWidget(); ?>

</div>
<div class="span8">
     <?php 
        $this->widget('zii.widgets.CListView', 
                array(
                      'dataProvider'=>$model->search(),
                      'ajaxUpdate' => true,
                      'enablePagination'=>true,

                      'itemView'=>'_list',   // refers to the partial view named '_post'
                      'sortableAttributes'=>array(
                                                  'Price',
                                                  'Year',
                                                  'Lenght'
                                                  ),

                      )

                    );
               ?>

</div>
</div>

which actually generates something like left side of the attached picture

enter image description here

How can I make sure that the CListView widget is aligned within the filter? And get rid of the text "Displaying 1-29 results" and align the filters on the top?

2

There are 2 best solutions below

2
On

My solution is a bit longer but bear with me.

The default layout for CListItem is as follows:

<div>{pager}</div>
<div>{summary}</div>
<div class='items'>{item1}{item2}...{item_n}</div>

To achieve your desired layout, you need to somehow insert the filter in the container i.e. the .items div. This can be done in several ways.

  1. You can overwrite the ListView class to add a variable beforeItems whose content will be placed in the item container but before the first item. e.g

    <?php
    
    Yii::import('zii.widgets.CListView');
    
    class MyListView extends CListView {
    
    public $beforeItems = '';
    
        public function renderItems()
        {
            echo CHtml::openTag($this->itemsTagName,array('class'=>$this->itemsCssClass))."\n";
            $data=$this->dataProvider->getData();
            if(($n=count($data))>0)
            {
                echo $this->beforeItems;
                $owner=$this->getOwner();
                $viewFile=$owner->getViewFile($this->itemView);
                $j=0;
                foreach($data as $i=>$item)
                {
                    $data=$this->viewData;
                    $data['index']=$i;
                    $data['data']=$item;
                    $data['widget']=$this;
                    $owner->renderFile($viewFile,$data);
                    if($j++ < $n-1)
                        echo $this->separator;
                }
            }
            else
                $this->renderEmptyText();
            echo CHtml::closeTag($this->itemsTagName);
        }
    
    }
    

    You can then call your list view as:

    $this->widget('path.to.MyListView, array(
        ...
        'beforeSend' => '<filter html here>',
    
  2. However, to ensure that your listview looks as in the image, you will need to extend the listview to remove some the rendering of the opening and closing container tag commented out in the example below.

    Yii::import('zii.widgets.CListView');
    
    class MyListView extends CListView {
    
        public function renderItems()
        {
            // echo CHtml::openTag($this->itemsTagName,array('class'=>$this->itemsCssClass))."\n";
            $data=$this->dataProvider->getData();
            if(($n=count($data))>0)
            {
                $owner=$this->getOwner();
                $viewFile=$owner->getViewFile($this->itemView);
                $j=0;
                foreach($data as $i=>$item)
                {
                    $data=$this->viewData;
                    $data['index']=$i;
                    $data['data']=$item;
                    $data['widget']=$this;
                    $owner->renderFile($viewFile,$data);
                    if($j++ < $n-1)
                        echo $this->separator;
                }
            }
            else
                $this->renderEmptyText();
            // echo CHtml::closeTag($this->itemsTagName);
        }
    
    }
    

You can then edit template to remove the summary and pager that appear before the items:

`template` => `<div><your_filter_html>{items}</div>`

The template is used to control the layout of various components in the list view. These tokens are recognized: {summary}, {sorter}, {items} and {pager}. They will be replaced with the summary text, the sort links, the data item list, and the pager.

2
On

Divs are block elements, so you've two <div class="span4"> and <div class="span8"> kind of blocking against one another.

What if you drop the bootstrap layout, make filters in div floating left and put it inside div of CListView?

<div class="row-fluid span12">
  <div style="float:left;">
   ... filters
  </div > 
    ... 
    $this->widget('zii.widgets.CListView',
    ... 
</div><!-- span12 -->

Update

From the site you've mentioned:

the floating div

the upper container