Difference between #3 and #2 of CJuiDialog for create new model

unchanged
Title
CJuiDialog for create new model
unchanged
Category
Tutorials
changed
Tags
juidialog, user interfaceinterface, AJAX
unchanged
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") 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:



~~~
[php]
	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]

<?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.