form with multiple relations

I’m new to Yii and in trouble with relations and a special view for editing and creating.

My entities:

customer(id,…)

profile(id,customer_id,…)

device(id,customer_id,profile_id,…)

app(id,…)

device_app(device_id,app_id)

profile_app(profile_id,app_id)

app_label(id,app_id,…)

My relations:

Customer:

devices => array(self::HAS_MANY, Device, customer_id),

profiles => array(self::HAS_MANY, Profile, customer_id),

Profile:

devices => array(self::HAS_MANY, Device, profile_id),

customer => array(self::BELONGS_TO, Customer, customer_id),

Device:

customer => array(self::BELONGS_TO, Customer, customer_id),

profile => array(self::BELONGS_TO, Profile, profile_id),

apps => array(self::MANY_MANY, App, profile_app(profile_id, app_id)),

App:

appLabels => array(self::HAS_MANY, AppLabel, app_id),

devices => array(self::MANY_MANY, ‘Device’, device_app(app_id, device_id)),

profiles => array(self::MANY_MANY, Profile, profile_app(app_id, profile_id)),

DeviceApp:

no relations

ProfileApp:

no relations

AppLabel:

app => array(self::BELONGS_TO, App, app_id),

I can create/edit customers, devices so far. But now i have a problem: when creating a profile it should be possible to associate apps to it. I tried to solve this with CActiveForm and a checkBoxList and ran in two major problems. On the one hand is such a list not very usefull, because there are about hundreds of apps in this list and on the other hand i didn’t ‘find’ the right code for checked oder unchecked boxes. Code from this(_form in profile):

$form->checkBoxList($model,‘id’, CHtml::listData(App::model()->findAll(array(‘order’=>‘package_name’)), ‘id’,‘package_name’),array(‘multiple’=>‘multiple’,‘template’=>’<li>{input} {label}</li>’,‘labelOptions’=>array(‘style’=>‘display:inline’),))

This will compare the id of apps with id of profile… :frowning:

I think about a better way to make a view with CGridView, where you can see all active apps first and afterwards all other apps with checkboxes and a routine to save them.

Any ideas or advices much appreciated!

Dear friend,

I am not able to comprehend the exact problem you are facing.

Here I am setting a scenario.

Kindly check whether it suits you.

Take the blog example.

There are number of comments remain unapproved.

I want all the unapproved comments listed in a page along with title of the post,content of comment, name and email of person who made the comment.There is also radiobutton to check for making the comment approved.

CommentController.php




public function actionApproval() 

{       

        //status1=unapproved; status2=approved


	$dataProvider=new CActiveDataProvider('Comment',array(

			'criteria'=>array(

			'condition'=>'status=1',

                        'order'=>'create_time DESC',

                     )));

	

	if(!isset($_POST['status']))

	{   $this->render('approval',array(

			'dataProvider'=>$dataProvider,

			));

	}

	

	if(isset($_POST['status'])) 

	{

		foreach($_POST['status'] as $i=>$j) 

		{

			if($j==1) //boolean selected from radiobutton

			{

				$model=$this->loadModel($i);

				$model->status=2;

				$model->update();

			}

		}

		$this->redirect(array('comment/index'));

	}

		

}



This is approval.php utilising the power of CListView.




<?php

$this->breadcrumbs=array(

	'Manage Comments',

);


$this->menu=array(

	array('label'=>'Create Comment', 'url'=>array('create')),

	array('label'=>'Manage Comment', 'url'=>array('admin')),

);

?>


<h1>Comments</h1>

<?php if(count($dataProvider->getData())>0) {?>

<h1>Comments Not Approved</h1>

<?php } else echo "<div class=\"flash-success\"><h4>All the comments are approved</h4></div>"; ?>


<div class="form">

<?php echo CHtml::beginForm(); ?>


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

	'dataProvider'=>$dataProvider,

	'itemView'=>'_approval',

)); ?>


<?php if(count($dataProvider->getData())>0) echo CHtml::submitButton('Save'); ?>

<?php echo CHtml::endForm(); ?>

</div>



This is _approval.php to dispaly the form.




<div class="view">

<div style="float:right;">

<?php echo CHtml::encode('approve');?>

<?php echo CHtml::checkBox("status[$data->id]",false,array('separator'=>'')); ?>

</div>


<b><?php echo CHtml::encode($data->getAttributeLabel('author')); ?>:</b>

<?php echo CHtml::encode($data->author); ?>

<br />


<b><?php echo CHtml::encode($data->getAttributeLabel('email')); ?>:</b>

<?php echo CHtml::encode($data->email); ?>

<br />


<b><?php echo CHtml::encode($data->getAttributeLabel('content')); ?>:</b>

<?php echo CHtml::encode($data->content); ?>

<br />


<b><?php echo CHtml::encode($data->getAttributeLabel('post.title')); ?>:</b>

<?php echo CHtml::encode($data->post->title); ?>

<br />

</div>



In a similar manner I can manage posts by using radiobutton list classifying them into draft,published or archived.

If you have a select box list or checkbox list with LOTS of choices it makes more sense to use one of the jquery multiselects people have built. They usually have a built-in filter.

You can also try ‘multicomplete’ which is an autocomplete extension that lets you save multiple instances.