SilverStripe自定义HTML表单提交重定向后不显示成功消息怎么办
SilverStripe自定义表单提交后成功提示不显示的调整方案
控制器代码修正
当前控制器存在3个核心问题:
- 重复实例化Form对象,第一次创建的无字段、无动作的Form对象未挂载任何逻辑就被直接丢弃;第二次实例化时参数顺序完全错位:SilverStripe的Form构造参数顺序为
(控制器实例, 表单名, 字段列表, 动作列表),代码中将动作列表传到了本该放置字段列表的位置,导致表单本身没有完成正确初始化 - 定义好的提交动作没有传入Form构造函数,表单无法识别对应提交触发逻辑
- 表单未正确初始化时,调用
sessionMessage写入的提示会存在错误的session键值下,重定向后无法被模板读取
修正后的控制器代码:
public function HelloForm() { // 定义表单需要的所有字段,和模板中的输入框一一对应 $fields = FieldList::create( EmailField::create('Email', 'Email:'), PasswordField::create('Password', 'Password:') ); // 定义提交动作 $actions = FieldList::create( FormAction::create('doSayHello', 'Submit') ->setAttribute('class', 'btn btn-success') ); // 按正确参数顺序实例化表单 return Form::create( $this, 'HelloForm', $fields, $actions ); } public function doSayHello($data, $form) { // 写入会话存储的成功提示 $form->sessionMessage('感谢您的联系', 'good'); // 重定向回原页面 return $this->redirectBack(); }
模板代码修正
当前模板存在3个核心问题:
- 手写的input元素没有挂载到Form对象的字段列表上,和表单的字段映射完全脱节
- 试图用hidden input伪装成提交动作是无效的:SilverStripe靠FormAction生成的特定name属性路由提交逻辑,手写的hidden字段不会被系统识别为提交触发器,导致提交请求根本没有走到
doSayHello方法 - 消息展示块没有做存在性判断,无消息时也会渲染空的占位标签
修正后的自定义结构模板代码:
<form class="form-inline" $HelloForm.FormAttributes> <%-- 仅在存在会话提示时渲染展示块 --%> <% if $HelloForm.Message %> <p id="{$HelloForm.FormName}_success" class="message $HelloForm.MessageType"> $HelloForm.Message </p> <% end_if %> <div class="form-group"> <label for="{$HelloForm.dataFieldByName('Email')->ID}">Email:</label> <%-- 给表单自动渲染的字段加自定义样式类和占位符 --%> {$HelloForm.dataFieldByName('Email')->addExtraClass('form-control')->setAttribute('placeholder','Enter email')} </div> <div class="form-group"> <label for="{$HelloForm.dataFieldByName('Password')->ID}">Password:</label> {$HelloForm.dataFieldByName('Password')->addExtraClass('form-control')->setAttribute('placeholder','Enter password')} </div> <%-- 自动渲染表单动作按钮,不需要手写hidden元素 --%> {$HelloForm.Actions} </form>
必注意事项
- 不要依赖模板手写的input作为表单提交的字段,必须在控制器的Form实例中显式定义所有参与提交、校验的字段,否则表单无法正确识别请求内容,也无法正确读写绑定在表单上的会话消息
- 不要删除
$HelloForm.FormAttributes,这个属性会自动生成表单的提交地址、CSRF校验值等必填属性,缺失的话会直接导致提交请求被拦截 - 只要保证控制器实例化的HelloForm在提交请求、重定向后的页面加载两个场景下参数完全一致,
sessionMessage写入的提示会自动通过会话机制存储,重定向后即可正常展示
内容的提问来源于stack exchange,提问作者Ajay Sajwan
相关产品推荐
相关产品推荐

