I am trying to create a single page that will display multiple userforms in a tabbed view. For example basic contact form, request a quote form etc.
I thought I could make a new page type and loop through the children to display the forms, but the $Form variable isn't rendering the form.
<% loop $Children %>
<div>
<h2>$Title</h2>
$Form
</div>
<% end_loop %>
Am I missing something here, or is there a different way to render a form using a its ID in a template file?
You could try the following.
Create a function in your page holder controller to get the form from a specific child (must be a UserDefinedForm page). To do this you'll need to create the controller of this child page.
public function ChildForm($pageID) {
$page = UserDefinedForm::get()->byID($pageID);
$controller = UserDefinedForm_Controller::create($page);
return $controller->Form();
}
afterwards you'll call this function in your loop and pass the current child id to it
<% loop $Children %>
<div>
<h2>$Title</h2>
$Top.ChildForm($ID)
</div>
<% end_loop %>
This should (code is untested) return the forms you want.
The problem at play here is the difference between the DataObject
/Page
and the Controller
. Looping over $Children
returns you a DataObject
whereas the Form
function and template variable are part of UserDefinedForm
's controller.
The other answer shows one working solution however it has some hair on it:
UserDefinedForm
We can implement a more generic solution that removes some of those elements and making your code a little more maintainable.
Take the following which would be added to the Page
class (not the controller):
function getInLoopForm() {
if (in_array('UserDefinedForm', $this->ClassAncestry)) {
$controllerName = $this->ClassName . '_Controller';
$controller = $controllerName::create($this);
if ($controller->hasMethod('Form')) {
return $controller->Form();
}
}
return false;
}
The first part of that checks whether the current object has UserDefinedForm
in its class ancestry. If it is, we then create the appropriate controller and return the form.
Your template code would look like this instead:
<% loop $Children %>
<div>
<h2>$Title</h2>
$InLoopForm
</div>
<% end_loop %>
This solution is generic for three reasons:
getInLoopForm
function, the value "UserDefinedForm" can be replaced with any class that extends Page
. It could even be brought out to a YML value if you were so inclined.UserDefinedForm
and its controller and we can still call the right function.DataObject
to access the form, you don't need your own controller.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With