Is Widget used to render content only?

I browsed the source code for zii widget. There is no controller/action in widget. Does it mean widget is used to render html element only like CMenu?

I’d like to place a form and a button in a widget to provide login feature. Is this possible?

Thank you!

hello,

I hope I understand your question right, but you can render in the widget’s run() whatever you’d like … something like this …




class SomeWidget extends CWidget

{

  // properties, init code etc ...


  public function run()

  {

    $this->render( '_someview' [, array( variables if you have any )] );

  }

}



and you can create a views folder in your components folder and put _someview.php there …

i hope it helps

–iM

Yes, that’s the standard way to extend a Yii CWidget. But I want to use Widge to handle a user input, e.g. a login form. Where shall I write the form submission script in the widget( if isset($_Post[User]) {…})?

As a beginner, my question may go to the ditch… Please let me know any better way to do it.Thanks!

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 .

yes,

you definitely need a controller to handle your requests! let it be AJAX or not. If you are trying to build a more "mobile" solution, you might want to write a module, and put your widget and controller code etc there.

and then, you can just “plug-n-play” and share :)

http://www.yiiframework.com/doc/guide/1.1/en/basics.module

–iM

Hi twisted1919,

Thanks for sharing that with me. This line of code I think can solve my problem:


<?php echo CHtml::form( Yii::app()->createUrl('user/guest/login') ,'post', array('id'=>'loginForm'));?>

It directs the handling to the the login action in Guest controller in User Module! It’s where I stuck, because I don’t know it can be done this way. Nothing like this mentioned anywhere in the Tutorials or Guide.

How did you learn about this?

Well, please don’t expect to find everything in the guide, because is not possible for the guide to cover everything.

Instead, build the idea into your mind, have a plan on how you want to achieve a task, then go to YII class documentation and grab the methods you need for that task.

Also, don’t be afraid to ask on these forums, here you will learn a lot of useful things about YII, but please do a search first time, because there might be persons having same issues like you who already are solved in the forums .

Great example twisted1919. But there is a general failure (feature) in this concept:

If you put widget to the layout, out of view template, there is no way to pass variables to the widget from handling Controller::action(). You need this, if you want for example search/login form on every page of the site (layout), and want to validate this form - you need pass $model back to the widget, but there is no way.




+-----------------------+

| +-------------------+ |  (post)

| |         [widget] =============> ArticleController::search(){

| +-------------------+ |             $model = new SearchForm();

| +-------------------+ |             $model->attributes = $_POST['widget'];

| |[$content]         | |             $model->validate();

| | ^                 | |

| | |                 | | (errors)    $this->render('search', array(

| | \================================== 'model'=>$model

| |                   | |             ));

| +-------------------+ |           }

+-----------------------+



Does anyone have solution?