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
Related
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.
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.
i want to create a form from 2 different models,
1st is for countries, and the 2nd is for documents.
The problem is that i can't make a dropdown list, i get the errors all the time.
Here's the code, first my controller.php part
$model = new Country;
$model2 = new Product;
$this->performAjaxValidation(array($model, $model2));
if(isset($_POST['Country'],$_POST['Product']))
{
// populate input data to $model and $model2
$model->attributes=$_POST['Country'];
$model2->attributes=$_POST['Product'];
// validate BOTH $model and $model2
$valid=$model->validate();
$valid=$model2->validate() && $valid;
if($valid)
{
// use false parameter to disable validation
$model->save(false);
$model2->save(false);
$this->redirect('index');
}
}
...
$countriesIssued = Country::model()->findAll(array('select'=>'code, name', 'order'=>'name'));
...
$this->render('legalisation', array('model'=>$model, 'model2'=>$model2, 'documents'=>$documents, 'countriesIssued'=>$countriesIssued, 'countries'=>$countries, 'flag'=>$flag));
}
In my view script I use this code
<?php $form = $this->beginWidget('CActiveForm', array(
'id'=>'user-form',
'enableAjaxValidation'=>true,
)); ?>
<?php echo $form->errorSummary(array($model,$model2)); ?>
<?php echo $form->dropDownList($model, 'countriesIssued',
CHtml::listData($countriesIssued, 'code', 'name'));?>
<?php $this->endWidget(); ?>
but i get this error :
Property "Country.countriesIssued" is not defined.
Ok it's not defined, i try to change it to 'countriesIssued', then i got another error saying Invalid argument supplied for foreach() .
If anybody can help me please.
I know there is more solutions on net, i try it but not understand, Thanks.
By definition, the first param of listData is an array; Your is a object;
<?php
echo $form->dropDownList($model, 'classification_levels_id', CHtml::listData(ClassificationLevels::model()->findAll(), 'id', 'name'),$classification_levels_options);
?>
Make a list variable like this:
In your Model:
$countriesIssued = Country::model()->findAll(array('select'=>'code, name', 'order'=>'name'));
And in your view:
$list = CHtml::listData($countriesIssued, 'code', 'name'));
echo CHtml::dropDownList('Your variable', Your $model,
$list,
array('empty' => '(Select a category'));
dropDownList($model,'state',array('1' => 'Do 1', '2' => 'Do 2'),array('selected' => 'Choose')); ?>
Or Yii 2
field($model,'state')->dropDownList(
array('1' => 'Do 1','0' => 'Do 2'),array('options' => array('0' => array('selected' => true))))
->label('State')
?>
I get this error when I call CreateController : "get_class() expects parameter 1 to be object, array given "
Controll/actionCreate() is as follows:
public function actionCreate() {
$model = new Ogrenci;
$model2 =new Adresler;
$this->performAjaxValidation($model, 'ogrenci-form');
$this->performAjaxValidation($model2, 'ogrenci-form');
if (isset($_POST['Ogrenci'],$_POST['Adresler'])) {
$model->setAttributes($_POST['Ogrenci']);
$model2->setAttributes($_POST['Adresler']);
if ($model->save(false) && $model2->save(false)) {
if (Yii::app()->getRequest()->getIsAjaxRequest())
Yii::app()->end();
else
$this->redirect(array('view', 'id' => $model->ogrenci_id));
}
}
$this->render('create', array( 'model' => $model,'model2' => $model2));
}
create.php:
<?php $this->renderPartial('_form', array(
'model' => array('model'=>$model,'model2'=>$model2),
'buttons' => 'create'));
?>
And _form.php's fields is as follows:
<div class="row">
<?php echo $form->labelEx($model2,'aciklama'); ?>
<?php echo $form->textField($model2,'aciklama'); ?>
<?php echo $form->error($model2,'aciklama'); ?>
</div><!-- row -->
$this->renderPartial('_form', array(
'model' => array(
'model'=>$model,
'model2'=>$model2
),
'buttons' => 'create'
));
code above means that file _form.php will have access to two variables:
$model - array of two elements, and $buttons - string.
So, to get access to first model you have to write $model['model'], second - $model['model2'].
but in this code
<?php echo $form->labelEx($model2,'aciklama'); ?>
<?php echo $form->textField($model2,'aciklama'); ?>
<?php echo $form->error($model2,'aciklama'); ?>
You are trying to access undefined variable $model2. And this should raise respective error.
The thing that error is not got makes me thinking that somewhere before listed code you access variable $model in the similar way, something like this:
echo $form->labelEx($model,'test');
In the above code $model is array(because you passed array). That is why you receive error that object is expected.
So, you should either pass models or access them in a proper way.
I hope this helps.
I solved another problem.Perhaps someone may be in need..
(CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key)
if ($model->save(false) && $model2->save(false)) {
if (Yii::app()->getRequest()->getIsAjaxRequest())
Yii::app()->end();
else
$this->redirect(array('view', 'id' => $model->ogrenci_id));
}
to
$a=$model2->save(false);
$model->adresler_id=$model2->adresler_id;
if ($a && $model->save(false)) {
if (Yii::app()->getRequest()->getIsAjaxRequest())
Yii::app()->end();
else
$this->redirect(array('view', 'id' => $model->ogrenci_id));
}
I am only trying to create a non-AJAX registration form.
When I submit through a CForm, PHP says error() is being called on a non-object. I checked the source file where the error occurred and (using var_dump(get_class($parent->getActiveFormWidget()));) found that getActiveFormWidget() returns a CFormInputElement, which does not have error() defined.
I thought this had to do with CForm::activeForm, but it defaulted to CActiveForm.
I did try 'enableAjaxValidation'=>false.
What am I not understanding? I suspect I misinterpreted something along the way.
CFormInputElement::renderError():
public function renderError()
{
$parent=$this->getParent();
// $parent->getActiveFormWidget() returns object that does not define error()
return $parent->getActiveFormWidget()->error($parent->getModel(), $this->name, $this->errorOptions, $this->enableAjaxValidation, $this->enableClientValidation);
}
Model:
class RegisterFormModel extends CFormModel {
public $email;
public $password;
public $password_confirm;
public function rules()
{
return array(
array('email, password, password_confirm', 'required'),
array('password','compare','compareAttribute'=>'password_confirm'),
array('password, password_confirm','length','min'=>'6','max'=>'20'),
array('email', 'email'),
array('email', 'length', 'max'=>256)
);
}
public function attributeLabels()
{
return array(
'email'=>'Email',
'password'=>'Password',
'password_confirm'=>'Confirm Password',
);
}
}
View:
<div class="form">
<?php echo $form; ?>
</div><!-- form -->
Controller Action:
class RegisterAction extends CAction
{
public function run()
{
$register_model = new RegisterFormModel;
$controller = $this->getController();
$form = new CForm(array(
'title'=>'Register',
'enableAjaxValidation'=>false,
'elements'=>array(
'email'=>array(
'type'=>'text',
'maxlength'=>256,
),
'password'=>array(
'type'=>'password',
'minlength'=>6,
'maxlength'=>32,
),
'password_confirm'=>array(
'type'=>'password',
'minlength'=>6,
'maxlength'=>32,
),
),
'buttons'=>array(
'register'=>array(
'type'=>'submit',
'label'=>'Register',
),
),
), $register_model);
if($form->submitted('register', true) && $form->validate())
{
// ...
}
else
{
$controller->render('register', array('model'=>$register_model, 'form'=>$form));
}
}
}
Well, I have never seen using CForm as you show us.
I recommend you to use the active form widget,
http://www.yiiframework.com/wiki/195/implementing-a-registration-process-using-the-yii-user-management-module/
and you need to define all those fields in your CFormModel. This way you will be able to provide proper validation for them.
I know that the answer is really late :)
But for the sake of anyone else who may have a similar error.
<?php
// change from: echo $form;
echo $form->render();
?>
I was rendering the elements separately so this is how I did it:
<?php
// without the renderBegin() and renderEnd() it may give the no object error
echo $form->renderBegin();
echo $form->renderElements();
echo $form->renderEnd();
?>