A few hours ago, i had to write a login/register popup and i used a widget for this.
Here is how i did it, in short lines, as the code is way too long:
//application.components.GuestWidget.php
<?php
class GuestPopup extends CWidget{
public function run()
{
$this->render('guestPopup');
}
}
//application.components.views.guestPopup.php (the view file for the widget)
<div class="loginWindowHolder">
<div class="loginWindow">
<?php echo CHtml::form( Yii::app()->createUrl('user/guest/login') ,'post', array('id'=>'loginForm'));?>
[INPUT FIELDS HERE]
</form>
</div>
</div>
<script>
$(function(){
$('.loginWindowButton').click(function(){
[SHOW THE LOGIN POPUP]
});
$('form#loginForm').live('submit',function(){
[DO SOMETHING HERE]
return false;
});
});
</script>
The view file is simple enough, just javascript and html to handle the look and the way the content interacts with the user.
You can pass params to the widget, like the model, but i didn’t do it because i think is overkill to do it in this particular case.
Now,i needed this popup in each page of the website, so in my layout file, i have something like:
<div id="loginRegister">
<?php if(Yii::app()->user->isGuest):?>
<a href="javascript:;" class="white registerWindowButton">Register</a> | <a class="white loginWindowButton" href="javascript:;">Login</a>
<?php else:?>
<a class="white" href="javascript:;">Hi <?php echo Yii::app()->user->getName();?></a> | <a class="white" href="<?php echo Yii::app()->createUrl('user/default/logout');?>">Logout</a>
<?php endif;?>
</div>
<?php if(Yii::app()->user->isGuest):?>
<?php $this->widget('application.components.GuestPopup');?> [THIS IS THE WIDGET CALL]
<?php endif;?>
Then, all you have to do, is a controller to handle the form submission, in my case this is a module, so i did all the form processing in /user/DefaultController.php
What you need to know, is that a widget is used to show something to a user(a notification/a form etc) BUT not process the data that comes from that user, the widget is just an interface between the user and the controller and the data needs to be processed by a controller/model and return the result of the process in a way that the widget expects to get, so that again, the widget can present the result of the action, to the user.
Think like, the widget shows a form and has the javascript code for sending the form via ajax to the controller.
The controller receives the data and sends it to the model which validates it and saves it if it is the case.
The model returns the result of validation/saving to the controller which uses CJSON::encode() to send back the result of the model validation to the widget.
The widget then, sees the result, and notifies the user.
Hope you can understand what i mean .