"copy and create" action for CRUD

It’s very convenient to have “copy and create” action for CRUD operations.

It enables you to copy the contents from an existing entry and paste them to the form to create a new one.

For example, when you are creating a large number of new entries in your address book, you’ll surely be bored with the repetitive task of inputting those data that are almost the same with each other, just with a little difference in some fields. There comes the handy action “copy and create” to help you.

It is very easy to extend your Gii-genarated CRUD codes to support "copy and create".

  1. In the controller, add a method to duplicate a model data.



public function duplicateModel($id)

{

	$model = $this->loadModel($id);

	// clean up data for new entry

	$model->id = null;   // clear the primary key value

	$model->foo = null;  // for example

	$model->bar = null;  // for example

	....                 // what should be cleared depends on the design of the model

	$model->isNewRecord = true;    // it's a new record

	return $model;

}



  1. In the controller, modify the actionCreate() method to accept a primary key as an argument.



public function actionCreate($id = null)

{

	$model = null;

	if ($id === null || isset($_POST['FooBar']))

		$model = new FooBar;

	else

		$model = $this->duplicateModel($id);


	// AJAX validation

	$this->performAjaxValidation($model);


	if (isset($_POST['FooBar']))

	{

		$model->attributes = $_POST['FooBar'];

		if ($model->save())

			$this->redirect(array('view', 'id'=>$model->id));

	}

	$this->render('create',array(

		'model' => $model,

	));

}



The argument $id should have the default value of null.

While the method continues to work as "create" aciton when $id is null, it will work as "copy and create" when $id is supplied.

  1. Add a link to invoke the action in the appropriate view file.

For example, in the view.php:




// views/FooBar/view.php

....

<?php echo CHtml::link('Copy and Create', array('create', 'id'=>$model->id)); ?>

....



Or in the admin.php:




// views/FooBar/admin.php

....

$this->widget('zii.widgets.grid.CGridView', array(

	'id' => 'foo-bar-grid',

	'dataProvider' => $model->search(),

	'filter' => $model,

	'columns' => array(

		'foo',

		'bar',

		....

		array(

			'class' => 'CButtonColumn',

		),

		array(

			'header' => 'Copy and Create',

			'type' => 'raw',

			'value' => 'CHtml::link("Copy and Create", array("create", "id"=>$data->id))',

		),

	),

));



That’s all. :D

Thanks,

This is exactly what i needed to get my forward message and reply message actions to work!

MAD

Am I missing something? When I create a new model it fails because of duplicate primary key. part_id is my primary key that is a auto increment. When i click on copy and create in say item 1. it takes me to mysite/parts/create/1 and so it’s acting like it’s being updated but with a create new button.


	public function duplicateModel($id)

	{

		$model = $this->loadModel($id);

		// clean up data for new entry

		$model->part_id = null;   // clear the primary key value

		$model->filename = null;  // list what should be cleared here

		$model->isNewRecord = true;    // it's a new record

		return $model;

	}

	/**

	 * Creates a new model.

	 * If creation is successful, the browser will be redirected to the 'view' page.

	 *also allowed to duplicate items based on parms set in duplicate model in this controller above

	 */

	public function actionCreate($id = null)

	{

		$model = null;

		if ($id === null || isset($_POST['Parts']))

			$model = new Parts;

		else

			$model = $this->duplicateModel($id);

	

		// AJAX validation

		$this->performAjaxValidation($model);

	

		if (isset($_POST['Parts']))

		{

			$model->attributes = $_POST['Parts'];

			if ($model->save())

				$this->redirect(array('view', 'id'=>$model->part_id));

		}

		$this->render('create',array(

			'model' => $model,

		));

	}

Hi skworden,

I’m not very sure, but you might have made a mistake in view script.




// views/FooBar/view.php

....

<?php echo CHtml::link('Copy and Create', array('create', 'id'=>$model->part_id)); ?>

....



Works Perfectly!!!.

I guess i cant copy and paste very well :P.