Reusing subforms on multiple forms

Hi all,

The app I’m building has many different models that all share links to several common tables (such as Contacts, File-notes, Address).

When building forms for these entities I’m including a sub-form for one or more of these common tables in each form. I want to do this with as simply as possible.

I’ve chosen to do this by adding a sub-form property to my recurring table Models. I will also add an action to the controllers of these models to manage the Create & Update logic (linking to the parent record etc.)

Here is a cut-down look at my method, please let me know if you have a better way, or if you think my way has merit. cheers Paul.

1. For reusability add repeatedly called CForm values to their Model (protected/models/Contact.php) as a property


	// Details required to load model as a subform in a CForm object

	private $_subform = array(

            'type'=>'form',

            'title'=>'CContact information',

            'elements'=>array(

                'contact_name'=>array(

                    'type'=>'text',

                ),

                'contact_role'=>array(

                    'type'=>'text',

                ),

            ),

        );


public function getSubform(){

        return $this->_subform;

}

2. Create a ’containing’ page for our form (protected/views/customer/create.php)…


 <?php

//Usual guff - breadcrumbs & action menu

$this->breadcrumbs=array(

	'Customers'=>array('index'),

	'Create',

);


$this->menu=array(

	array('label'=>'List Customer', 'url'=>array('index')),

	array('label'=>'Manage Customer', 'url'=>array('admin')),

);

?>


<h1>Create Customer</h1>

//Then just echo our $form object (detailed below)

<div class="form">

<?php echo $form; ?>

</div>

3. Create a CForm array page for our form (protected/views/customer/createForm.php)…

This defines the values we want to be rendered by our CForm object


<?php

return array(

    'elements'=>array(

        'customer'=>array(

            'type'=>'form',

            'title'=>'Customer information',

            'elements'=>array(

                'customer_name'=>array(

                    'type'=>'text',

                ),

            ),

        ),

         

	//This is a property added to the Model to generate the array we want (detailed below)

	'contact'=>Contact::model()->subform,

    ),

 

    'buttons'=>array(

        'register'=>array(

            'type'=>'submit',

            'label'=>'Register Customer',

        ),

    ),

);

?>

4. Define an action to request our form (protected/controllers/customerController.php)…


public function actionCreate()

{

    // Instantiate a CForm object - detailed in later sections

    $form = new CForm('application.views.customer.createForm');


    //Associate models with the ‘school’ & ‘parish’ elements of $form

    $form['customer']->model = new Customer;

    $form['contact']->model = new Contact;


    //If the form has been submitted, then validate save records and redirect 

    if($form->submitted('register') && $form->validate())

    {

		$customer = $form['customer']->model;

		$contact = $form['contact']->model;

		if($customer->save(false))

		{

			//This code will end up as a public function on the Contact controller

			$contact->model = 'Customer';

			$contact->model_id = $customer->idcustomer;

			$contact->save(false);


			$this->redirect(array('site/index'));

		}	

      }

	

    //Render up the containing page, passing it the $form object we have built

	$this->render('create',array('form'=>$form,));

}

[font="arial, sans-serif"][size="3"][color="#333333"]

You can put the subform in a separate view …

and then, use renderPartial () to add in the other view …[/color][/size][/font]