Thursday, January 24, 2013

Creating Data Picker Using Yii Framework [Part 2]

Read the first Part  :: Contain the database and basic creating / generating models / crud


CJUIDIALOG

In these part 2 I will concentrate on CJuiDialog on how to create pop up button. If you need explanation bit further go to this http://www.yiiframework.com/doc/api/1.1/CJuiDialog/.

Now lets start coding. I will creating button that will open dialog.

Open protected\views\post\_form.php and add this code, if you now javascript it will help.

<input type="button" value="Get List User" name="get_user_btn" onclick="$('#mydialog').dialog('open'); return false;" > 

So you will get
<div class="row">
        <?php echo $form->labelEx($model,'id_user'); ?>
        <?php echo $form->textField($model,'id_user'); ?>
        <input type="button" value="Get List User" name="get_user_btn" onclick="$('#mydialog').dialog('open'); return false;" >
        <?php echo $form->error($model,'id_user'); ?>
    </div>

This image should help

[Creating Button]



As you can see we only creating a button and nothing happens if you click it.

Add these code at very bottom of the page


<?php
    $this->beginWidget('zii.widgets.jui.CJuiDialog',array(
    'id'=>'mydialog',
    // additional javascript options for the dialog plugin
    'options'=>array(
        'title'=>'List User',
        'autoOpen'=>false,
    ),
));

    echo 'CGRIDVIEW here';
    // these area will be filled with CGridView

$this->endWidget('zii.widgets.jui.CJuiDialog');
?>



So the overall  code will look like this

<?php
/* @var $this PostController */
/* @var $model Post */
/* @var $form CActiveForm */
?>

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'post-form',
    'enableAjaxValidation'=>false,
)); ?>

    <p class="note">Fields with <span class="required">*</span> are required.</p>

    <?php echo $form->errorSummary($model); ?>

    <div class="row">
        <?php echo $form->labelEx($model,'id_user'); ?>
        <?php echo $form->textField($model,'id_user'); ?>
        <input type="button" value="Get List User" name="get_user_btn" onclick="$('#mydialog').dialog('open'); return false;" >
        <?php echo $form->error($model,'id_user'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'title'); ?>
        <?php echo $form->textField($model,'title',array('size'=>60,'maxlength'=>250)); ?>
        <?php echo $form->error($model,'title'); ?>
    </div>

    <div class="row buttons">
        <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
    </div>

<?php $this->endWidget(); ?>

</div><!-- form -->

<?php 
    $this->beginWidget('zii.widgets.jui.CJuiDialog',array(
    'id'=>'mydialog',
    // additional javascript options for the dialog plugin
    'options'=>array(
        'title'=>'List User',
        'autoOpen'=>false,
    ),
));

    echo 'CGRIDVIEW here';
    // these area will be filled with CGridView

$this->endWidget('zii.widgets.jui.CJuiDialog');
?>



Now if you click the button, it pop up a dialog. This dialog will hold the cgridview later on. This is the end result

CGRIDVIEW

Now for the cgridview with list of users. To make it more simple, I’m just gonna copy paste the code from protected\controllers\UserController.php in function actionAdmin which hold the code for viewing data in CGridView into protected\controllers\PostController.php at function actionCreate and actionUpdate.

First lets just open protected\controllers\UserController.php and go to function actionAdmin.

public function actionAdmin()

    {

        $model=new User('search');

        $model-&gt;unsetAttributes();  // clear any default values

        if(isset($_GET['User']))

            $model-&gt;attributes=$_GET['User'];

        $this-&gt;render('admin',array(

            'model'=&gt;$model,

        ));

    }


Now just copy paste these part of the code

<?php
$model=new User('search');

        $model-&gt;unsetAttributes();  // clear any default values

        if(isset($_GET['User']))

            $model-&gt;attributes=$_GET['User'];
?>


Into protected\controllers\PostController.php at function actionCreate and don’t forget to change the variable into $modelUser so you wont messed with the code to create post.

These are the end result at protected\controllers\PostController.php. and also don’t forget to render it into view

<?php
public function actionCreate()
    {
// don’t forget to change variable $model into $modelUser or something else.
        $modelUser=new User('search');
        $modelUser->unsetAttributes();  // clear any default values
        if(isset($_GET['User']))
            $modelUser->attributes=$_GET['User'];
// if you forget it will messed up these code to create new Post        
        $model=new Post;

        // Uncomment the following line if AJAX validation is needed
        // $this->performAjaxValidation($model);

        if(isset($_POST['Post']))
        {
            $model->attributes=$_POST['Post'];
            if($model->save())
                $this->redirect(array('view','id'=>$model->id));
        }

        $this->render('create',array(
            'model'=>$model,
// Don’t forget to pass the variable value into the view
'modelUser'=>$modelUser
        ));
    }
?>


From this code you still doesn’t change anything at the form, if you refresh the page it should be nothing happens that just because we have not yet to modified the view files.

Now lets open the view that holds the form which is at protected\views\post\create.php

Add these 1 line of code

<?php echo $this->renderPartial('_form', array(
            'model'=>$model,
// add these line to ensure that the value is passed on into the form view
            'modelUser'=>$modelUser
            )); ?>

After these point you should notice that the value from modelUser is successfully passed into the form view.

Now lets just add the CGridView that holds user data into the CJuiDialog.
To add the CGridView, we just doing a simple copy paste and edit from the protected\views\user\admin.php

Open protected\views\user\admin.php and copy paste these code

<?php
$this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'user-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        'id',
        'user',
        array(
            'class'=>'CButtonColumn',
        ),
    ),
));
?>


Into the protected\views\user\form.php, right in the middle of CJuiDialog Widget, so the end result in CJuiDialog will be looking like this.

<?php 
    $this->beginWidget('zii.widgets.jui.CJuiDialog',array(
    'id'=>'mydialog',
    // additional javascript options for the dialog plugin
    'options'=>array(
        'title'=>'List User',
        'autoOpen'=>false,
    ),
));

   // echo 'CGRIDVIEW here';
    // these area will be filled with CGridView
    $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'user-grid',
    // dont forget to change the model into $modelUser
    'dataProvider'=>$modelUser->search(),
    'filter'=>$modelUser,
    'columns'=>array(
        'id',
        'user',
    // and dont forget to clear these function 
        // array(
            // 'class'=>'CButtonColumn',
        // ),
    ),
));

$this->endWidget('zii.widgets.jui.CJuiDialog');
?>

So the end result will be looking like these


[CJuiDialog with CGridView]

Now that we can view the list of user from the CJuiDialog, but we still can’t pass anything into the form, at least we made a quite progress with just doing a few lines of codes.

Creating Custom Button on CGridView Field

To pass the id user value from the cgridview I need a simple button that will pass the value into the form. A simple javascript should do.

If you want learn more about custom button or custom Field please refer to this http://www.yiiframework.com/doc/api/1.1/CGridView if you scroll down and see the comments of the page you’ll notice that some developer sending a few modified code.

Let’s just start adding a button onto the cgridview that will close the dialog when we click it. Add these code

<?php
array(
    'header'=>'',
    'type'=>'raw',
    'value'=>'CHtml::Button("+"    
    , array(
        "name" => "get_link",
        "id" => "get_link",
        "onClick" => "$(\"#mydialog\").dialog(\"close\");"))',
    ),
?>

Into CgridView columns so the end result of the code will be like these

<?php 
    $this->beginWidget('zii.widgets.jui.CJuiDialog',array(
    'id'=>'mydialog',
    // additional javascript options for the dialog plugin
    'options'=>array(
        'title'=>'List User',
        'autoOpen'=>false,
    ),
));

   // echo 'CGRIDVIEW here';
    // these area will be filled with CGridView
    $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'user-grid',
    // dont forget to change the model into $modelUser
    'dataProvider'=>$modelUser->search(),
    'filter'=>$modelUser,
    'columns'=>array(
        'id',
        'user',
    // and dont forget to clear these function 
        // array(
            // 'class'=>'CButtonColumn',
        // ),
        array(
                                'header'=>'',
                                'type'=>'raw',
                                'value'=>'CHtml::Button(
                                        "+"
                                        , array(
                                            "name" => "get_link"
                                            , "id" => "get_link"
                                            , "onClick" => "$(\"#mydialog\").dialog(\"close\");"))',
                            ),
    ),
));
$this->endWidget('zii.widgets.jui.CJuiDialog');
?>

You’ll get a custom button in each row, these button will close and pass the value into the form. But for now it’s just closing the dialog first.


[CGridView Buttons]

Now the cute part of the tutorial, we have to pass the id_user value from the cgridview into the form, we will be using javascript a little bit but there is a catch, you have to know the html id of the textfield.
Open view page source by right clicking the page and view the html id of the textfield.



[View Page Source]

And get the html id of the id user textfield




[name of the field]

Or you can just use FireBug inspect element, firebug is a firefox extension for developer which help debug your web site

[firebug name of the field ]

So after viewing the source we know that the html id of the textfield is Post_id_user, we can just do simple jquery like $(\"# Post_id_user \").val(\"". $data->id."\");

So lets add this to our code

<?php
array(    
    'header'=>'',
    'type'=>'raw',
    'value'=>'CHtml::Button(
        "+"
        , array(
        "name" => "get_link"
        , "id" => "get_link"
        , "onClick" => "$(\"#mydialog\").dialog(\"close\");$(\"#Post_id_user \").val(\"". $data->id."\");"))',
    ),
?>

With these code you already passing the id of user into the form.

[Passing Value to Form]

But still it’s not too pretty,  user have to know the name not just the id of user.

First we create a textfield that will hold the name of the user, and hide the id_user textfield.
Modified the id_user textfield into hiddenfield, and then add some text field which hold the name of the user, I add few code into the value of user name field so that when we updating the form, the name of user will show up

<div class="row">
        <?php echo $form->labelEx($model,'id_user'); ?>
        <?php echo $form->hiddenField($model,'id_user'); ?>
        <input type="text" id="user_name" name="user_name" value="<?php echo isset($model->id_user) ? User::model()->findByPk($model->id_user)-> user : "" ?>" readonly >
        <input type="button" value="Get List User" name="get_user_btn" onclick="$('#mydialog').dialog('open'); return false;" >
        <?php echo $form->error($model,'id_user'); ?>
    </div>

And don’t forget to add few lines into CGridView Button, add this code $(\"#user_name \").val(\"". $data-> user."\"); to the button

This is the end result of the CGridVIew

<?php 
    $this->beginWidget('zii.widgets.jui.CJuiDialog',array(
    'id'=>'mydialog',
    // additional javascript options for the dialog plugin
    'options'=>array(
        'title'=>'List User',
        'autoOpen'=>false,
    ),
));

   // echo 'CGRIDVIEW here';
    // these area will be filled with CGridView
    $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'user-grid',
    // dont forget to change the model into $modelUser
    'dataProvider'=>$modelUser->search(),
    'filter'=>$modelUser,
    'columns'=>array(
        'id',
        'user',
    // and dont forget to clear these function 
        // array(
            // 'class'=>'CButtonColumn',
        // ),
        array(
                                'header'=>'',
                                'type'=>'raw',
                                'value'=>'CHtml::Button(
                                        "+"
                                        , array(
                                            "name" => "get_link"
                                            , "id" => "get_link"
                                            , "onClick" => "$(\"#mydialog\").dialog(\"close\");$(\"#Post_id_user \").val(\"". $data->id."\");$(\"#user_name \").val(\"". $data->user."\");"))',
                            ),
    ),
));

$this->endWidget('zii.widgets.jui.CJuiDialog');
?>


And this is the image for the end result

[End Result]

No comments: