Files
yii/docs/blog/comment.create.txt
2010-12-24 16:24:12 +00:00

150 lines
5.1 KiB
Plaintext

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,
~~~
[php]
...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](http://www.yiiframework.com/doc/guide/database.arr).
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/views/post/_comments.php`.
Creating Comments
-----------------
To handle comment creation, we first modify the `actionView()` method of `PostController` as follows,
~~~
[php]
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,
~~~
[php]
......
<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:
~~~
[php]
<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].
~~~
[php]
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;
}
~~~
<div class="revision">$Id$</div>