分步表单
<h1>分步表单</h1>
<h2>安装</h2>
<p>前往<a href="https://github.com/dcat-admin/form-step"><a href="https://github.com/dcat-admin/form-step">https://github.com/dcat-admin/form-step</a></a>下载分步表单扩展,然后安装并启用。</p>
<p>> {tip} 扩展安装请参考文档<a href="extension-f.md">扩展基本使用</a>章节。</p>
<h2>简单示例</h2>
<pre><code class="language-php">protected function form()
{
return Form::make(new Model(), function (Form $form) {
$form-&gt;title('分步表单');
$form-&gt;action('step');
$form-&gt;disableListButton();
$form-&gt;multipleSteps()
-&gt;remember() // 记住表单步骤,默认不开启
-&gt;width('950px')
-&gt;add('基本信息', function ($step) {
$info = '&lt;i class=&quot;fa fa-exclamation-circle&quot;&gt;&lt;/i&gt; 表单字段支持前端验证和后端验证混用,前端验证支持H5表单验证以及自定义验证。';
$step-&gt;html(Alert::make($info)-&gt;info());
$step-&gt;text('name', '姓名')-&gt;required()-&gt;maxLength(20);
// h5 表单验证
$step-&gt;text('age', '年龄')
-&gt;required()
-&gt;type('number')
-&gt;attribute('max', 150)
-&gt;help('前端验证');
$step-&gt;radio('sex', '性别')-&gt;options(['未知', '男', '女'])-&gt;default(0);
// 后端验证
$step-&gt;text('birthplace', '籍贯')
-&gt;rules('required')
-&gt;help('演示后端字段验证');
$step-&gt;url('homepage', '个人主页');
$step-&gt;textarea('description', '简介');
})
-&gt;add('兴趣爱好', function ($step) {
$step-&gt;tags('hobbies', '爱好')
-&gt;options(['唱', '跳', 'RAP', '踢足球'])
-&gt;required();
$step-&gt;text('books', '书籍');
$step-&gt;text('music', '音乐');
// 事件
$step-&gt;shown(function () {
return &lt;&lt;&lt;JS
Dcat.info('兴趣爱好');
console.log('兴趣爱好', args);
JS;
});
})
-&gt;add('地址', function ($step) {
$step-&gt;text('address', '街道地址');
$step-&gt;text('post_code', '邮政编码');
$step-&gt;tel('tel', ' 联系电话');
})
-&gt;done(function () use ($form) {
$resource = $form-&gt;getResource(0);
$data = [
'title' =&gt; '操作成功',
'description' =&gt; '恭喜您成为第10086位用户',
'createUrl' =&gt; $resource,
'backUrl' =&gt; $resource,
];
return view('admin::form.done-step', $data);
});
});
}</code></pre>
<p>效果</p>
<p><a href="{{public}}/assets/img/screenshots/step-form-1.png" target="_blank">
<img style="box-shadow:0 1px 6px 1px rgba(0, 0, 0, 0.12)" width="100%" src="{{public}}/assets/img/screenshots/step-form-1.png">
</a></p>
<h2>运行逻辑</h2>
<p>分步表单的使用很简单,运行逻辑也与普通表单没有太大区别,下面简单说说分步表单的运行逻辑。</p>
<p>> {tip} 分步表单没有 <code>update</code> 的概念。</p>
<h4>参数验证</h4>
<p>当用户点击 <code>下一步</code> 时,会向后端发起请求验证参数是否正确,如果参数不符合要求则显示错误信息,验证通过才会进入下一个步骤。</p>
<h4>表单提交</h4>
<p>当进行到最后一步时,会对所有步骤的表单参数一起提交到后端并进行验证,如果参数不符合要求则显示错误信息,验证通过则保存表单数据,保存的方法与普通表单完全一致。</p>
<p>> {tip} 最后保存表单的方法是 <code>Form::store</code>。</p>
<h4>完成页面</h4>
<p>表单保存完成之后会显示完成页面,此步骤无法忽略。</p>
<h2>编辑表单</h2>
<p>分步表单默认是没有编辑功能的,用户输入了长步骤的表单之后不需要再分步编辑,因此如果需要对分步表单进行编辑,可以参考以下方式</p>
<pre><code class="language-php">protected function form()
{
return Form::make(new MyRepository(), function (Form $form) {
// 判断是否是编辑页面
if ($form-&gt;isEditing()) {
$form-&gt;text('age', '年龄')
-&gt;required()
-&gt;type('number')
-&gt;attribute('max', 150)
-&gt;help('前端验证')
...
return;
}
$form-&gt;multipleSteps()
-&gt;remember()
-&gt;width('950px')
-&gt;add('基本信息', function (Form\StepForm $step) {
$info = '&lt;i class=&quot;fa fa-exclamation-circle&quot;&gt;&lt;/i&gt; 表单字段支持前端验证和后端验证混用,前端验证支持H5表单验证以及自定义验证。';
$step-&gt;html(Alert::make($info)-&gt;info());
$step-&gt;text('name', '姓名')-&gt;required()-&gt;maxLength(20);
// h5 表单验证
$step-&gt;text('age', '年龄')
-&gt;required()
-&gt;type('number')
-&gt;attribute('max', 150)
-&gt;help('前端验证');
$step-&gt;radio('sex', '性别')-&gt;options(['未知', '男', '女'])-&gt;default(0);
...
})
-&gt;add('兴趣爱好', function (Form\StepForm $step) {
...
})
-&gt;done(function () use ($form) {
...
});
});
}</code></pre>
<h2>功能接口</h2>
<h3>设置容器最大宽度</h3>
<p>默认 <code>1000px</code>。</p>
<p>> {tip} 此方法只针对大屏幕,手机端页面会自动调节大小。</p>
<pre><code class="language-php">$form-&gt;multipleSteps()-&gt;width('900px');</code></pre>
<h3>记住表单数据</h3>
<p>开启此功能之后,当用户点击 <code>下一步</code> 按钮并且参数验证通过后,会把表单数据保存在 <code>session</code> 中,直到整个分步表单保存完毕之后才会销毁。</p>
<p>> {tip} 此功能默认不开启。</p>
<pre><code class="language-php">// 开启
$form-&gt;multipleSteps()-&gt;remember();
// 关闭
$form-&gt;multipleSteps()-&gt;remember(false);</code></pre>
<h3>设置容器间距</h3>
<p>默认值 <code>30px 18px 30px</code>。</p>
<pre><code class="language-php">$form-&gt;multipleSteps()-&gt;padding('30px 18px 30px');</code></pre>
<h3>监听页面离开事件</h3>
<p>监听所有步骤表单页面离开事件,可添加多个。</p>
<pre><code class="language-php">$form-&gt;multipleSteps()-&gt;leaving(&lt;&lt;&lt;JS
// 获取当前页面的步骤索引
var index = args.index;
Dcat.info(&quot;你将要离开第 &quot; + (index + 1) + &quot; 个页面&quot;);
// args变量是一个js对象,包含当前事件对象、当前步骤选项、表单对象和表单值等字段。
console.log(&quot;leaving&quot;, args);
// 获取当前事件对象
var evt = args.event;
// 获取步骤表单标题tap对象
var tab = args.tab;
// 获取动向是前往上一步还是下一步页面:&quot;forward&quot;、&quot;backward&quot;
var direction = args.direction;
// 获取当前步骤的表单JQ对象
var $form = args.form;
// 获取当前步骤页的表单值
var formArray = args.formArray;
// 获取指定步骤的表单JQ对象
var $firstForm = args.getForm(0);
// 获取指定步骤的表单值
var firstFormArray = args.getFormArray(0);
// 停止离开当前页面
return false;
JS
)-&gt;leaving(...);</code></pre>
<h3>监听页面显示事件</h3>
<p>监听所有步骤表单页面显示事件,可添加多个。</p>
<pre><code class="language-php">$form-&gt;multipleSteps()-&gt;shown(&lt;&lt;&lt;JS
// 获取当前页面的步骤索引
var index = args.index;
Dcat.info(&quot;当前显示的是第 &quot; + (index + 1) + &quot; 个页面&quot;);
// args变量的值与“leaving”事件的值相同。
console.log(&quot;shown&quot;, args);
JS
)-&gt;shown(...);</code></pre>
<h3>增加步骤表单</h3>
<p>步骤表单支持所有表单字段。</p>
<pre><code class="language-php">use Dcat\Admin\Form;
$form-&gt;multipleSteps()-&gt;add('标题', function (Form\StepForm $step) {
$step-&gt;text('username')-&gt;rules('required');
...
});</code></pre>
<h4>监听步骤页面离开事件</h4>
<p>监听当前步骤页面离开事件,支持监听多次。</p>
<pre><code class="language-php">use Dcat\Admin\Form;
$form-&gt;multipleSteps()-&gt;add('基本信息', function (Form\StepForm $step) {
...
$step-&gt;leaving(&lt;&lt;&lt;JS
Dcat.info(&quot;你将要离开 基本信息 页面&quot;);
// args变量是一个js对象,包含当前事件对象、当前步骤选项、表单对象和表单值等字段。
console.log(&quot;离开 基本信息&quot;, args);
// 获取当前事件对象
var evt = args.event;
// 获取当前页面的步骤索引
var index = args.index;
// 获取步骤表单标题tap对象
var tab = args.tab;
// 获取动向是前往上一步还是下一步页面:&quot;forward&quot;、&quot;backward&quot;
var direction = args.direction;
// 获取当前步骤的表单JQ对象
var $form = args.form;
// 获取当前步骤页的表单值
var formArray = args.formArray;
// 获取指定步骤的表单JQ对象
var $firstForm = args.getForm(0);
// 获取指定步骤的表单值
var firstFormArray = args.getFormArray(0);
// 停止离开当前页面
return false;
JS
);
// 监听多次
$step-&gt;leaving(...);
});</code></pre>
<h4>监听步骤页面显示事件</h4>
<p>监听当前步骤页面显示事件,支持监听多次。</p>
<pre><code class="language-php">use Dcat\Admin\Form;
$form-&gt;multipleSteps()-&gt;add('基本信息', function (Form\StepForm $step) {
...
$step-&gt;shown(&lt;&lt;&lt;JS
Dcat.info(&quot;当前步骤是 基本信息&quot;);
// args变量的值与“leaving”事件的值相同。
console.log(&quot;显示 基本信息&quot;, args);
JS
);
// 监听多次
$step-&gt;shown(...);
});</code></pre>
<h3>设置完成页面</h3>
<p>当所有步骤都完成之后会显示完成页面,系统提供一个默认的完成页面,开发者也可以通过以下方法自定义完成页面要显示的内容。</p>
<pre><code class="language-php">use Dcat\Admin\Form;
$form-&gt;multipleSteps()-&gt;done(function (Form\DoneStep $done) {
// 获取新增ID
// 由 Repository::store 返回的值
$newId = $done-&gt;getNewId();
// 返回你要显示的内容,可以使一个视图也可以是一个字符串。
return view(...);
});</code></pre>