CJuiDialog for create new model

You are viewing revision #3 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version or see the changes made in this revision.

« previous (#2)next (#4) »

  1. Introduction
  2. Scenario
  3. Preparation of the form
  4. Enhance the action create
  5. The dialog
  6. Summary

Introduction

In this tutorial we will learn how to realize a create interface using a dialog.

Here there is a similar tutorial that uses ajax link for achive the goal, but here we will use a simplier and more effective approach: the event onSubmit of the form.

Scenario

Let's immagine that we have a class with many students. If the user fill the form of the stundent and there is not the class, he has to create a class first, so loosing the input already inserted.

We want to allow the user to insert the class in the form of the students, without changing page.

Preparation of the form

First of all we need a form for instert the class. We can generate a Crud for class with gii and adapt the code to our needs.

Once we are satisfacted of our form that works with usual submit, we can use it in a dialog.

Enhance the action create

We need now to enhance the action create of the class controller.

Let's change in this way:

public function actionCreate()
	{
		$model=new Classs;

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

		if(isset($_POST['Classs']))
		{
			$model->attributes=$_POST['Classs'];
			if($model->save())
			{
				if (Yii::app()->request->isAjaxRequest)
				{
					echo CJSON::encode(array(
						'status'=>'success', 
						'div'=>"Class successfully added"
						));
					exit;				
				}
				else
					$this->redirect(array('view','id'=>$model->id));
			}
		}
		
		if (Yii::app()->request->isAjaxRequest)
		{
			echo CJSON::encode(array(
				'status'=>'failure', 
				'div'=>$this->renderPartial('_form', array('model'=>$model), true)));
			exit;				
		}
		else
			$this->render('create',array('model'=>$model,));
	}

We add some small changes: in case of ajax request we write a json encoded array.

In this array we return a status (failure/success) and the whole form created with renderPartial.

The dialog

Now the backend is done, let's write the dialog itself.

In the form of the student somewere we add this code:

<?php echo CHtml::link('Create class', "",  // the link for open the dialog
	array(
		'style'=>'cursor: pointer; text-decoration: underline;',
		'onclick'=>"{addClass(); $('#dialogClass').dialog('open');}"));?>

<?php
$this->beginWidget('zii.widgets.jui.CJuiDialog', array( // the dialog
    'id'=>'dialogClass',
    'options'=>array(
        'title'=>'Create class',
        'autoOpen'=>false,
        'modal'=>true,
		'width'=>550,
		'height'=>470,
    ),
));?>
<div class="divForForm"></div>

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

<script type="text/javascript">
// here is the magic
function addClass()
{
	<?php echo CHtml::ajax(array(
			'url'=>array('classs/create'),
			'data'=> "js:$(this).serialize()",
			'type'=>'post',
			'dataType'=>'json',
			'success'=>"function(data)
			{
				if (data.status == 'failure')
				{
					$('#dialogClass div.divForForm').html(data.div);
                          // Here is the trick: on submit-> once again this function!
					$('#dialogClass div.divForForm form').submit(addClass);
				}
				else
				{
					$('#dialogClass div.divForForm').html(data.div);
					setTimeout(\"$('#dialogClass').dialog('close') \",3000);
				}
				
			} ",
			))?>;
	return false; 
	
}

</script>

And that's all. In this code we have:

  • A link for open the dialog
  • the dialog itself, with a div inside that will be replaced with ajax
  • the javascript function addClass().

This function fires an ajax request to the action create we prepared in the previous step.

The returned form will be placed in the dialog (with eventually, all errors and so on) in case of status failure, in case of status success in the example we replace the div and we close the dialog after 3 seconds.

If you use this system in the form for student, you can return, for example, the id of the newly inserted class and select it authomatically in a ddl.

Summary

For make a long story short:

  • Prepare the usual creation with gii generated code
  • Change the action create for answer to ajax requests
  • Place the link/dialog/js wherever you want.

This methodology is very confortable because it changes anything in the code of the _form, so any evenutally added field in class will be available in both standard and dialog insert.