分步表单

简单示例

  1. protected function form()
  2. {
  3. return Form::make(new Model(), function (Form $form) {
  4. $form->title('分步表单');
  5. $form->action('step');
  6. $form->disableListButton();
  7. $form->multipleSteps()
  8. ->remember()
  9. ->width('950px')
  10. ->add('基本信息', function (Form\StepForm $step) {
  11. $info = '<i class="fa fa-exclamation-circle"></i> 表单字段支持前端验证和后端验证混用,前端验证支持H5表单验证以及自定义验证。';
  12. $step->html(Alert::make($info)->info());
  13. $step->text('name', '姓名')->required()->maxLength(20);
  14. // h5 表单验证
  15. $step->text('age', '年龄')
  16. ->required()
  17. ->type('number')
  18. ->attribute('max', 150)
  19. ->help('前端验证');
  20. $step->radio('sex', '性别')->options(['未知', '男', '女'])->default(0);
  21. // 后端验证
  22. $step->text('birthplace', '籍贯')
  23. ->rules('required')
  24. ->help('演示后端字段验证');
  25. $step->url('homepage', '个人主页');
  26. $step->textarea('description', '简介');
  27. })
  28. ->add('兴趣爱好', function (Form\StepForm $step) {
  29. $step->tags('hobbies', '爱好')
  30. ->options(['唱', '跳', 'RAP', '踢足球'])
  31. ->required();
  32. $step->text('books', '书籍');
  33. $step->text('music', '音乐');
  34. // 事件
  35. $step->shown(function () {
  36. return <<<JS
  37. Dcat.info('兴趣爱好');
  38. console.log('兴趣爱好', args);
  39. JS;
  40. });
  41. })
  42. ->add('地址', function (Form\StepForm $step) {
  43. $step->text('address', '街道地址');
  44. $step->text('post_code', '邮政编码');
  45. $step->tel('tel', ' 联系电话');
  46. })
  47. ->done(function () use ($form) {
  48. $resource = $form->getResource(0);
  49. $data = [
  50. 'title' => '操作成功',
  51. 'description' => '恭喜您成为第10086位用户',
  52. 'createUrl' => $resource,
  53. 'backUrl' => $resource,
  54. ];
  55. return view('admin::form.done-step', $data);
  56. });
  57. });
  58. }

效果

分步表单 - 图1

运行逻辑

分步表单的使用很简单,运行逻辑也与普通表单没有太大区别,下面简单说说分步表单的运行逻辑。

{tip} 分步表单没有 update 的概念。

参数验证

当用户点击 下一步 时,会向后端发起请求验证参数是否正确,如果参数不符合要求则显示错误信息,验证通过才会进入下一个步骤。

表单提交

当进行到最后一步时,会对所有步骤的表单参数一起提交到后端并进行验证,如果参数不符合要求则显示错误信息,验证通过则保存表单数据,保存的方法与普通表单完全一致。

{tip} 最后保存表单的方法是 Form::store

完成页面

表单保存完成之后会显示完成页面,此步骤无法忽略。

编辑表单

分步表单默认是没有编辑功能的,用户输入了长步骤的表单之后不需要再分步编辑,因此如果需要对分步表单进行编辑,可以参考以下方式

  1. protected function form()
  2. {
  3. return Form::make(new MyRepository(), function (Form $form) {
  4. // 判断是否是编辑页面
  5. if ($form->isEditing()) {
  6. $form->text('age', '年龄')
  7. ->required()
  8. ->type('number')
  9. ->attribute('max', 150)
  10. ->help('前端验证')
  11. ...
  12. return;
  13. }
  14. $form->multipleSteps()
  15. ->remember()
  16. ->width('950px')
  17. ->add('基本信息', function (Form\StepForm $step) {
  18. $info = '<i class="fa fa-exclamation-circle"></i> 表单字段支持前端验证和后端验证混用,前端验证支持H5表单验证以及自定义验证。';
  19. $step->html(Alert::make($info)->info());
  20. $step->text('name', '姓名')->required()->maxLength(20);
  21. // h5 表单验证
  22. $step->text('age', '年龄')
  23. ->required()
  24. ->type('number')
  25. ->attribute('max', 150)
  26. ->help('前端验证');
  27. $step->radio('sex', '性别')->options(['未知', '男', '女'])->default(0);
  28. ...
  29. })
  30. ->add('兴趣爱好', function (Form\StepForm $step) {
  31. ...
  32. })
  33. ->done(function () use ($form) {
  34. ...
  35. });
  36. });
  37. }

功能接口

设置容器最大宽度

默认 1000px

{tip} 此方法只针对大屏幕,手机端页面会自动调节大小。

  1. $form->multipleSteps()->width('900px');

记住表单数据

开启此功能之后,当用户点击 下一步 按钮并且参数验证通过后,会把表单数据保存在 session 中,直到整个分步表单保存完毕之后才会销毁。

{tip} 此功能默认不开启。

  1. // 开启
  2. $form->multipleSteps()->remember();
  3. // 关闭
  4. $form->multipleSteps()->remember(false);

设置容器间距

默认值 30px 18px 30px

  1. $form->multipleSteps()->padding('30px 18px 30px');

监听页面离开事件

监听所有步骤表单页面离开事件,可添加多个。

  1. $form->multipleSteps()->leaving(<<<JS
  2. // 获取当前页面的步骤索引
  3. var index = args.index;
  4. Dcat.info("你将要离开第 " + (index + 1) + " 个页面");
  5. // args变量是一个js对象,包含当前事件对象、当前步骤选项、表单对象和表单值等字段。
  6. console.log("leaving", args);
  7. // 获取当前事件对象
  8. var evt = args.event;
  9. // 获取步骤表单标题tap对象
  10. var tab = args.tab;
  11. // 获取动向是前往上一步还是下一步页面:"forward"、"backward"
  12. var direction = args.direction;
  13. // 获取当前步骤的表单JQ对象
  14. var $form = args.form;
  15. // 获取当前步骤页的表单值
  16. var formArray = args.formArray;
  17. // 获取指定步骤的表单JQ对象
  18. var $firstForm = args.getForm(0);
  19. // 获取指定步骤的表单值
  20. var firstFormArray = args.getFormArray(0);
  21. // 停止离开当前页面
  22. return false;
  23. JS
  24. )->leaving(...);

监听页面显示事件

监听所有步骤表单页面显示事件,可添加多个。

  1. $form->multipleSteps()->shown(<<<JS
  2. // 获取当前页面的步骤索引
  3. var index = args.index;
  4. Dcat.info("当前显示的是第 " + (index + 1) + " 个页面");
  5. // args变量的值与“leaving”事件的值相同。
  6. console.log("shown", args);
  7. JS
  8. )->shown(...);

增加步骤表单

步骤表单支持所有表单字段。

  1. use Dcat\Admin\Form;
  2. $form->multipleSteps()->add('标题', function (Form\StepForm $step) {
  3. $step->text('username')->rules('required');
  4. ...
  5. });

监听步骤页面离开事件

监听当前步骤页面离开事件,支持监听多次。

  1. use Dcat\Admin\Form;
  2. $form->multipleSteps()->add('基本信息', function (Form\StepForm $step) {
  3. ...
  4. $step->leaving(<<<JS
  5. Dcat.info("你将要离开 基本信息 页面");
  6. // args变量是一个js对象,包含当前事件对象、当前步骤选项、表单对象和表单值等字段。
  7. console.log("离开 基本信息", args);
  8. // 获取当前事件对象
  9. var evt = args.event;
  10. // 获取当前页面的步骤索引
  11. var index = args.index;
  12. // 获取步骤表单标题tap对象
  13. var tab = args.tab;
  14. // 获取动向是前往上一步还是下一步页面:"forward"、"backward"
  15. var direction = args.direction;
  16. // 获取当前步骤的表单JQ对象
  17. var $form = args.form;
  18. // 获取当前步骤页的表单值
  19. var formArray = args.formArray;
  20. // 获取指定步骤的表单JQ对象
  21. var $firstForm = args.getForm(0);
  22. // 获取指定步骤的表单值
  23. var firstFormArray = args.getFormArray(0);
  24. // 停止离开当前页面
  25. return false;
  26. JS
  27. );
  28. // 监听多次
  29. $step->leaving(...);
  30. });

监听步骤页面显示事件

监听当前步骤页面显示事件,支持监听多次。

  1. use Dcat\Admin\Form;
  2. $form->multipleSteps()->add('基本信息', function (Form\StepForm $step) {
  3. ...
  4. $step->shown(<<<JS
  5. Dcat.info("当前步骤是 基本信息");
  6. // args变量的值与“leaving”事件的值相同。
  7. console.log("显示 基本信息", args);
  8. JS
  9. );
  10. // 监听多次
  11. $step->shown(...);
  12. });

设置完成页面

当所有步骤都完成之后会显示完成页面,系统提供一个默认的完成页面,开发者也可以通过以下方法自定义完成页面要显示的内容。

  1. use Dcat\Admin\Form;
  2. $form->multipleSteps()->done(function (Form\DoneStep $done) {
  3. // 获取新增ID
  4. // 由 Repository::store 返回的值
  5. $newId = $done->getNewId();
  6. // 返回你要显示的内容,可以使一个视图也可以是一个字符串。
  7. return view(...);
  8. });