Also available in these languages:
English日本語polskiРусский简体中文

Creating and Displaying Comments

In this section, we implement the comment display and creation features.

In order to enhance the user interactivity, we would like to prompt users the possible errors each time he finishes entering one field. This is known client-side input validation. We will show how this can be done in Yii seamlessly and extremely easy. Note that this requires Yii version 1.1.1 or later.

Displaying Comments

Instead of displaying and creating comments on individual pages, we use the post detail page (generated by the view action of PostController). Below the post content display, we display first a list of comments belonging to that post and then a comment creation form.

In order to display comments on the post detail page, we modify the view script /wwwroot/blog/protected/views/post/view.php as follows,

...post view here...
 
<div id="comments">
    <?php if($model->commentCount>=1): ?>
        <h3>
            <?php echo $model->commentCount . 'comment(s)'; ?>
        </h3>
 
        <?php $this->renderPartial('_comments',array(
            'post'=>$model,
            'comments'=>$model->comments,
        )); ?>
    <?php endif; ?>
</div>

In the above, we call renderPartial() to render a partial view named _comments to display the list of comments belonging to the current post. Note that in the view we use the expression $model->comments to retrieve the comments for the post. This is valid because we have declared a comments relation in the Post class. Evaluating this expression would trigger an implicit JOIN database query to bring back the proper comments. This feature is known as lazy relational query.

The partial view _comments is not very interesting. It mainly goes through every comment and displays the detail of it. Interested readers may refer to /wwwroot/yii/demos/blog/protected/post/_comments.php.

Creating Comments

To handle comment creation, we first modify the actionView() method of PostController as follows,

public function actionView()
{
    $post=$this->loadModel();
    $comment=$this->newComment($post);
 
    $this->render('view',array(
        'model'=>$post,
        'comment'=>$comment,
    ));
}
 
protected function newComment($post)
{
    $comment=new Comment;
    if(isset($_POST['Comment']))
    {
        $comment->attributes=$_POST['Comment'];
        if($post->addComment($comment))
        {
            if($comment->status==Comment::STATUS_PENDING)
                Yii::app()->user->setFlash('commentSubmitted','Thank you...');
            $this->refresh();
        }
    }
    return $comment;
}

In the above, we call the newComment() method before we render view. In the newComment() method, we generate a Comment instance and check if the comment form is submitted. If so, we try to add the comment for the post by calling $post->addComment($comment). If it goes through, we refresh the post detail page. In case the comment needs to be approved, we will show a flash message to indicate this decision. A flash message is usually a confirmation message displayed to end users. If the user clicks on the refresh button of his browser, the message will disappear.

We also need to modify /wwwroot/blog/protected/views/post/view.php furthermore,

......
<div id="comments">
    ......
    <h3>Leave a Comment</h3>
 
    <?php if(Yii::app()->user->hasFlash('commentSubmitted')): ?>
        <div class="flash-success">
            <?php echo Yii::app()->user->getFlash('commentSubmitted'); ?>
        </div>
    <?php else: ?>
        <?php $this->renderPartial('/comment/_form',array(
            'model'=>$comment,
        )); ?>
    <?php endif; ?>
 
</div><!-- comments -->

In the above code, we display the flash message if it is available. If not, we display the comment input form by rendering the partial view /wwwroot/blog/protected/views/comment/_form.php.

Client-side Validation

In order to support client-side validation of the comment form, we need to make some minor changes to both the comment form view /wwwroot/blog/protected/views/comment/_form.php and the newComment() method.

In the _form.php file, we mainly need to set CActiveForm::enableAjaxValidation to be true when we create the CActiveForm widget:

<div class="form">
 
<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'comment-form',
    'enableAjaxValidation'=>true,
)); ?>
......
<?php $this->endWidget(); ?>
 
</div><!-- form -->

And in the newComment() method, we insert a piece of code to respond to the AJAX validation requests. The code checks if there is a POST variable named ajax. If so, it displays the validation results by calling CActiveForm::validate.

protected function newComment($post)
{
    $comment=new Comment;
 
    if(isset($_POST['ajax']) && $_POST['ajax']==='comment-form')
    {
        echo CActiveForm::validate($comment);
        Yii::app()->end();
    }
 
    if(isset($_POST['Comment']))
    {
        $comment->attributes=$_POST['Comment'];
        if($post->addComment($comment))
        {
            if($comment->status==Comment::STATUS_PENDING)
                Yii::app()->user->setFlash('commentSubmitted','Thank you...');
            $this->refresh();
        }
    }
    return $comment;
}
$Id: comment.create.txt 1753 2010-01-25 18:25:03Z qiang.xue $
If you find any typos or errors in the tutorial, please create a Yii ticket to report it. If it is a translation error, please create a Yiidoc ticket, instead. Thank you.

Total 8 comments:

#165
verifyCode variabein Comment Model
by thomas.mery at 4:20am on April 4, 2009.

Hi,

Since I spent 15 mn trying to figure out why the application was returning a :

Property "Comment.verifyCode" is not defined.

when trying to setup the new Comment form

I thought I'd share that I think there must exist in th emodel a variable for each Validation Rule that has been set up in thi same model. That is for validation rules for fields that ar not a db field.

Example :

for this rule to exist without any errors being returned :

array('verifyCode', 'captcha', 'on' => 'insert', 'allowEmpty'=>!Yii::app()->user->isGuest)

the following line must be added in the Comment model

public $verifyCode;

Maybe it was explaned somawhere but if this is the case I missed the info :)

hope htat helps someone

Thanks

is a rule that

#166
captcha not showing
by thomas.mery at 4:13am on April 5, 2009.

hi,

I had aproblem with the captcha image not showing ...

it turns out that :

the captcha image is generated by the CCaptchaAction class which is an action for the Ccaptcha widget.

everything takes place in the renderImage method if the captcha widget : $url=$this->getController()->createUrl($this->captchaAction); $alt=isset($imageOptions['alt'])?$imageOptions['alt']:''; echo CHtml::image($url,$alt,$this->imageOptions);

#167
follow up ...
by thomas.mery at 4:35am on April 5, 2009.

hit submit by mistake ... (how do I edit my comments by the way ?)

so :

$url=$this->getController()->createUrl($this->captchaAction);
CHtml::image($url,$alt,$this->imageOptions);

are the important lines. The first one creates an action for the current controller which will look like this (default urls with get parameters) : index.php?r=post/captcha

this url will be used to point to the captcha action CCaptchaAction which will actually render the image with the help of the gd library (see renderImage method of the CCaptchaAction class).

But for all this to work you need to have this url point to the right action and this is done in the actions array of the PostController (see Action section in tne Controller page of the guide):

/**
 * Declares class-based actions.
 */
public function actions()
{
    return array(
        // captcha action renders the CAPTCHA image
        // this is used by the contact page
        'captcha'=>array(
            'class'=>'CCaptchaAction',
            'backColor'=>0xF5F5F5,
        ),
    );
}


hope this helps someone who like me was trying to follow the tutorial without looking at the completed demo code.

#583
not Good
by sebi at 8:04pm on August 14, 2009.

This part of the tutorial is really bad, not enough explanation about the Captcha :(

#704
white screen ...
by nima at 10:30am on October 5, 2009.

After completing the tutorial step http://www.yiiframew.../comment.create I get a white screen of death when I try to submit a comment to a post.

Here is an example: http://taskhead.com/...=post/show&id=4

How do I debug it?

#705
example
by nima at 10:31am on October 5, 2009.

sorry, here is the example:

http://taskhead.com/blog/index.php?r=post/show&id=4

#706
error
by nima at 10:15am on October 5, 2009.

Ah I found the following php error in the log:

PHP Fatal error: Undefined class constant 'STATUS_PENDIN G' in .../blog/protected/controllers/PostContr oller.php on line 70

#948
problem
by venkatesh1586 at 1:35am on January 5, 2010.

i had one problem captcha image not display my project , plz reply me..

view-> <?php $this->widget('CCaptcha',array('buttonType'=>'button')); ?>

model-->

public function rules() { return array( array('blogtitle,blogspotname,blogsname','required'), array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd')),

                 );
}


      public function actions()
{
    return array(
        'captcha' => array(
            'class' => 'CCaptchaAction',
            'backColor' => 0xEBF4FB,
            ),
        );
}

    public function filters()
{
    return array('accessControl');
}

public function accessRules()
{
    return array(array('allow', 'actions' => array('list', 'show', 'add', 'update', 'captcha'), 'users' => array('*')));
}



public static function model($className=__CLASS__)
{ 
    return parent::model($className);
}

    public function tableName()
{
    return 'Createblog';
}





Your Comment:

You may enter comment using Markdown syntax.

Please login with your forum account.
Note: you must have at least ONE forum post with your account.