Yii - One to many update form - php

I have a one to many relationship where a movie can have many youtubeclips.. Ive managed to create the models and display the movie data inside the update form. I now need to be able to create a loop of some sort to out put my many relationship data into the form.. But cant seem to figure out how to do it.. This is what I have so far..
MovieController --
public function actionUpdate($id)
{
$model=$this->loadModel($id);
$modelYoutubeVideo=$this->loadYoutubeVideoModel($id);
$modelTwitterFeed=$this->loadTwitterModel($id);
if(isset($_POST['Movie']))
{
$model->attributes=$_POST['Movie'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('update',array(
'model'=>$model,
'modelYoutubeVideo'=>$modelYoutubeVideo,
'modelTwitterFeed'=> $modelTwitterFeed
));
}
Update Form --
<div class="row clone">
<?php echo $form->labelEx($modelYoutubeVideo,'embed_code'); ?>
<?php echo $form->textField($modelYoutubeVideo,'embed_code[]',array('size'=>50,'maxlength'=>50)); ?>
<?php echo $form->error($modelYoutubeVideo,'embed_code'); ?>
<?php echo $form->labelEx($modelYoutubeVideo,'description'); ?>
<?php echo $form->textField($modelYoutubeVideo,'description[]',array('size'=>50,'maxlength'=>250)); ?>
<?php echo $form->error($modelYoutubeVideo,'description'); ?>
</div>
<?php
$this->widget('ext.widgets.reCopy.ReCopyWidget', array(
'targetClass'=>'clone',
));
?>
Need to Create a loop which outputs my data from the many relations ship table --
<?php
for ($i = 0; $i < count($modelYoutubeVideo); ++$i) {
($modelYoutubeVideo->embed_code[i]);
($modelYoutubeVideo->embed_code[i]);
}
?>
Movie Relationships --
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(
'competitions' => array(self::HAS_MANY, 'Competition', 'movie_id'),
'studio' => array(self::BELONGS_TO, 'Studio', 'studio_id'),
'country' => array(self::BELONGS_TO, 'Country', 'country_id'),
'movieRating' => array(self::BELONGS_TO, 'MovieRating', 'movie_rating_id'),
'mapPin' => array(self::BELONGS_TO, 'MapPin', 'map_pin_id'),
'twitterFeeds' => array(self::HAS_MANY, 'TwitterFeed', 'movie_id'),
'YoutubeVideo' => array(self::HAS_MANY, 'YoutubeVideo', 'movie_id'),
);
}

in your actionUpdate you can use use relation like this
$model=$this->loadModel($id);
$youTubevideos=$model->YoutubeVideo;
Here YouTubeVideo is the same relation name in your model.It will bring you all the youtubeVideo active records related to specific movie. Now pass this array to your view like
$this->render('update',array(
'model'=>$model,
'modelYoutubeVideo'=>$modelYoutubeVideo,
'modelTwitterFeed'=> $modelTwitterFeed,
'youTubeVideos'=>$youTubeVideos,
));
then in your view use foreach loop to show each value of the model like
foreach($youTubeVideos as $video)
{
echo $video->name;
}
In above echo statement actually you can echo any thing like CdetailView widget or anything you want repeatedly.

Related

Yii. Application form. Adding info about user company + SEVERAL goods in one form

Don't know, if it is a typical problem, but can't figure how to realise it.
3 tables:
Application. It's relations:
return array(
'company_info' => array(self::HAS_ONE, 'AppCompany', 'applicant_id'),
'region'=>array(
self::HAS_ONE,'AppRegion',array('company_region_id'=>'id'),
'through'=>'company_info'
),
'sector'=>array(
self::HAS_ONE,'AppSector',array('company_sector_id'=>'id'),
'through'=>'company_info'
),
);
AppCompany. Relations:
return array(
'application' => array(self::BELONGS_TO, 'Application', 'applicant_id'),
'region' => array(self::BELONGS_TO, 'AppRegion', 'company_region_id'),
'sector' => array(self::BELONGS_TO, 'AppSector', 'company_sector_id'),
'goodsservices' => array(self::HAS_MANY, 'AppGoodsServices', 'company_id')
);
App.GoodsServices. Relations:
return array(
'company'=>array(self::BELONGS_TO, 'AppCompany', 'company_id'),
);
So, one user adds info about his company (company_name, date_of_registration etc), and than add some goods/services that this company produces. How to COLLECT, UPDATE AND VIEW all this information in one form? Is it possible?
How do I see this:
User addes some info and meets the field: "Goods and services and their percentage" and two fields - "GOODS AND SERVICES" and "PERCENTAGE" and ADD MORE button and he has 6 goods that he wants to add. So, he clicks on ADD MORE button and each time the new fields below appear. But the goods limit is 5, so the button becomes inactive after 5 fields have info.
And after SUBMIT button, all this info records to its table. It can be taken from table on UPDATE button and can be viewd in one CDetailView.
Please, how it can be implemented at least in general terms. Thank you
UPDATE
Ok, some work is done (don't know if it right, but...):
I used this extension: http://www.yiiframework.com/extension/esaverelatedbehavior/
Now I have:
public function actionCreate()
{
$model=new Application;
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if(isset($_POST['Application']))
{
$model->attributes=$_POST['Application'];
if(isset($_POST['AppGoodsServices']))
{
$model->goodsservices = $_POST['AppGoodsServices'];
}
if ($model->saveWithRelated('goodsservices'))
{
$this->redirect(array('view', 'id' => $model->id));
} else {$model->addError('goodsservices', 'Error occured while saving goods/services.'); }
}
$this->render('create',array(
'model'=>$model,
));
}
public function actionUpdate($id)
{
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Application']))
{
$model->attributes=$_POST['Application'];
if(isset($_POST['AppGoodsServices']))
{
$model->goodsservices = $_POST['AppGoodsServices'];
}
if ($model->saveWithRelated('goodsservices'))
{
$this->redirect(array('view', 'id' => $model->id));
} else {$model->addError('goodsservices', 'Error occured while saving goods/services.'); }
}
$this->render('update',array(
'model'=>$model,
));
}
public function loadModel($id)
{
$model=Application::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
In my _form.php
<div id="goodsservices">
<?php
$index = 0;
foreach ($model->goodsservices as $id => $goods):
$this->renderPartial('goods/_form', array(
'model' => $goods,
'index' => $id,
));
$index++;
endforeach;
?>
</div>
and subform in goods/_form:
<div style="margin-bottom: 20px; width:100%; clear:left;" class="crow">
<div class="row" style="float: left;">
<?php echo CHtml::activeLabelEx($model, '['.$index.']goods_and_services'); ?>
<?php echo CHtml::activeTextField($model, '['.$index.']goods_and_services', array('size' => 30, 'maxlength' => 150)); ?>
<?php echo CHtml::error($model, '['.$index .']goods_and_services'); ?>
</div>
<div class="row" style="float: left;">
<?php echo CHtml::activeLabelEx($model, '['.$index .']percentage'); ?>
<?php echo CHtml::activeTextField($model, '['.$index.']percentage', array('size' => 5)); ?>
<?php echo CHtml::error($model, '['.$index.']percentage'); ?>
</div>
<div class="row" style="float: left;">
<?php echo CHtml::link('Delete', '#', array('onclick' => 'deleteGoods(this, '.$index.'); return false;'));
?>
</div>
</div>
<div style="clear: both;"></div>
<?php
Yii::app()->clientScript->registerScript('deleteGoods', "
function deleteGoods(elm, index)
{
element=$(elm).parent().parent();
/* animate div */
$(element).animate(
{
opacity: 0.25,
left: '+=50',
height: 'toggle'
}, 500,
function() {
/* remove div */
$(element).remove();
});
}", CClientScript::POS_END);
?>
Everything works, but I cant understand how to make a batch CREATE for children (goodsservices) model. Now it only shows me children in UPDATE form (I've made some records straight into DB) with DELETE button near each. But how to implement CREATE? So, one empty row should be visible and I could ADD other rows on click "Add row"?
It is possible. Using javascript you should create additional items in view, in controller action you are getting $_POST with all data, fill and validate all models in one transaction. In update action view you are showing related models with php foreach.
There is an example of code that can be useful for you. See comments also.

Editing a specific record in yii

I have a view section in my project,and using CGridView to list all the data from table,also have an edit and delete option within the grid to edit and delete specific row.
I am stuck with the edit section.I am working on how to get a specific row data dispalyed in editjob.php,I have done a few things,but no use.My codes are as follows,
In my view job section using CgridView,
'buttons' =>array('update'=>array(
'label'=>'edit',
'url'=>'Yii::app()->controller->createUrl("UpdateJob",array("id"=>$data["id"]))',
))
In Model UpdateJob:
public function edit()
{
$criteria=new CDbCriteria;
$criteria->find('id','Admin',true);
return new CActiveDataProvider('viewjob', array(
'criteria'=>$criteria,
// 'sort'=>array(
// 'defaultOrder'=>'key_skills ASC',
// ),
));
in controller:
public function actionUpdateJob()
{
if(isset($_GET['id']))
{
$id=$_GET['id'];
}
$model = new UpdateJob('edit');
$params = array('model' => $model,'id' => $id //passing the id like this
);
$this->render('update', $params);
}
And finaly in view written something like ,but showing error
<div class="row">
<?php echo $form->labelEx($model,'Company Name'); ?>
<?php echo Chtml::textField('posted_by',UpdateJob::model()->FindByPk($model->id)->posted_by); ?>
<?php echo $form->error($model,'posted_by'); ?>
</div>
am I on right track.
Youre loading a fresh model instead of fetching an existing one. Replace this line:
$model = new UpdateJob('edit');
By this line:
$model = UpdateJob::model()->findByPk($id);
To save the data you do this:
if(isset($_POST['UpdateJob'])) {
$model->scenario='edit';
$model->attributes=$_POST['UpdateJob'];
if($model->save())
$this->redirect(array('admin');
}

how can i get relation data by CActiverecord in yii?

I have 2 tables. tables have relation (HAS_MANY)
table1: user(id,name)
table2:address(id,userId,address)
user can has some address
I define relation in moles: user.php and address.php
user.php
'address' => array(self::HAS_MANY, 'address', 'userId'),
address.php
'user' => array(self::BELONGS_TO, 'user', 'userId'),
when i write
$dataProvider = new CActiveDataProvider('user')
i get only record of user table but i want to get records two table i want to get name,array(address) For each user , how can do it?
UserController.php
public function actionIndex() {
$dataProvider = new CActiveDataProvider('User');
$this->render('index', array(
'dataProvider' => $dataProvider,
));
}
index.php
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
)); ?>
_view.php
<b><?php echo $data->name)); ?>: <?php $data->address->address; ?>:</b>
In indexaction function, change the dataprovider code as below.
$dataProvider = new CActiveDataProvider('User','criteria'=>array(
'with'=>array(
'address'
),
'together'=>true,
));
You can get the data from address table using $data->address->address_table_field_name in your view file.
Here address is relation name defined in your user model file.
You don't need to use CActiveDataProvider, rather use the model directly.
Give it a try
foreach( User::model()->findAll() as $user ) {
$address = $user->address;
foreach( $address as $a ) {
}
}
try using
$model= User::model()->with('address')->findAll();
Note:- address in with('address') is the relation Name.
Eg:-
To get User records try this
foreach($model as $record)
{
echo $record->id . $record->name;
}
To get address records try this
foreach($model as $record)
{
foreach($record->address as $myaddress)
{
echo $myaddress->id . $myaddress->userId . $myaddress->address;
}
}

Yii model not getting posted

I have this weird issue where the values seems to get posted on form submit but still there the controller seems to not find it. I am saving three models with a single form. Both the relations to the main model are HAS_MANY. Here's the controller.
$model=$this->loadModel($id);
$modelunitgroup = $model->userUnitgroups;
$modelunit = $model->userUnits;
if(isset($_POST['User'], $_POST['Userunitgroup'], $_POST['Userunit']))
{
$model->attributes=$_POST['User'];
$modelunit->attributes=$_POST['Userunitgroup'];
$modelunitgroup->attributes=$_POST['Userunit'];
$valid=$model->validate();
if($valid)
{
if($model->save(false))
{
$modelunitgroup->user_id = $model->id;
$modelunit->user_id = $model->id;
if ($modelunitgroup->save() && $modelunit->save())
{
Yii::app()->user->setFlash('success', "User updated!");
$this->redirect(array('view','id'=>$model->id));
}
}
}
}
$this->render('update',array(
'model'=>$model,
'modelunitgroup'=>$modelunitgroup,
'modelunit'=>$modelunit,
));
Here's the relations
'userUnitgroups' => array(self::HAS_MANY, 'Userunitgroup', 'user_id'),
'userUnits' => array(self::HAS_MANY, 'Userunit', 'user_id'),
And the form view
<?php echo $form->errorSummary($model); ?>
<?php echo $form->dropDownListRow($model, 'title', $model->getUtitle(),array('prompt' => 'Select ...'));?>
<?php echo $form->textFieldRow($model,'firstname',array('class'=>'span5','maxlength'=>60)); ?>
<?php echo $form->textFieldRow($model,'lastname',array('class'=>'span5','maxlength'=>60)); ?>
<?php echo $form->textFieldRow($model,'mobile',array('class'=>'span5')); ?>
<?php echo $form->textFieldRow($model,'email',array('class'=>'span5','maxlength'=>160)); ?>
<?php echo $form->passwordFieldRow($model,'password',array('class'=>'span5','maxlength'=>32)); ?>
<?php
foreach ($modelunitgroup as $mgroup) {
echo $form->dropDownListRow($mgroup,
'unitgroup',
$model->getUnitgroups(),
array(
'ajax' => array(
'type'=>'POST',
'url'=>CController::createUrl('user/getunit'),
'update'=>'#Userunit_unit',
)));
}
foreach ($modelunit as $munit) {
echo $form->dropDownListRow($munit,
'unit',
array()
);
}
?>
I keep getting the error "Attempt to assign property of non-object". It seems that the 'Userunitgroup' and 'Userunit' are never posted, which is weird cause I checked the header in Firefox and all the values are correctly being posted. Any help on what may be causing this and how to solve this?
$modelUnitGroup and $modelunit are arrays, yet you are assigning attributes like they are individual models (objects). For more information on how to do batch inserts/updates consult the manual.
I think you have a problem in your models rules in your scenario, in your model class:
public function rules() {
array('title ,name, country, ..., password', 'safe', 'on'=>'thisCustomeScenario'),
...
}
and try to var_dump($_POST) to see what exactly your getting

Update two models of different databases with single view in yii

I have a view (_form.php) with fields (name,summary) submit button. If I click on submit button, it should update Name field of One model and Summary field of another model.Both this models are of different databases.
Can anyone help on this. I tried the following for this
In _form.php(Test)
<?php echo $form->labelEx($model, ‘name’); ?>
<?php echo $form->textField($model, ‘name’, array(‘size’ => 60, ‘maxlength’ => 250)); ?>
<?php echo $form->error($model, ‘name’); ?>
<?php echo $form->labelEx(Test1::model(), ‘summary’); ?>
<?php echo $form->textField(Test1::model(), ‘summary’, array(‘size’ => 60, ‘maxlength’ => 250)); ?>
<?php echo $form->error(Test1::model(), ‘summary’); ?>
<?php echo CHtml::submitButton($model->isNewRecord ? ‘Create’ : ‘Save’); ?>
In TestController.php
public function actionCreate() {
$model = new Test;
if (isset($_POST['Test'])) {
$model->attributes = $_POST['Test'];
if ($model->save()) {
$modeltest1 = new Test1;
$modeltest1->attributes = $_POST['Test1'];
$modeltest1->Id = $model->Id;
if ($modeltest1->save())
$this->redirect(array('view', 'Id' => $model->Id));
}
}
$this->render('create', array(
'model' => $model,
));
}
This code is not working. How can I make it work for different databases. I followed the below link for this.
http://www.yiiframework.com/wiki/291/update-two-models-with-one-view/
This code actually should work, but its bad.
I assume that you dont understand at all what is model and what its doing in Yii, also how to render and create forms.
I'll try to explain how it should be.
1st of all dont use Test::model() in views, unless you want to call some function from it(but try to avoid it). It can be done by passing it from controller:
public function actionCreate() {
$model_name = new Name;
$model_summary=new Summary;
//something here
$this->render('create', array(
'name' => $model_name,
'summary'=>$model_summary,
));
}
When you make render you passing variables to your view (name_in_view=>$variable)
2nd. In your view you can use your variables.
<?php echo $form->labelEx($name, ‘name’);
echo $form->textField($name, ‘name’, array(‘size’ => 60, ‘maxlength’ => 250));
echo $form->error($name, ‘name’);
echo $form->labelEx($summary, ‘summary’);
echo $form->textField($summary, ‘summary’, array(‘size’ => 60, ‘maxlength’ => 250)); ?>
echo $form->error($summary, ‘summary’); ?>
echo CHtml::submitButton($model->isNewRecord ? ‘Create’ : ‘Save’); ?>
3rd. You need to understand what is model. It's class that extends CActiveRecord in this case. Your code in controller should loo like:
public function actionCreate() {
$model_name = new Name;
$model_summary=new Summary;
if (isset($_POST['Name']))
$model_name->attributes=$_POST['Name'];
if (isset($_POST['Summary']))
$model_name->attributes=$_POST['Summary'];
if ($model_name->save()&&$model_summary->save())
$this->redirect(array('view', 'Id' => $model->Id));
$this->render('create', array(
'name' => $model_name,
'summary'=>$model_summary,
));
}
$model->attributes=$_POST[] here is mass assignment of attributes, so they must be safe in rules. You always can assign attributes with your hands (1 by 1), or form an array and push it from array.

Categories