I got a Yii form which collects data for three models. I am using ajaxvalidation, on change and on submit:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'offer-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions' => array(
'validateOnChange'=>true,
'validateOnSubmit'=>true,
)
)); ?>
Now the problem is that that only the first three inputs are getting validated, code of these inputs:
1:
<div class="input-bg wide-input">
<?php
//fill this field after selecting newspaper
echo $form->hiddenField($newspaper, 'id'); ?>
<?php echo $form->textField($newspaper, 'name', array('maxlength' => 45, 'placeholder'=>'Krantnaam')); ?>
<?php echo $form->error($newspaper, 'name', array('class'=>'error')); ?>
</div>
<a class="button gray-button">Aanbieden</a>
2 and 3:
<div class="input-bg linked-input">
<?php echo $form->textField($address, 'postalcode', array('maxlength' => 45, 'placeholder'=>'Postcode')) ?>
<?php echo $form->error($address, 'postalcode'); ?>
</div>
<div class="input-bg linked-input">
<?php echo $form->textField($address, 'street_number', array('maxlength' => 45, 'placeholder'=>'Huisnummer')); ?>
<?php echo $form->error($address, 'street_number'); ?>
</div>
Those three inputs serve for two models which are $newspaper and $address. Now the case is that those three inputs are perfectly validated(on change and on submit) where the other seven inputs are not validated, example of one of those inputs that are not validated:
<div class="input-bg linked-input">
<?php echo $form->textField($offer, 'firstname', array('maxlength' => 45, 'placeholder'=>'Voornaam')); ?>
<?php echo $form->error($offer, 'firstname'); ?>
</div>
Finally, I will post my controller code:
$this->performAjaxValidation($offer, 'offer-form');
$this->performAjaxValidation($address, 'offer-form');
$this->performAjaxValidation($newspaper, 'offer-form');
if(Yii::app()->getRequest()->getIsAjaxRequest()) {
echo CActiveForm::validate( array($address));
echo CActiveForm::validate( array($offer));
echo CActiveForm::validate( array($newspaper));
print_r($_POST);
die();
//Yii::app()->end();
}
If I am submitting or changing the form I do get back JSON with the errors for the fields that are not validated on the eye, but they don't get an error state.
I hope there is someone that can see a mistake or anything else.
Greetz,
The reason it returns once it finds an error is that performAjaxValidation calls Yii::app()->end() after validating the model. In order to validate several models use the method below
protected function performTabularAjaxValidation($models, $form = null) {
if (Yii::app()->getRequest()->getIsAjaxRequest() && (($form === null) || ($_POST['ajax'] == $form))) {
echo CActiveForm::validateTabular($models);
Yii::app()->end();
}
}
and in your controller method
$this->performTabularAjaxValidation(array($address,$offer,$newspaper),'offer-form');
Related
In a Yii project passed to me, there's a function that creates (or shows?) a textbox when the button/link Comment is clicked. From there, the user can create Comments, which will be displayed in a row.
I'm trying to see if I can create an edit comment function, so I thought I could go about this by copying the Comment function - it'll show a textbox, and the user can input the new text in there. And instead of adding a new comment, it will edit the existing one.
But I hit a snag, as apparently the view.php makes use of a variable that I couldn't for the life of me figure out how to use in _comments.php - the file responsible for displaying the individual comments, afaik.
Here's the code for view.php:
</script>
<?php
$this->breadcrumbs=array('Forums'=>array('index'),$model->title,);
?>
<?php
if(Yii::app()->user->hasFlash('message')):
echo '<script>alert("'.Yii::app()->user->getFlash('message').'");</script>';
endif;
?>
<?php $starter = Persons::model()->findByAttributes(array('party_id'=>$model->party_id));?>
<div id="forum_main_box">
<div class="comment-icon-textbox">
<?php echo CHtml::ajaxLink('Comment',array('forum/callcommentform'),
array(
'update' => '#render_div'.$model->id,
'data'=>array('id'=>$model->id),
)); ?>
</div>
<?php endif; ?>
<div id="forum_comment_headerbox">
</div>
<div>
<?php
$this->widget('zii.widgets.CListView',
array(
'dataProvider'=>$dataProvider,
'itemView'=>'_comments',
'summaryText'=>'',
));
?>
<div id="render_div<?=$model->id?>" class="comment-form">
</div>
</div>
</div>
Of that code, below is the Comment link I spoke of:
<?php echo CHtml::ajaxLink('Comment',array('forum/callcommentform'),
array(
'update' => '#render_div'.$model->id,
'data'=>array('id'=>$model->id),
)); ?>
<?php } ?>
This block displays the list of comments, and what (I assume to be) the space where the textbox will pop up when the above Comment is clicked:
<?php
$this->widget('zii.widgets.CListView',
array(
'dataProvider'=>$dataProvider,
'itemView'=>'_comments',
'summaryText'=>'',
));
?>
<div id="render_div<?=$model->id?>" class="comment-form">
</div>
Notice that both makes use of $model. It first appeared in the code as $model->title.
And here's a shortened version of the _comments.php, which is used for the comment rows and the comment box.
<?php $comment = $data; ?>
<div class="other-member-comment-box">
<?php $person=Persons::model()->findByAttributes(array('party_id'=>$comment->party_id)); ?>
<?php
$country=Lookup_codes::model()->findByAttributes(array('id'=>$person->country));
$location = empty($country) ? '' : ' - '.$country->name;
// $model->title;
?>
<?php if (Yii::app()->user->id == $person->party_id || Yii::app()->partyroles->isAdmin()) {
?>
<p class="admin-commands">
<?php echo CHtml::link(CHtml::encode('Edit'),array('forum/editcomment','reply'=>$data->id,'topic'=>$data->content_id)); ?>
<?php echo CHtml::ajaxLink('EditTestComment',array('forum/callcommentform'),array('update' => '#render_div'.$model->id,'data'=>array('id'=>$model->content_id),)); ?>
<?php echo CHtml::link(CHtml::encode('Delete'),array('forum/delete','reply'=>$data->id,'topic'=>$data->content_id),array('confirm'=>'Are you sure you want to delete this item?')); ?>
<div id="render_div<?=$model->id?>" class="comment-form">
</div>
</p>
<?php } ?>
</div>
Under <p class="admin-commands">, there's a EditTestComment link which is a straight up copy of the Comment code from the view.php. This doesn't work, of course, because of this:
2016/04/07 10:24:03 [error] [php] Undefined variable: model
Where'd $model come from in view.php? Because putting in the same line ($model->title) anywhere in _comments.php just breaks it further.
EDIT: Here's the CallComment part of the controller:
public function actionCallCommentForm($id='')
{
$topic=Forum::model()->findByPk($id);
$this->renderPartial('_commentform', array(
'forum'=>$topic,
'model'=>new Comment,
//'view'=>array('view','id'=>$id),
'view'=>'view',
));
}
$model variable is coming from your controller initially. It is an instance of a Comment class which gets passed to the view via $this->render('view', array('model'=>$whatever)). This line will make $whatever available in the forum/view.php file under the name of $model. Now since you are dealing with partial views you have to track it because it is possible that the same $model variable will be passed to another partial view with $this->renderPartial('_comment', array('whatever'=>$model)) and now this will be accessible in partial view as $whatever.
It's showing an error like "Undefined variable: fullImgSource".
Can anyone help me with this?
in view
<div class="form">
<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'Candidate-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true
),
'htmlOptions' => array('enctype' => 'multipart/form-data')
));
?>
<p class="note">Fields with <span class="required">*</span> are required. </p>
<?php echo $form->errorSummary($model); ?>
<?php
echo $form->labelEx($model, 'delete_YN');
echo $form->fileField($model, 'delete_YN');
echo $form->error($model, 'delete_YN');
?>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Add' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
In Controller code is here
Uploadfile
$model = new Candidate;
if(isset($_POST['Candidate']))
{
$model->attributes=$_POST['Candidate'];
$name=#$_FILES["Candidate"]["name"]["delete_YN"];
$model->delete_YN = CUploadedFile::getInstance($model,'delete_YN');
if($model->save())
$fullImgSource = Yii::getPathOfAlias('webroot').'/upload/'.$name;
$model->delete_YN->saveAs($fullImgSource);
$model->delete_YN = $name;
$model->save();
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array('model'=>$model,));
Yii have built in support for file uploads. You don't need to worry about $_FILES.
Kindly go through with, How to upload files using model
Regards
Your $model is most likely not passing validation (check $model->getErrors() if validation fails for more information on what exactly failed), so the save() method does not go through and $fullImgSource ends up not being defined. You should wrap your code in braces after the save method since the following code relies on it to succeed.
$cUploadedFile = CUploadedFile::getInstance($model, 'delete_YN');
if ($cUploadedFile) {
$model->delete_YN = $cUploadedFile;
}
if ($model->save()) {
if ($cUploadedFile) {
// Save file from temp to a specific location
$cUploadedFile->saveAs('upload/' . $model->delete_YN);
}
$this->redirect(array('view','id'=>$model->id));
}
Hopefully this answers why you are getting that error. Now as to how to actually handle uploads, you do not have to access $_FILES to get your upload. CUploadedFile::getInstance($model, 'attribute_name') should take care of that for you.
In my web application I need to collect data from two models in a single form. The first model form is like an update action for making changes in existing data and the second form is for creating a new record. Below is the code I tried but when I click "save" button Its not saving and redirecting instead it is just staying in the same page and the changes I made are reverting back to their previous values for I model and second model the attribute are becoming empty.
My code for the controller
public function actionBookvegetable($id){
$BookVegetable=new BookVegetable;
$model=$this->loadModel($id);
if(isset($_POST['ProducerOffer'])AND (isset($_POST['BookVegetable'])) ) {
$model->attributes=$_POST['ProducerOffer'];
$BookVegetable->attributes=$_POST['BookVegetable'];
if($ProducerOffer->validate() AND $BookVegetable->validate()) {
$BookVegetable->save();
$BookVegetable->booked_by=Yii::app()->user->id;
$BookVegetable->producer_offer_id=$model->id;
$model->save();
}
if (($model->hasErrors() === false)&&($BookVegetable->hasErrors===false))
{
$this->redirect(Yii::app()->user->returnUrl);
}
}
else
{
Yii::app()->user->setReturnUrl($_GET['returnUrl']);
}
$this->render('book',array('model'=>$model,'BookVegetable'=>$BookVegetable));
}
My code for the view form.
<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array('id'=>'non-ajax_form','enableAjaxValidation'=>false,)); ?>
<p class="help-block">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model,$BookVegetable); ?>
<?php echo "<br>" ?>
<?php echo $form->dropDownList($model,'vegetable_id', CHtml::listData(Vegetable::model()->findAll(),'id', 'name'), array('prompt'=>'Select Vegetable')); ?>
<?php echo CHtml::encode($model->getAttributeLabel('offered_qty')); ?>
<?php echo CHtml::textField("offered_qty",$model->offered_qty,array('readonly'=>true)); ?>
<?php echo CHtml::encode($model->getAttributeLabel('unit_cost')); ?>
<?php echo CHtml::textField("unit_cost",$model->unit_cost,array('readonly'=>true)); ?>
<?php echo CHtml::encode($model->getAttributeLabel('unit_delivery_cost')); ?>
<?php echo CHtml::textField("unit_delivery_cost",$model->unit_delivery_cost,array('readonly'=>true)); ?>
<?php echo CHtml::textField("booked_quantity",$BookVegetable->booked_quantity); ?>
</div>
<?php $this->endWidget(); ?>
</div>
<div class="form-actions">
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'type'=>'primary', 'label'=> 'Save',)); ?
How should I resolve this Anybody help me out .I am unable to debug the source of error
You are saving the values before assigning the requested values.
Try this code, if it works:
public function actionBookvegetable($id){
$BookVegetable=new BookVegetable;
$model=$this->loadModel($id);
if(isset($_POST['ProducerOffer'])AND (isset($_POST['BookVegetable'])) )
{
$model->attributes=$_POST['ProducerOffer'];
$BookVegetable->attributes= $_POST['BookVegetable'];
/*** The below two lines should be before "$BookVegetable->save()" function ***/
$BookVegetable->booked_by=Yii::app()->user->id;
$BookVegetable->producer_offer_id=$model->id;
/*** Validate() function will check for the errors **/
if($ProducerOffer->validate() AND $BookVegetable->validate())
{
$BookVegetable->save();
$model->save();
$this->redirect(Yii::app()->user->returnUrl);
}
/***There is no need to check again for the errors as validate() will do that, So you can comment this three lines ***/
/**if (($model->hasErrors() === false)&&($BookVegetable->hasErrors===false))
{
$this->redirect(Yii::app()->user->returnUrl);
} */
}
else
{
Yii::app()->user->setReturnUrl($_GET['returnUrl']);
}
$this->render('book',array('model'=>$model,'BookVegetable'=>$BookVegetable));
}
Try changing these input text fields in your view file:
<?php echo $form->dropDownList($model,'vegetable_id', CHtml::listData(Vegetable::model()->findAll(),'id', 'name'), array('prompt'=>'Select Vegetable')); ?>
/*** The first field for below input text field is for "name" of the text fields, so this must follow "ModelName[field_name]" format **/
<?php echo CHtml::textField("ProducerOffer[offered_qty]",$model->offered_qty,array('readonly'=>true)); ?>
<?php echo CHtml::textField("ProducerOffer[unit_cost]",$model->unit_cost,array('readonly'=>true)); ?>
<?php echo CHtml::textField("ProducerOffer[unit_delivery_cost]",$model->unit_delivery_cost,array('readonly'=>true)); ?>
<?php echo CHtml::textField("BookVegetable[booked_quantity]",$BookVegetable->booked_quantity); ?>
I hope this would definitely work.. :)
I just started working with yii and I stumbled upon a problem.
I have a table called "users" and a table called "messages".
I basically want to have a page where I can view a user's details but also send him a message that would be saved in the message table.
I have a view called "user/view.php" which consists of:
<h1>View User #<?php echo $model->id; ?></h1>
<?php $this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'username',
'first_name',
'last_name',
),
)); ?>
<?php $message=new Message;
echo $this->renderPartial('_messagesend', array('model'=>$message)); ?>
the _messagesend form (created using gii) looks like:
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'message-_messagesend-form',
'enableAjaxValidation'=>false,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
//for the sake of simplicity lets just insert the id's manually for now
<div class="row">
<?php echo $form->labelEx($model,'idFrom'); ?>
<?php echo $form->textField($model,'idFrom'); ?>
<?php echo $form->error($model,'idFrom'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'idTo'); ?>
<?php echo $form->textField($model,'idTo'); ?>
<?php echo $form->error($model,'idTo'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'msg'); ?>
<?php echo $form->textField($model,'msg'); ?>
<?php echo $form->error($model,'msg'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Send'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
I have a simple view in my UserController to display the details info:
public function actionView($id)
{
$this->render('view',array(
'model'=>$this->loadModel($id)
));
}
And now I want to figure out how i can add the controller to save the message. After gii creation I get a code which I tried to use and modify a little bit:
public function actionMessagesend()
{
$model=new Message;
if(isset($_POST['Message']))
{
$model->attributes=$_POST['Message'];
if($model->save()){
$this->redirect(array('admin'));
}
}
$this->render('_messagesend',array('model'=>$model));
}
I tried to add this controller function in the UserController.php but it doesn't seem to work, I tried to add the same function to MessageController.php but it also doesn't seem to work. I tried to remove all the code and only add a redirect to show if the controllercode actually hits but it doesn't redirect (i tried it both in usercontroller and messagecontroller). So I have a feeling my code isn't reached. You guys have any idea what I'm missing here?
Maybe a little extra question: Is there a better suggestion to do what I want to do?
Thanks a lot!
Best regards,
WtFudgE
Your message sending action isn't reached because by default the CActiveForm submits to the current page, so you will have to add the message processing to the view action, or you will need to set the action property for your CActiveForm.
Here is the link to the property documentation: http://www.yiiframework.com/doc/api/1.1/CActiveForm#action-detail
So the form widget in the view should be something like:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'message-_messagesend-form',
'enableAjaxValidation'=>false,
'action' => array( '/message/messageSend' ), // change depending on your project
)); ?>
You can also achieve this by editing the submit button in the view page like this:
<?php echo CHtml::button('Send', array('submit' => array('message/messageSend')));?>
I have a problem with captcha in my YII project. I included a captcha in popup form. It's showing correctly, but there's a problem with the validation. The validation is true sometimes, if we entered the correct word in first attempt, the validation says it is wrong, after generating another code the validation succeeds. Why?
In model-> rules:
array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements(),'on'=> 'signup')
In controller -> calling the signup form via renderPartial
$this->renderPartial('signUp',array('model'=>$model),false,true);
In view :
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'sign-up-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
-----------------------
-----------------------
<?php if(CCaptcha::checkRequirements()): ?>
<?php echo $form->labelEx($model, 'verifyCode', array('for'=>'User_security_code')); ?>
<?php $this->widget('CCaptcha'); ?>
<?php echo $form->textField($model,'verifyCode',array('class'=>'txt-style width-289')); ?>
Please enter the letters as they are shown in the image above. Letters are not case-sensitive.
<?php echo $form->error($model,'verifyCode',array('class'=>'error_msg')); ?>
<?php endif; ?>
i added this in view
<?php
Yii::app()->clientScript->registerScript(
'initCaptcha',
'$("#yw0_button").trigger("click");',
CClientScript::POS_READY);
?>
and in
`CCaptchaAction.php` updated `$testLimit = 0;` //for unlimted test`
and the problem solved. I'm not sure about this is the right way, but for my current scenario it helped.