Silverstripe Multiple Userforms on one page

南笙酒味 提交于 2019-12-07 04:44:16

问题


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?


回答1:


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.




回答2:


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:

  • Jumping scope to your controller to pass an ID to get your form
  • Additional DB query
  • Requires all the child pages to be of type 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:

  • In our 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.
  • For SilverStripe, controller names for pages must match "{PageClassName}_Controller" so we can abuse that by working out the controller name dynamically. This allows for you to extend UserDefinedForm and its controller and we can still call the right function.
  • You only require your DataObject to access the form, you don't need your own controller.



回答3:


For SS 4 there is a small code change needed:

public function getInLoopForm() {
    if (in_array('SilverStripe\UserForms\Model\UserDefinedForm', $this->ClassAncestry)) {
        $controller = UserDefinedFormController::create($this);
        if ($controller->hasMethod('Form')) {
            return $controller->Form();
        }
    }
    return false;
}


来源:https://stackoverflow.com/questions/34888010/silverstripe-multiple-userforms-on-one-page

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!