How Do You Display Content From Related Model In Tabs? Please Help!

Hello All!

I am having problems showing my data in my tabs. I don’t care what kind of tabs, i just want my relational data in tabs.

Im using the latest version of Yii 1.1.12

I have read a lot about it and just can’t seem to figure it out. People saying loop it in an array, put it in another file etc. I don’t know how to do that. I have tried it seems like everything except the right thing.

Alot of what i tried made everything throw errors because it involved altering the index view in my controller which messed everything else up. I am open to any option to get this to work. Also, a lot of the stuff was very old and outdated.

I wanted to put my items in clistview so i can alter the look as you can see what it looks like now from my attachment. However, I wanted to put my ‘products’ in the tab itself as well as other relational data in the other tabs using clistview. The attached screenshot it what it currently looks like and what i want it to look like.

3443

companies screenshot.png

Here is the code I am using.

Companies Model Relations:





	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'country' => array(self::BELONGS_TO, 'Country', 'country_id'),

			'companyTypes' => array(self::HAS_MANY, 'CompanyType', 'company_id'),

			'contacts' => array(self::HAS_MANY, 'Contacts', 'company_id'),

			'inventories' => array(self::HAS_MANY, 'Inventory', 'company_id'),

			'locations' => array(self::HAS_MANY, 'Locations', 'company_id'),

			'parts' => array(self::HAS_MANY, 'Parts', 'company_id'),

			'products' => array(self::HAS_MANY, 'Products', 'company_id'),

		);

	}

My Companies View File Where I need the tabs to display:




<?php $this->widget('zii.widgets.jui.CJuiTabs', array(

    'tabs'=>array(

    'Products'=>'Products should show here',

    'Points of Contact'=>'Points of contacts go here',

    'Contact Information'=>'contact information should go here',

    'Comments'=>'Content for tab 1',


     // 'AjaxTab'=>array('ajax'=>$ajaxUrl),

    ),

    // additional javascript options for the tabs plugin

    'options'=>array(

    'collapsible'=>true,

    ),

    'htmlOptions'=>array(

        'style'=>'min-height:400px;'

	),

    ));


//product gallery calls products.  'model' is the 'name' field in my product model.


$config = array('keyField' => 'company_id');

$dataProvider = new CArrayDataProvider($rawData=$model->products, $config);


$this->widget('zii.widgets.CListView', array(

         'dataProvider'=>$dataProvider,

	'template'=>'{sorter}{pager}{items}<br/>{pager}',

        'itemView'=>'productgallery',

		'sortableAttributes'=>array(

			'model',

		),

)); ?>



productgallery file that displays the product ‘gallery’ . it’s just css based.


<div class="productimg">

    <?php echo CHtml::link('<img src="../'.$data->getAttachment('thumb').'" />', array("products/view", "id"=>$data->product_id)); ?><br>

    <div class="productimgdesc">

        <h5>

        <?php echo CHtml::link(CHtml::encode($data->model),array("products/view","id"=>$data->product_id)); ?>

        </h5>

    </div>

</div>

My controller is all default gii.

Index File




<h1>Companies</h1>


<div>

<?php $this->widget('zii.widgets.CListView', array(

        'dataProvider'=>$model->search(),

	'template'=>'{sorter}{pager}{items}<br/>{pager}',

        'itemView'=>'companygallery',

		'sortableAttributes'=>array(

			'name',

		),

)); ?>

</div>



My Product Model Relations portion




	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'parts' => array(self::HAS_MANY, 'Parts', 'product_id'),

			'productCategories' => array(self::HAS_MANY, 'ProductCategories', 'product_id'),

			'company' => array(self::BELONGS_TO, 'Companies', 'company_id'),

 

		);

	}



Product controller is also default gii.

This is my actual database setup.




CREATE TABLE IF NOT EXISTS `products` (

  `product_id` int(11) NOT NULL AUTO_INCREMENT,

  `company_id` int(11) NOT NULL,

  `model` varchar(30) NOT NULL,

  `active_status` int(11) NOT NULL,

  `filename` text,

  PRIMARY KEY (`product_id`),

  UNIQUE KEY `company_id` (`company_id`,`model`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=17 ;




CREATE TABLE IF NOT EXISTS `companies` (

  `filename` text,

  `company_id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(25) NOT NULL,

  `website` varchar(30) DEFAULT NULL,

  `address` varchar(50) DEFAULT NULL,

  `city` varchar(25) DEFAULT NULL,

  `us_state` varchar(25) DEFAULT NULL,

  `zip` int(10) DEFAULT NULL,

  `country` int(3) DEFAULT NULL,

  PRIMARY KEY (`company_id`),

  UNIQUE KEY `name` (`name`),

  KEY `companies` (`country`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=18 ;


ALTER TABLE `products`

  ADD CONSTRAINT `products_ibfk_2` FOREIGN KEY (`company_id`) REFERENCES `companies` (`company_id`) ON DELETE NO ACTION ON UPDATE CASCADE;




I don’t know what else someone would need to help me. I tried to list it all.

See the reference of CTabView.

You can use the property ‘content’ to display a content string or the properties ‘view’ and ‘data’ to do a renderPartial.

So you have 2 solutions:

  1. move the products CListView into a view ‘productgallery’




 $config = array('keyField' => 'company_id');

 $dataProvider = new CArrayDataProvider($rawData=$model->products, $config); 


 $this->widget('zii.widgets.jui.CJuiTabs', array(

    'tabs'=>array(

    'Products'=>array(

                   'title'=>'Products should show here',

                   'view'=>'productgallery',

                   'data'=>array('dataProvider'=>$dataProvider))




  1. use ob_start to catch the output of the productgallery




 $config = array('keyField' => 'company_id');

 $dataProvider = new CArrayDataProvider($rawData=$model->products, $config); 


 ob_start();

$this->widget('zii.widgets.CListView', array(

         'dataProvider'=>$dataProvider,

        'template'=>'{sorter}{pager}{items}<br/>{pager}',

        'itemView'=>'productgallery',

                'sortableAttributes'=>array(

                        'model',

                ),

));

$products = ob_get_clean();


 $this->widget('zii.widgets.jui.CJuiTabs', array(

    'tabs'=>array(

    'Products'=>array(

                   'title'=>'Products should show here',

                   'content'=>$products)




Is there a reason to use one method over the other? Or is one way more proper than the other? Thank you for your reply too.

I would prefer the 1. solution with the view/data properties.

  • keeps the code of the company view cleaner with a reduced size

  • you can reuse the ‘productgallery’ view in another controller action without tabs

maybe you should submit the $model variable to the view and not the $dataProvider and generate the dataProvider in the ‘productgallery’ view

Thanks again. However could you elaborate more on how to accomplish this (1 st option)? I tried what you said (1) and couldn’t get it to work :(. However, the second i got to work. I’d rather do it the right way then some hack. It’s not like I’m just doing this in one place. I have to repeat this almost 20 times for all of my tables and do want to hack my code all up.

i.e. i have product specs that gets called from product_specs table and product_capabilities that get called from that table etc. They all need to be in the same tab set as the products.

Could you please put an example of how to set up the controller action to show the productgallery.

And why it doesn’t work?

Companies view





$this->widget('CTabView', array(

    'tabs'=>array(

        'Products'=>array(

            'title'=>'Products',

            'view'=>'companyproducts',

            'data'=>array('model'=>$model),

        ),

    ),

))




View ‘companyproducts’





 $dataProvider = new CArrayDataProvider($model->products, array('keyField' => 'company_id')); 


 $this->widget('zii.widgets.CListView', array(

         'dataProvider'=>$dataProvider,

         'itemView'=>'productgallery',

));




But maybe you have issues with ajax inside the tabs: pagination, sorting…

Google for: Yii CTabView CListView

You will find some topics.




$this->widget('zii.widgets.jui.CJuiTabs', array(

    'tabs'=>array(

      'tab1'=>array('id' => 'tab1', 'content' => $this->renderPartial('view', $data, true)),

      'tab2'=>array('id' => 'tab2', 'content' => 'just text'), 

    )

);




Hi.

Check this wiki CJuiTabs