Difference between #5 and #4 of CJuiDialog for create new model

unchanged
Title
CJuiDialog for create new model
unchanged
Category
Tutorials
unchanged
Tags
juidialog, user interface, AJAX
changed
Content
Introduction
------------------

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

[Here](http://www.yiiframework.com/wiki/72/cjuidialog-and-ajaxsubmitbutton
"other tutorial") is a similar tutorial that uses Ajax link to achieve
the goal, but we will use a simpler and more effective approach: the event
onSubmit of the form.

Scenario
------------------

Let's imagine we have a classroom with many students. If the user fills in the
form of the student and there is no classroom made, he will have to create a
classroom first and lose the already inserted input.

We want to allow the user to create the classroom from the form of the student,
without changing pages.

Preparation of the form
------------------

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

Once we are satisfied with our form and it works with the usual submit, we can
use it in a dialog.

Enhance the action create
------------------

We need to enhance the action create of the classroom controller.

Let's change it this way:



~~~
[php]
	public function actionCreate()
	{
		$model=new Classroom;

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

		if(isset($_POST['Classroom']))
		{
			$model->attributes=$_POST['Classroom'];
			if($model->save())
			{
				if (Yii::app()->request->isAjaxRequest)
				{
					echo CJSON::encode(array(
						'status'=>'success', 
						'div'=>"Classroom 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 back-end is done, let's write the dialog itself.

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



~~~
[php]

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

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

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

<script type="text/javascript">
// here is the magic
function addClassroom()
{
	<?php echo CHtml::ajax(array(
			'url'=>array('classroom/create'),
			'data'=> "js:$(this).serialize()",
			'type'=>'post',
			'dataType'=>'json',
			'success'=>"function(data)
			{
				if (data.status == 'failure')
				{
					$('#dialogClassroom div.divForForm').html(data.div);
                          // Here is the trick: on submit-> once again this
function!
					$('#dialogClassroom div.divForForm form').submit(addClassroom);
				}
				else
				{
					$('#dialogClassroom div.divForForm').html(data.div);
					setTimeout(\"$('#dialogClassroom').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 addClassroom().

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 classroom and select it automatically in a drop down
list.

Summary
------------------

ForTo 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 comfortable because it changes anything in the code of
the _form, so any eventually added field in classroom will be available in both
standard and dialog insert.