Today I found myself reworking a set of directory classes I wrote in haste a few months ago. I decided that some of them would gain from making use of DB_DataObject_FormBuilder but had to remind myself of how to make that package work with multiple tables.
The presentation included as part of the documentation demonstrates how to create a form with data from multiple tables, using something like:
$first_table =& DB_DataObject::factory('table_one');
$first_table->fb_createSubmit = false;
$first_build =& DB_DataObject_FormBuilder::create($first_table);
$first_form = $first_build->getForm();
$second_table = DB_DataObject::factory('table_two');
$second_build =& DB_DataObject_FormBuilder::create($second_table);
$second_build->useForm($first_form);
print $second_build->toHTML();
Personally, I’m not a fan of the headers that QuickForm (the form class behind FormBuilder) adds for each table, so after a little hunting around I discovered that:
$first_table->fb_addFormHeader = false;
would get rid of those.
What wasn’t clear from the documentation is how to validate and process the form that is produced from these two tables. I briefly wondered if ‘useForm’ would join the validation and processing terms, but as I suspected it didn’t. If you’re creating new entries for both tables, what you’ll want to do is something like:
if ($first_form->validate() && $second_form->validate()) {
$first_form->process(array(&$first_build,'processForm'), false);
$first_table->link_field = $second_table->link_field;
$second_form->process(array(&$second_build,'processForm'), false);
}
Of course, if you’re using the forms to edit content rather than create new rows in the database, your DataObjects will be pre-loaded with the relevant IDs and so that middle line, setting the keys won’t be necessary.
Aside: I’ve a lot of sympathy with Paul Jones’ comments on HTML_QuickForm and MVC. Right now I’m setting up my forms with the relevant data in the model layer and then passing a reference to the object to the view layer so that it can handle the output. That works okay for now, but if there’s a more elegant solution out there I’d love to know!