dcat-admin

dcat-admin


表单字段的使用

<h1>表单字段的使用</h1> <p>在<code>model-form</code>中内置了大量的form组件来帮助你快速的构建form表单</p> <p>&lt;a name=&quot;public&quot;&gt;&lt;/a&gt;</p> <h2>公共方法</h2> <p>&lt;a name=&quot;value&quot;&gt;&lt;/a&gt;</p> <h3>设置表单值 (value)</h3> <pre><code class="language-php">$form-&amp;gt;text('title')-&amp;gt;value('text...');</code></pre> <p>&lt;a name=&quot;default&quot;&gt;&lt;/a&gt;</p> <h3>设置默认值 (default)</h3> <pre><code class="language-php">$form-&amp;gt;text('title')-&amp;gt;default('text...');</code></pre> <p>此方法仅在<strong>新增页面</strong>有效,如果<strong>编辑页面</strong>也需要设置默认值,可以参考以下方法</p> <pre><code class="language-php">$form-&amp;gt;text('xxx')-&amp;gt;default('默认值', true);</code></pre> <p>&lt;a name=&quot;help&quot;&gt;&lt;/a&gt;</p> <h3>设置提示信息 (help)</h3> <pre><code class="language-php">$form-&amp;gt;text('title')-&amp;gt;help('help...');</code></pre> <p>&lt;a name=&quot;attr&quot;&gt;&lt;/a&gt;</p> <h3>设置属性 (attribute)</h3> <pre><code class="language-php">$form-&amp;gt;text('title')-&amp;gt;attribute(['data-title' =&amp;gt; 'title...']); $form-&amp;gt;text('title')-&amp;gt;attribute('data-title', 'title...');</code></pre> <p>&lt;a name=&quot;required&quot;&gt;&lt;/a&gt;</p> <h3>设置为必填 (required)</h3> <pre><code class="language-php">$form-&amp;gt;text('title')-&amp;gt;required(); // 不显示&amp;quot;*&amp;quot;号 $form-&amp;gt;text('title')-&amp;gt;required(false);</code></pre> <p>&lt;a name=&quot;disable&quot;&gt;&lt;/a&gt;</p> <h3>设置为不可编辑 (disable)</h3> <pre><code class="language-php">$form-&amp;gt;text('title')-&amp;gt;disable();</code></pre> <p>&lt;a name=&quot;placeholder&quot;&gt;&lt;/a&gt;</p> <h3>设置占位符 (placeholder)</h3> <pre><code class="language-php">$form-&amp;gt;text('title')-&amp;gt;placeholder('请输入。。。');</code></pre> <p>&lt;a name=&quot;setWidth&quot;&gt;&lt;/a&gt;</p> <h3>设置宽度 (width)</h3> <pre><code class="language-php">$form-&amp;gt;text('title')-&amp;gt;width(8, 2);</code></pre> <p>&lt;a name=&quot;rules&quot;&gt;&lt;/a&gt;</p> <h3>设置验证规则 (rules)</h3> <p>具体使用可参考<a href="model-form-validation.md">表单验证</a>。</p> <p>&lt;a name=&quot;saving&quot;&gt;&lt;/a&gt;</p> <h3>修改待保存的表单输入值 (saving)</h3> <p>通过<code>saving</code>方法可以更改待保存数据的格式。</p> <pre><code class="language-php">use Dcat\Admin\Support\Helper; $form-&amp;gt;multipleFile('files')-&amp;gt;saving(function ($paths) { $paths = Helper::array($paths); // 获取数据库当前行的其他字段 $username = $this-&amp;gt;username; // 最终转化为json保存到数据库 return json_encode($paths); });</code></pre> <p>&lt;a name=&quot;customFormat&quot;&gt;&lt;/a&gt;</p> <h3>修改表单数据显示 (customFormat)</h3> <p>通过<code>customFormat</code>方法可以改变从外部注入到表单的字段值。</p> <p>如下例子中,<code>multipleFile</code>字段要求待渲染的字段值为数组格式,我们可以通过<code>customFormat</code>方法把从数据库查出的字段值转化为<code>array</code>格式</p> <pre><code class="language-php">use Dcat\Admin\Support\Helper; $form-&amp;gt;multipleFile('files')-&amp;gt;saving(function ($paths) { $paths = Helper::array($paths); return json_encode($paths); })-&amp;gt;customFormat(function ($paths) { // 获取数据库当前行的其他字段 $username = $this-&amp;gt;username; // 转为数组 return Helper::array($paths); });</code></pre> <h3>在弹窗中隐藏</h3> <p>如果不想在弹窗中显示某个字段,可以使用<code>Form\Field::hideInDialog</code>方法</p> <pre><code class="language-php">$form-&amp;gt;display('id'); $form-&amp;gt;text('title'); $form-&amp;gt;textarea('contents')-&amp;gt;hideInDialog();</code></pre> <h3>保存为字符串类型 <code>saveAsString</code></h3> <p><code>saveAsString</code>方法可以把表单值转化为<code>string</code>类型保存,当保存的数据库字段值不允许为<code>null</code>时非常有用;</p> <pre><code class="language-php">$form-&amp;gt;text('nickname')-&amp;gt;saveAsString();</code></pre> <h3>保存为json类型 <code>saveAsJson</code></h3> <p><code>saveAsJson</code>可以把表单值保存为<code>json</code>格式</p> <pre><code class="language-php">$form-&amp;gt;text('nickname')-&amp;gt;saveAsJson();</code></pre> <p>&lt;a name=&quot;text&quot;&gt;&lt;/a&gt;</p> <h2>文本 (text)</h2> <pre><code class="language-php">$form-&amp;gt;text($column, [$label]); // 添加提交验证规则 $form-&amp;gt;text($column, [$label])-&amp;gt;rules('required|min:10');</code></pre> <p>&lt;a name=&quot;hidden&quot;&gt;&lt;/a&gt;</p> <h2>隐藏字段 (hidden)</h2> <p>通过<code>hidden</code>方法可以给你的表单设置一个隐藏字段。</p> <pre><code class="language-php">$form-&amp;gt;hidden('author_id')-&amp;gt;value(Admin::user()-&amp;gt;getKey());</code></pre> <p>通常可以结合<code>saving</code>事件使用</p> <pre><code class="language-php">$form-&amp;gt;hidden('author_id'); $form-&amp;gt;saving(function (Form $form) { $form-&amp;gt;author_id = Admin::user()-&amp;gt;getKey(); });</code></pre> <p>&lt;a name=&quot;select&quot;&gt;&lt;/a&gt;</p> <h2>下拉选框单选 (select)</h2> <pre><code class="language-php">$form-&amp;gt;select($column[, $label])-&amp;gt;options([1 =&amp;gt; 'foo', 2 =&amp;gt; 'bar', 'val' =&amp;gt; 'Option name']);</code></pre> <p>或者从api中获取选项列表:</p> <pre><code class="language-php">$form-&amp;gt;select($column[, $label])-&amp;gt;options('/api/users'); // 使用ajax并显示所选项目 $form-&amp;gt;select($column[, $label])-&amp;gt;options(Model::class)-&amp;gt;ajax('/api/users'); // 或指定名称和ID $form-&amp;gt;select($column[, $label])-&amp;gt;options(Model::class, 'name', 'id')-&amp;gt;ajax('/api/users');</code></pre> <p>其中api接口的格式必须为下面格式:</p> <pre><code class="language-php">[ { &amp;quot;id&amp;quot;: 9, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 21, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, ... ]</code></pre> <p>如果选项过多,可通过ajax方式动态分页载入选项:</p> <pre><code class="language-php">$form-&amp;gt;select('user_id')-&amp;gt;options(function ($id) { $user = User::find($id); if ($user) { return [$user-&amp;gt;id =&amp;gt; $user-&amp;gt;name]; } })-&amp;gt;ajax('api/users');</code></pre> <p>使用model方法在編輯時載入資料:</p> <pre><code class="language-php">$form-&amp;gt;select('user_id')-&amp;gt;model(User::class, 'id', 'name');</code></pre> <p>上面的代碼跟下面這個是一樣的</p> <pre><code class="language-php">$form-&amp;gt;select('user_id')-&amp;gt;options(function ($id) { $user = User::find($id); if ($user) { return [$user-&amp;gt;id =&amp;gt; $user-&amp;gt;name]; } });</code></pre> <p>API <code>/admin/api/users</code>接口的代码:</p> <pre><code class="language-php">public function users(Request $request) { $q = $request-&amp;gt;get('q'); return User::where('name', 'like', &amp;quot;%$q%&amp;quot;)-&amp;gt;paginate(null, ['id', 'name as text']); } </code></pre> <p>接口返回的数据结构为</p> <pre><code class="language-json">{ &amp;quot;total&amp;quot;: 4, &amp;quot;per_page&amp;quot;: 15, &amp;quot;current_page&amp;quot;: 1, &amp;quot;last_page&amp;quot;: 1, &amp;quot;next_page_url&amp;quot;: null, &amp;quot;prev_page_url&amp;quot;: null, &amp;quot;from&amp;quot;: 1, &amp;quot;to&amp;quot;: 3, &amp;quot;data&amp;quot;: [ { &amp;quot;id&amp;quot;: 9, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 21, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 42, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 48, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; } ] }</code></pre> <p>&lt;a name=&quot;selectload&quot;&gt;&lt;/a&gt;</p> <h2>下拉选框联动 (load)</h2> <p><code>select</code>组件支持父子关系的单向联动:</p> <pre><code class="language-php">$form-&amp;gt;select('province')-&amp;gt;options(...)-&amp;gt;load('city', '/api/city'); $form-&amp;gt;select('city');</code></pre> <p>其中<code>load('city', '/api/city');</code>的意思是,在当前select的选项切换之后,会把当前选项的值通过参数<code>q</code>, 调用接口<code>/api/city</code>,并把api返回的数据填充为city选择框的选项,其中api<code>/api/city</code>返回的数据格式必须符合:</p> <pre><code class="language-php">[ { &amp;quot;id&amp;quot;: 9, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 21, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, ... ]</code></pre> <p>控制器action的代码示例如下:</p> <pre><code class="language-php">public function city(Request $request) { $provinceId = $request-&amp;gt;get('q'); return ChinaArea::city()-&amp;gt;where('parent_id', $provinceId)-&amp;gt;get(['id', DB::raw('name as text')]); }</code></pre> <p><code>selectTable</code>、<code>multipleSelectTable</code>、<code>radio</code>、<code>checkbox</code>也可以使用<code>load</code>方法联动<code>select</code>和<code>multipleSelect</code>表单,用法和上面的示例一致。</p> <h3>联动多个字段 (loads)</h3> <p>使用<code>loads</code>方法可以联动多个字段,用法如下</p> <pre><code class="language-php">$form-&amp;gt;select('status') -&amp;gt;options(...) -&amp;gt;loads(['field1', 'field2'], ['/api/field1', '/api/field2']); $form-&amp;gt;select('field1'); $form-&amp;gt;select('field2');</code></pre> <p><code>api</code>返回的数据格式与<code>load</code>方法一致,<code>selectTable</code>、<code>multipleSelectTable</code>、<code>radio</code>、<code>checkbox</code>也可以使用<code>loads</code>方法联动。</p> <p>&lt;a name=&quot;multipleSelect&quot;&gt;&lt;/a&gt;</p> <h2>下拉选框多选 (multipleSelect)</h2> <p>&gt; {tip} 注入这个字段的数据(从数据库查出来的)可以是一个以<code>,</code>隔开的字符串,也可以是<code>json</code>字符串或<code>array</code>数组。</p> <pre><code class="language-php">$form-&amp;gt;multipleSelect($column[, $label]) -&amp;gt;options([1 =&amp;gt; 'foo', 2 =&amp;gt; 'bar', 'val' =&amp;gt; 'Option name']) -&amp;gt;saving(function ($value) { // 转化成json字符串保存到数据库 return json_encode($value); }); // 使用ajax并显示所选项目: $form-&amp;gt;multipleSelect($column[, $label])-&amp;gt;options(Model::class)-&amp;gt;ajax('ajax_url'); // 或指定名称和ID $form-&amp;gt;multipleSelect($column[, $label])-&amp;gt;options(Model::class, 'name', 'id')-&amp;gt;ajax('ajax_url');</code></pre> <p>多选框可以处理两种情况,第一种是<code>ManyToMany</code>的关系。</p> <pre><code class="language-php">class Post extends Models { public function tags() { return $this-&amp;gt;belongsToMany(Tag::class); } } return Form::make(Post::with('tags'), function (Form $form) { ... $form-&amp;gt;multipleSelect('tags') -&amp;gt;options(Tag::all()-&amp;gt;pluck('name', 'id')) -&amp;gt;customFormat(function ($v) { if (! $v) { return []; } // 从数据库中查出的二维数组中转化成ID return array_column($v, 'id'); }); }); </code></pre> <p>第二种是将选项数组存储到单字段中,如果字段是字符串类型,那就需要在模型里面为该字段定义<a href="https://laravel.com/docs/5.5/eloquent-mutators">访问器和修改器</a>来存储和读取了。</p> <p>如果选项过多,可通过ajax方式动态分页载入选项:</p> <pre><code class="language-php">$form-&amp;gt;select('friends')-&amp;gt;options(function ($ids) { return User::find($ids)-&amp;gt;pluck('name', 'id'); })-&amp;gt;ajax('api/users');</code></pre> <p>API <code>/admin/api/users</code>接口的代码:</p> <pre><code class="language-php">public function users(Request $request) { $q = $request-&amp;gt;get('q'); return User::where('name', 'like', &amp;quot;%$q%&amp;quot;)-&amp;gt;paginate(null, ['id', 'name as text']); } </code></pre> <p>接口返回的数据结构为</p> <pre><code>{ &amp;quot;total&amp;quot;: 4, &amp;quot;per_page&amp;quot;: 15, &amp;quot;current_page&amp;quot;: 1, &amp;quot;last_page&amp;quot;: 1, &amp;quot;next_page_url&amp;quot;: null, &amp;quot;prev_page_url&amp;quot;: null, &amp;quot;from&amp;quot;: 1, &amp;quot;to&amp;quot;: 3, &amp;quot;data&amp;quot;: [ { &amp;quot;id&amp;quot;: 9, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 21, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 42, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 48, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; } ] }</code></pre> <p>&lt;a name=&quot;select-table&quot;&gt;&lt;/a&gt;</p> <h2>表格选择器 (selectTable)</h2> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Models\Administrator; $form-&amp;gt;selectTable($field) -&amp;gt;title('弹窗标题') -&amp;gt;dialogWidth('50%') // 弹窗宽度,默认 800px -&amp;gt;from(UserTable::make(['id' =&amp;gt; $form-&amp;gt;getKey()])) // 设置渲染类实例,并传递自定义参数 -&amp;gt;model(Administrator::class, 'id', 'name'); // 设置编辑数据显示 // 上面的代码等同于 $form-&amp;gt;selectTable($field) -&amp;gt;from(UserTable::make(['id' =&amp;gt; $form-&amp;gt;getKey()])) // 设置渲染类实例,并传递自定义参数 -&amp;gt;options(function ($v) { // 设置编辑数据显示 if (! $v) { return []; } return Administrator::find($v)-&amp;gt;pluck('name', 'id'); });</code></pre> <p>定义渲染类如下,需要继承<code>Dcat\Admin\Grid\LazyRenderable</code></p> <p>&gt; {tip} 这里使用了数据表格异步加载功能,详细用法请参考<a href="lazy.md">异步加载</a></p> <pre><code class="language-php">&amp;lt;?php namespace App\Admin\Renderable; use Dcat\Admin\Grid; use Dcat\Admin\Grid\LazyRenderable; use Dcat\Admin\Models\Administrator; class UserTable extends LazyRenderable { public function grid(): Grid { // 获取外部传递的参数 $id = $this-&amp;gt;id; return Grid::make(Administrator::where('xxx_id', $id), function (Grid $grid) { $grid-&amp;gt;column('id'); $grid-&amp;gt;column('username'); $grid-&amp;gt;column('name'); $grid-&amp;gt;column('created_at'); $grid-&amp;gt;column('updated_at'); $grid-&amp;gt;quickSearch(['id', 'username', 'name']); $grid-&amp;gt;paginate(10); $grid-&amp;gt;disableActions(); $grid-&amp;gt;filter(function (Grid\Filter $filter) { $filter-&amp;gt;like('username')-&amp;gt;width(4); $filter-&amp;gt;like('name')-&amp;gt;width(4); }); }); } }</code></pre> <p>效果</p> <p>&lt;a href=&quot;<a href="https://cdn.learnku.com/uploads/images/202008/23/38389/P5hZXiqAj9.gif!large&quot">https://cdn.learnku.com/uploads/images/202008/23/38389/P5hZXiqAj9.gif!large&quot</a>; target=&quot;_blank&quot;&gt; <img src="https://cdn.learnku.com/uploads/images/202008/23/38389/P5hZXiqAj9.gif!large" alt="" /> &lt;/a&gt;</p> <h3>设置选中后将保存到表单的字段和显示的字段</h3> <pre><code class="language-php">$form-&amp;gt;selectTable($field) -&amp;gt;from(UserTable::make(['id' =&amp;gt; $form-&amp;gt;getKey()])) -&amp;gt;options(function ($v) { // 设置编辑数据显示 if (! $v) { return []; } return Administrator::find($v)-&amp;gt;pluck('name', 'id'); }) -&amp;gt;pluck('name', 'id'); // 第一个参数为显示的字段,第二个参数为选中后将保存到表单的字段 // 上面的代码也可以简化为 $form-&amp;gt;selectTable($field) -&amp;gt;from(UserTable::make(['id' =&amp;gt; $form-&amp;gt;getKey()])) -&amp;gt;model(Administrator::class, 'id', 'name'); // 设置编辑数据显示</code></pre> <h3>多选 (multipleSelectTable)</h3> <p>多选的用法与上述<code>selectTable</code>方法一致</p> <pre><code class="language-php">$form-&amp;gt;multipleSelectTable($field) -&amp;gt;max(10) // 最多选择 10 个选项,不传则不限制 -&amp;gt;from(UserTable::make(['id' =&amp;gt; $form-&amp;gt;getKey()])) // 设置渲染类实例,并传递自定义参数 -&amp;gt;model(Administrator::class, 'id', 'name') // 设置编辑数据显示 -&amp;gt;saving(function ($v) { // $v 是表单提交的字段值,默认是数组类型,这里需要手动转换一下 // 保存为以 &amp;quot;,&amp;quot; 隔开的字符串,如果是多对多关联关系,则不需要转换。 return implode(',', $v); });</code></pre> <h2>多选盒 (listbox)</h2> <p>使用方法和<code>multipleSelect</code>类似。</p> <p>&gt; {tip} 注入这个字段的数据(从数据库查出来的)可以是一个以<code>,</code>隔开的字符串,也可以是<code>json</code>字符串或<code>array</code>数组。</p> <pre><code class="language-php">$form-&amp;gt;listbox($column[, $label])-&amp;gt;options([1 =&amp;gt; 'foo', 2 =&amp;gt; 'bar', 'val' =&amp;gt; 'Option name']);</code></pre> <p>&lt;a name=&quot;textarea&quot;&gt;&lt;/a&gt;</p> <h2>长文本 (textarea)</h2> <pre><code class="language-php">$form-&amp;gt;textarea($column[, $label])-&amp;gt;rows(10);</code></pre> <p>&lt;a name=&quot;radio&quot;&gt;&lt;/a&gt;</p> <h2>单选 (radio)</h2> <pre><code class="language-php">$form-&amp;gt;radio($column[, $label])-&amp;gt;options(['m' =&amp;gt; 'Female', 'f'=&amp;gt; 'Male'])-&amp;gt;default('m');</code></pre> <p>&lt;a name=&quot;checkbox&quot;&gt;&lt;/a&gt;</p> <h2>多选 (checkbox)</h2> <p><code>options()</code>方法用来设置选择项:</p> <pre><code class="language-php">$form-&amp;gt;checkbox($column[, $label]) -&amp;gt;options([1 =&amp;gt; 'foo', 2 =&amp;gt; 'bar', 'val' =&amp;gt; 'Option name']) -&amp;gt;saving(function ($value) { // 转化成json字符串保存到数据库 return json_encode($value); });</code></pre> <p>启用选中全部功能</p> <pre><code class="language-php">$form-&amp;gt;checkbox('column')-&amp;gt;canCheckAll();</code></pre> <p>&lt;a name=&quot;autocomplete&quot;&gt;&lt;/a&gt;</p> <h2>autocomplete</h2> <p>此表单可以在填写表单时进行对表单值进行搜索,并把结果展示在下拉列表中,用法如下</p> <pre><code class="language-php">$form-&amp;gt;autocomplete($column[, $label])-&amp;gt;options(['foo', 'bar', ...]); // 设置分组名称 $form-&amp;gt;autocomplete($column[, $label])-&amp;gt;groups([ [ 'label' =&amp;gt; 'group name', 'options' =&amp;gt; ['foo', 'bar', ...], ], ]);</code></pre> <p>效果如下 <img src="https://cdn.learnku.com/uploads/images/202112/12/38389/ArVNSvChag.png!large" alt="" /></p> <h3>从远程API获取数据</h3> <p>也可以从远程API中获取数据</p> <pre><code class="language-php">// ajax 函数的第一个参数为 ajax url, 第二个参数为 valueField(可选), 第三个参数为 groupField(可选) $form-&amp;gt;autocomplete($column[, $label])-&amp;gt;ajax('/countries', 'name', 'region');</code></pre> <p>远程API 服务端的请求参数为query,示例代码如下:</p> <pre><code class="language-php">class CountryController extends AdminController { public function search() { $countries = Country::when(request('query'), function ($query, $value) { $query-&amp;gt;where('name', 'like', &amp;quot;%{$value}%&amp;quot;); })-&amp;gt;get(); return Admin::json($countries-&amp;gt;toArray()); } }</code></pre> <h3>自定义 autocomplete 的设置:</h3> <p>详细设置请参考: <a href="https://github.com/devbridge/jQuery-Autocomplete">devbridge/jQuery-Autocomplete</a></p> <pre><code>$js = &amp;lt;&amp;lt;&amp;lt;JS function (suggestion) { alert('You selected: ' + suggestion.value + ', ' + suggestion.data); } JS; $form-&amp;gt;autocomplete($column[, $label])-&amp;gt;configs([ 'minChars' =&amp;gt; 5, 'noCache' =&amp;gt; true, 'onSelect' =&amp;gt; JavaScript::make($js), ]);</code></pre> <p>configs 同样也支持闭包:</p> <pre><code>$form-&amp;gt;autocomplete($column[, $label])-&amp;gt;configs(function($model, $value){ return [ .... ]; });</code></pre> <h3>表单联动</h3> <p>autocomplete 的联动逻辑和select的刚好相反。 depends 需要写在受影响的字段,不限上级字段类型,上级字段的值将同时上传到API。</p> <pre><code>$form-&amp;gt;select('region')-&amp;gt;options([ 'asia', 'Africa', 'America', 'Europe', ]); $form-&amp;gt;autocomplete('country')-&amp;gt;ajax('/countries', 'name', 'region'); // 将会发出 /states?query={query}&amp;amp;region={region}&amp;amp;country={country} 的请求 $form-&amp;gt;autocomplete('addr')-&amp;gt;ajax('/states', 'name')-&amp;gt;depends(['region', 'country']);</code></pre> <p>&lt;a name=&quot;email&quot;&gt;&lt;/a&gt;</p> <h2>邮箱 (email)</h2> <pre><code class="language-php">$form-&amp;gt;email($column[, $label]);</code></pre> <p>&lt;a name=&quot;password&quot;&gt;&lt;/a&gt;</p> <h2>密码 (password)</h2> <pre><code class="language-php">$form-&amp;gt;password($column[, $label]);</code></pre> <p>&lt;a name=&quot;url&quot;&gt;&lt;/a&gt;</p> <h2>链接 (url)</h2> <pre><code class="language-php">$form-&amp;gt;url($column[, $label]);</code></pre> <p>&lt;a name=&quot;ip&quot;&gt;&lt;/a&gt;</p> <h2>IP地址 (ip)</h2> <pre><code class="language-php">$form-&amp;gt;ip($column[, $label]);</code></pre> <p>&lt;a name=&quot;mobile&quot;&gt;&lt;/a&gt;</p> <h2>手机 (mobile)</h2> <pre><code class="language-php">$form-&amp;gt;mobile($column[, $label])-&amp;gt;options(['mask' =&amp;gt; '999 9999 9999']);</code></pre> <p>&lt;a name=&quot;color&quot;&gt;&lt;/a&gt;</p> <h2>颜色选择器 (color)</h2> <pre><code class="language-php">$form-&amp;gt;color($column[, $label]);</code></pre> <p>&lt;a name=&quot;time&quot;&gt;&lt;/a&gt;</p> <h2>时间 (time)</h2> <pre><code class="language-php">$form-&amp;gt;time($column[, $label]); // 设置时间格式,更多格式参考http://momentjs.com/docs/#/displaying/format/ $form-&amp;gt;time($column[, $label])-&amp;gt;format('HH:mm:ss');</code></pre> <p>&lt;a name=&quot;date&quot;&gt;&lt;/a&gt;</p> <h2>日期 (date)</h2> <pre><code class="language-php">$form-&amp;gt;date($column[, $label]); // 设置日期格式,更多格式参考http://momentjs.com/docs/#/displaying/format/ $form-&amp;gt;date($column[, $label])-&amp;gt;format('YYYY-MM-DD');</code></pre> <p>&lt;a name=&quot;datetime&quot;&gt;&lt;/a&gt;</p> <h2>时间日期 (datetime)</h2> <pre><code class="language-php">$form-&amp;gt;datetime($column[, $label]); // 设置日期格式,更多格式参考http://momentjs.com/docs/#/displaying/format/ $form-&amp;gt;datetime($column[, $label])-&amp;gt;format('YYYY-MM-DD HH:mm:ss');</code></pre> <p>&lt;a name=&quot;timeRange&quot;&gt;&lt;/a&gt;</p> <h2>时间范围 (timeRange)</h2> <p><code>$startTime</code>、<code>$endTime</code>为开始和结束时间字段:</p> <pre><code class="language-php">$form-&amp;gt;timeRange($startTime, $endTime, 'Time Range');</code></pre> <p>&lt;a name=&quot;dateRange&quot;&gt;&lt;/a&gt;</p> <h2>日期范围 (dateRange)</h2> <p><code>$startDate</code>、<code>$endDate</code>为开始和结束日期字段:</p> <pre><code class="language-php">$form-&amp;gt;dateRange($startDate, $endDate, 'Date Range');</code></pre> <p>&lt;a name=&quot;datetimeRange&quot;&gt;&lt;/a&gt;</p> <h2>时间日期范围 (datetimeRange)</h2> <p><code>$startDateTime</code>、<code>$endDateTime</code>为开始和结束时间日期:</p> <pre><code class="language-php">$form-&amp;gt;datetimeRange($startDateTime, $endDateTime, 'DateTime Range');</code></pre> <h2>范围 (range)</h2> <pre><code class="language-php">$form-&amp;gt;range('start_column', 'end_column', '范围');</code></pre> <p>&lt;a name=&quot;file&quot;&gt;&lt;/a&gt;</p> <h2>文件上传 (file)</h2> <p>使用文件上传功能之前需要先完成上传配置。文件上传配置以及内置方法请参考:<a href="model-form-upload.md">图片/文件上传</a>.</p> <p>文件上传目录在文件<code>config/admin.php</code>中的<code>upload.file</code>中配置,如果目录不存在,需要创建该目录并开放写权限。</p> <p>&gt; {tip} 文件或图片上传表单字段请不要在模型中设置<strong>访问器</strong>和<strong>修改器</strong>拼接域名,如有相关需求可参考<a href="model-form-upload.md#withhost">文件/图片域名拼接</a>。</p> <pre><code class="language-php">$form-&amp;gt;file($column[, $label]); // 修改文件上传路径和文件名 $form-&amp;gt;file($column[, $label])-&amp;gt;move($dir, $name); // 并设置上传文件类型 $form-&amp;gt;file($column[, $label])-&amp;gt;rules('mimes:doc,docx,xlsx'); // 添加文件删除按钮 $form-&amp;gt;file($column[, $label])-&amp;gt;removable();</code></pre> <p>&lt;a name=&quot;image&quot;&gt;&lt;/a&gt;</p> <h2>图片上传 (image)</h2> <p>使用图片上传功能之前需要先完成上传配置。图片上传配置以及内置方法请参考:<a href="model-form-upload.md">图片/文件上传</a>.</p> <p>图片上传目录在文件<code>config/admin.php</code>中的<code>upload.image</code>中配置,如果目录不存在,需要创建该目录并开放写权限。</p> <p>可以使用压缩、裁切、添加水印等各种方法,需要先安装<a href="http://image.intervention.io/getting_started/installation">intervention/image</a>。</p> <p>更多使用方法请参考[<a href="http://image.intervention.io/getting_started/introduction">Intervention</a>]:</p> <p>&gt; {tip} 文件或图片上传表单字段请不要在模型中设置<strong>访问器</strong>和<strong>修改器</strong>拼接域名,如有相关需求可参考<a href="model-form-upload.md#withhost">文件/图片域名拼接</a>。</p> <pre><code class="language-php">$form-&amp;gt;image($column[, $label]); // 修改图片上传路径和文件名 $form-&amp;gt;image($column[, $label])-&amp;gt;move($dir, $name); // 剪裁图片 $form-&amp;gt;image($column[, $label])-&amp;gt;crop(int $width, int $height, [int $x, int $y]); // 加水印 $form-&amp;gt;image($column[, $label])-&amp;gt;insert($watermark, 'center');</code></pre> <p>&lt;a name=&quot;multipleImage&quot;&gt;&lt;/a&gt;</p> <h2>多图和多文件上传 (multipleImage/multipleFile)</h2> <p>多图片上传表单继承自单图上传表单,多文件上传表单继承自单文件上传表单。</p> <p>&gt; {tip} 注入这个字段的数据(从数据库查出来的)可以是一个以<code>,</code>隔开的字符串,也可以是<code>json</code>字符串或<code>array</code>数组。</p> <pre><code class="language-php">// 多图 $form-&amp;gt;multipleImage($column[, $label]); // 限制最大上传数量 $form-&amp;gt;multipleImage($column[, $label])-&amp;gt;limit(3); // 多文件 $form-&amp;gt;multipleFile($column[, $label]); // 限制最大上传数量 $form-&amp;gt;multipleFile($column[, $label])-&amp;gt;limit(5);</code></pre> <p>多图/文件上传的时候提交的数据是一个<code>array</code>数组,你可以通过以下方式把数据在保存进数据库之前改为你想要的格式:</p> <pre><code class="language-php">// 转化为json格式保存到数据库 $form-&amp;gt;multipleFile($column[, $label])-&amp;gt;saving(function ($paths) { // 可以转化为由 , 隔开的字符串格式 // return implode(',', $paths); // 也可以转化为json return json_encode($paths); });</code></pre> <p>当然,如果你想保存为其他任意格式都是可以的,只是如果要保存其他格式,需要通过用<code>customFormat</code>方法把数据转化为一维数组展示,如:</p> <pre><code class="language-php">$form-&amp;gt;multipleFile($column[, $label]) -&amp;gt;customFormat(function ($paths) { return collect($paths)-&amp;gt;map(function ($value) { return explode('|', $value); })-&amp;gt;flatten()-&amp;gt;toArray(); }) -&amp;gt;saving(function ($paths) { return implode('|', $paths); });</code></pre> <p>启用可排序功能</p> <pre><code class="language-php">$form-&amp;gt;multipleImage('images')-&amp;gt;sortable();</code></pre> <p>&lt;a name=&quot;editor&quot;&gt;&lt;/a&gt;</p> <h2>富文本编辑器 (editor)</h2> <p>系统集成了<code>TinyMCE</code>编辑器作为内置编辑器。</p> <h4>基本使用</h4> <pre><code class="language-php">$form-&amp;gt;editor($column[, $label]);</code></pre> <h4>设置语言包</h4> <p>默认支持简体中文和英文两种语言,如需其他语言可以通过以下方式设置语言包地址。</p> <pre><code class="language-php">$form-&amp;gt;editor('content')-&amp;gt;languageUrl(url('TinyMCE/langs/de.js'));</code></pre> <h4>编辑器配置</h4> <p>具体配置等的使用可以参考<a href="https://www.tiny.cloud/docs">官方文档</a>或<a href="http://tinymce.ax-z.cn/">中文文档</a></p> <pre><code class="language-php">&amp;lt;?php use Dcat\Admin\Support\JavaScript; $form-&amp;gt;editor('content')-&amp;gt;options([ 'toolbar' =&amp;gt; [], 'setup' =&amp;gt; JavaScript::make( &amp;lt;&amp;lt;&amp;lt;JS function (editor) { console.log('编辑器初始化成功', editor) } JS ), ]);</code></pre> <h4>设置高度</h4> <p>默认值为<code>400</code></p> <pre><code class="language-php">$form-&amp;gt;editor('content')-&amp;gt;height('600');</code></pre> <h4>只读</h4> <pre><code class="language-php">$form-&amp;gt;editor('content')-&amp;gt;readOnly(); // 或 $form-&amp;gt;editor('content')-&amp;gt;disable();</code></pre> <h4>图片上传</h4> <p>设置图片上传<code>disk</code>配置,默认上传到<code>admin.upload.disk</code>指定的配置</p> <pre><code class="language-php">// 上传到oss $form-&amp;gt;editor('content')-&amp;gt;disk('oss');</code></pre> <p>设置图片上传目录,默认为<code>tinymce/images</code></p> <pre><code class="language-php">$form-&amp;gt;editor('content')-&amp;gt;imageDirectory('editor/images');</code></pre> <p>自定义上传接口,接口返回格式需要是<code>{&amp;quot;location&amp;quot;: &amp;quot;图片url&amp;quot;}</code></p> <pre><code class="language-php">$form-&amp;gt;editor('content')-&amp;gt;imageUrl('editor/upload-image');</code></pre> <h4>全局设置</h4> <p>如果你需要对编辑器进行全局设置,可以在<code>app\Admin\bootstrap.php</code>加上以下代码</p> <pre><code class="language-php">&amp;lt;?php use Dcat\Admin\Form\Field\Editor; Editor::resolving(function (Editor $editor) { // 设置默认配置 $editor-&amp;gt;options([...]); // 设置编辑器图片默认上传到七牛云 $editor-&amp;gt;disk('qiniu'); });</code></pre> <p>&lt;a name=&quot;markdown&quot;&gt;&lt;/a&gt;</p> <h2>Markdown编辑器 (markdown)</h2> <p>系统集成了<code>editor-md</code>编辑器作为内置Markdown编辑器。</p> <h4>基本使用</h4> <pre><code class="language-php">$form-&amp;gt;markdown($column[, $label]);</code></pre> <h4>设置语言包</h4> <p>默认支持简体中文和英文两种语言,如需其他语言可以通过以下方式设置语言包地址。</p> <pre><code class="language-php">$form-&amp;gt;markdown('content')-&amp;gt;languageUrl(admin_asset('@admin/dcat/plugins/editor-md/languages/zh-tw.js'));</code></pre> <h4>编辑器配置</h4> <p>具体配置等的使用可以参考<a href="https://pandao.github.io/editor.md/">官方文档</a></p> <pre><code class="language-php">&amp;lt;?php use Dcat\Admin\Support\JavaScript; $form-&amp;gt;markdown('content')-&amp;gt;options([ 'onpreviewing' =&amp;gt; JavaScript::make( &amp;lt;&amp;lt;&amp;lt;JS function() { // console.log(&amp;quot;onpreviewing =&amp;gt;&amp;quot;, this, this.id, this.settings); // on previewing you can custom css .editormd-preview-active } JS ), ]);</code></pre> <h4>设置高度</h4> <p>默认值为<code>500</code></p> <pre><code class="language-php">$form-&amp;gt;markdown('content')-&amp;gt;height('600');</code></pre> <h4>只读</h4> <pre><code class="language-php">$form-&amp;gt;markdown('content')-&amp;gt;readOnly(); // 或 $form-&amp;gt;markdown('content')-&amp;gt;disable();</code></pre> <h4>图片上传</h4> <p>设置图片上传<code>disk</code>配置,默认上传到<code>admin.upload.disk</code>指定的配置</p> <pre><code class="language-php">// 上传到oss $form-&amp;gt;markdown('content')-&amp;gt;disk('oss');</code></pre> <p>设置图片上传目录,默认为<code>markdown/images</code></p> <pre><code class="language-php">$form-&amp;gt;markdown('content')-&amp;gt;imageDirectory('markdown/images');</code></pre> <p>自定义上传接口,接口返回格式需要是<code>{&amp;quot;success&amp;quot;: 1, &amp;quot;url&amp;quot;: &amp;quot;图片url&amp;quot;}</code></p> <pre><code class="language-php">$form-&amp;gt;markdown('content')-&amp;gt;imageUrl('markdown/upload-image');</code></pre> <h4>全局设置</h4> <p>如果你需要对编辑器进行全局设置,可以在<code>app\Admin\bootstrap.php</code>加上以下代码</p> <pre><code class="language-php">&amp;lt;?php use Dcat\Admin\Form\Field\Markdown; Markdown::resolving(function (Markdown $markdown) { // 设置默认配置 $markdown-&amp;gt;options([...]); // 设置编辑器图片默认上传到七牛云 $markdown-&amp;gt;disk('qiniu'); });</code></pre> <p>&lt;a name=&quot;switch&quot;&gt;&lt;/a&gt;</p> <h2>开关 (switch)</h2> <p>使用</p> <pre><code class="language-php">$form-&amp;gt;switch($column[, $label]);</code></pre> <p>开关表单保存到数据库的默认值为<code>1</code>和<code>0</code>,如果需要更改保存到数据库的值,可以这样使用</p> <pre><code class="language-php">$form-&amp;gt;switch($column[, $label]) -&amp;gt;customFormat(function ($v) { return $v == '打开' ? 1 : 0; }) -&amp;gt;saving(function ($v) { return $v ? '打开' : '关闭'; });</code></pre> <p>&lt;a name=&quot;map&quot;&gt;&lt;/a&gt;</p> <h2>地图 (map)</h2> <p>地图控件,用来选择经纬度,<code>$latitude</code>, <code>$longitude</code>为经纬度字段。</p> <p>使用这个功能需要在 <code>config/admin.php</code> 文件中修改 <code>map_provider</code> 的值(目前支持的地图为:&quot;tencent&quot;, &quot;google&quot;, &quot;yandex&quot;,不同地图需要自己申请相应的 KEY 并在 .env 文件中配置,然后需要在<code>app/Admin/bootstrap.php</code>中加入以下代码</p> <pre><code class="language-php">Form\Field\Map::requireAssets();</code></pre> <p>使用</p> <pre><code class="language-php">$form-&amp;gt;map($latitude, $longitude, $label);</code></pre> <p>&lt;a name=&quot;slider&quot;&gt;&lt;/a&gt;</p> <h2>滑动条 (slider)</h2> <p>可以用来数字类型字段的选择,比如年龄:</p> <pre><code class="language-php">$form-&amp;gt;slider($column[, $label])-&amp;gt;options(['max' =&amp;gt; 100, 'min' =&amp;gt; 1, 'step' =&amp;gt; 1, 'postfix' =&amp;gt; 'years old']);</code></pre> <p>更多options请参考:<a href="https://github.com/IonDen/ion.rangeSlider#settings">https://github.com/IonDen/ion.rangeSlider#settings</a></p> <p>&lt;a name=&quot;display&quot;&gt;&lt;/a&gt;</p> <h2>仅显示 (display)</h2> <p>只显示字段,不做任何操作:</p> <pre><code class="language-php">$form-&amp;gt;display($column[, $label]); //更复杂的显示 $form-&amp;gt;display($column[, $label])-&amp;gt;with(function ($value) { return &amp;quot;&amp;lt;img src=&amp;quot;$value&amp;quot; /&amp;gt;&amp;quot;; });</code></pre> <p>&lt;a name=&quot;currency&quot;&gt;&lt;/a&gt;</p> <h2>单位符号 (currency)</h2> <pre><code class="language-php">$form-&amp;gt;currency($column[, $label]); // 设置单位符号 $form-&amp;gt;currency($column[, $label])-&amp;gt;symbol('¥');</code></pre> <p>&lt;a name=&quot;number&quot;&gt;&lt;/a&gt;</p> <h2>数字 (number)</h2> <pre><code class="language-php">$form-&amp;gt;number($column[, $label]);</code></pre> <p>&lt;a name=&quot;rate&quot;&gt;&lt;/a&gt;</p> <h2>费率 (rate)</h2> <pre><code class="language-php">$form-&amp;gt;rate($column[, $label]);</code></pre> <p>&lt;a name=&quot;divider&quot;&gt;&lt;/a&gt;</p> <h2>分割线 (divider)</h2> <pre><code class="language-php">$form-&amp;gt;divider();</code></pre> <p>&lt;a name=&quot;html&quot;&gt;&lt;/a&gt;</p> <h2>自定义内容 (html)</h2> <p>插入html内容,参数可以是实现了<code>Htmlable</code>、<code>Renderable</code>或者实现了<code>__toString()</code>方法的类</p> <pre><code class="language-php">$form-&amp;gt;html('你的html内容', $label = '');</code></pre> <p>&lt;a name=&quot;tags&quot;&gt;&lt;/a&gt;</p> <h2>标签 (tags)</h2> <p>插入逗号(,)隔开的字符串<code>tags</code></p> <pre><code class="language-php">$form-&amp;gt;tags('keywords');</code></pre> <p><code>tags</code>同样支持<code>ManyToMany</code>的关系,示例如下:</p> <pre><code class="language-php">$form-&amp;gt;tags('tags', '文章标签') -&amp;gt;pluck('name', 'id') // name 为需要显示的 Tag 模型的字段,id 为主键 -&amp;gt;options(Tag::all());// 下拉框选项</code></pre> <p>注意:处理<code>ManyToMany</code>关系时必须调用<code>pluck</code>方法,指定显示的字段名和主键。 此外 <code>options</code> 方法传入一个<code>Collection</code>对象时,<code>options</code>会自动调用该对象的<code>pluck</code>方法转为<code>['主键名' =&amp;gt; '显示字段名']</code> 数组,作为下拉框选项。或者可以直接使用<code>['主键名' =&amp;gt; '显示字段名']</code>这样的数组作为参数。</p> <p><code>tags</code>还支持<code>saving</code>方法用于处理提交的数据,示例如下:</p> <pre><code class="language-php">$form-&amp;gt;tags('tags', '文章标签') -&amp;gt;pluck('name', 'id') -&amp;gt;options(Tag::all()) -&amp;gt;saving(function ($value) { return $value; });</code></pre> <p><code>saving</code> 方法接收一个「参数为 tags 的提交值,返回值为修改后的 tags 提交值」的闭包,可以用于实现自动创建新 tag 或其它功能。</p> <p>如果选项过多,可通过ajax方式动态分页载入选项:</p> <pre><code class="language-php">$form-&amp;gt;tags('friends')-&amp;gt;options(function ($ids) { return User::find((array) $ids)-&amp;gt;pluck('name', 'id'); })-&amp;gt;ajax('api/users');</code></pre> <p>API <code>/admin/api/users</code>接口的代码:</p> <pre><code class="language-php">public function users(Request $request) { $q = $request-&amp;gt;get('q'); return User::where('name', 'like', &amp;quot;%$q%&amp;quot;)-&amp;gt;paginate(null, ['id', 'name as text']); }</code></pre> <p>接口返回的数据结构为</p> <pre><code>{ &amp;quot;total&amp;quot;: 4, &amp;quot;per_page&amp;quot;: 15, &amp;quot;current_page&amp;quot;: 1, &amp;quot;last_page&amp;quot;: 1, &amp;quot;next_page_url&amp;quot;: null, &amp;quot;prev_page_url&amp;quot;: null, &amp;quot;from&amp;quot;: 1, &amp;quot;to&amp;quot;: 3, &amp;quot;data&amp;quot;: [ { &amp;quot;id&amp;quot;: 9, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 21, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 42, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; }, { &amp;quot;id&amp;quot;: 48, &amp;quot;text&amp;quot;: &amp;quot;xxx&amp;quot; } ] }</code></pre> <p>&lt;a name=&quot;icon&quot;&gt;&lt;/a&gt;</p> <h2>图标选择器 (icon)</h2> <p>选择<code>font-awesome</code>图标</p> <pre><code class="language-php">$form-&amp;gt;icon('icon');</code></pre> <p>&lt;a name=&quot;tree&quot;&gt;&lt;/a&gt;</p> <h2>树形选择器 (tree)</h2> <p>树形结构表单</p> <pre><code class="language-php">$form-&amp;gt;tree('permissions') -&amp;gt;nodes(Model::get()-&amp;gt;toArray()) // 设置所有节点 -&amp;gt;customFormat(function ($v) { // 格式化外部注入的值 if (!$v) return []; return array_column($v, 'id'); }); // 修改节点的字段名称 // 默认 “id” “name” “parent_id” $form-&amp;gt;tree('permissions') -&amp;gt;nodes($permissionModel-&amp;gt;allNodes()) -&amp;gt;setIdColumn('id') -&amp;gt;setTitleColumn('title') -&amp;gt;setParentColumn('parent'); // 默认是不保存父节点的值的,因为一般来说父节点只是作为标题的形式存在 // 禁止过滤父节点的值 $form-&amp;gt;tree('permissions') -&amp;gt;nodes($permissionModel-&amp;gt;allNodes()) -&amp;gt;exceptParentNode(false); // 默认收缩子节点 $form-&amp;gt;tree('permissions') -&amp;gt;nodes($permissionModel-&amp;gt;allNodes()) -&amp;gt;expand(false);</code></pre> <p><code>tree</code>表单默认不允许单独选中父节点,可以通过<code>treeState(false)</code>开启这个功能</p> <pre><code class="language-php">$form-&amp;gt;tree('xxx') -&amp;gt;treeState(false) # 允许单独选择父节点 -&amp;gt;setTitleColumn('title') -&amp;gt;nodes(...);</code></pre> <p>效果</p> <p><img src="https://cdn.learnku.com/uploads/images/202104/30/38389/oChwzky2BT.gif!large" alt="" /></p> <p>&lt;a name=&quot;table&quot;&gt;&lt;/a&gt;</p> <h2>表格表单 (table)</h2> <p>如果某一个字段存储的是json格式的二维数组,可以使用table表单组件来实现快速的编辑:</p> <pre><code class="language-php">$form-&amp;gt;table('extra', function (NestedForm $table) { $table-&amp;gt;text('key'); $table-&amp;gt;text('value'); $table-&amp;gt;text('desc'); });</code></pre> <p>同时在模型里面给这个字段增加访问器和修改器:</p> <pre><code class="language-php">public function getExtraAttribute($extra) { return array_values(json_decode($extra, true) ?: []); } public function setExtraAttribute($extra) { $this-&amp;gt;attributes['extra'] = json_encode(array_values($extra)); }</code></pre> <p>这个组件类似于hasMany组件,不过是用来处理单个字段的情况,适用于简单的二维数据。</p> <p>&lt;a name=&quot;onemany&quot;&gt;&lt;/a&gt;</p> <h2>一对多 (hasMany)</h2> <p>一对多内嵌表格,用于处理一对多的关系,下面是个简单的例子:</p> <p>有两张表是一对多关系:</p> <pre><code class="language-sql">CREATE TABLE `demo_painters` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `bio` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; CREATE TABLE `demo_paintings` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `painter_id` int(10) unsigned NOT NULL, `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `body` text COLLATE utf8_unicode_ci NOT NULL, `completed_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`id`), KEY painter_id (`painter_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;</code></pre> <p>表的模型为:</p> <pre><code class="language-php">&amp;lt;?php namespace App\Models\Demo; use Illuminate\Database\Eloquent\Model; class Painter extends Model { public function paintings() { return $this-&amp;gt;hasMany(Painting::class, 'painter_id'); } }</code></pre> <pre><code class="language-php">&amp;lt;?php namespace App\Models\Demo; use Illuminate\Database\Eloquent\Model; class Painting extends Model { protected $fillable = ['title', 'body', 'completed_at']; public function painter() { return $this-&amp;gt;belongsTo(Painter::class, 'painter_id'); } }</code></pre> <p>构建表单代码如下:</p> <pre><code class="language-php">use App\Models\Demo\Painter; // 这里需要显式地指定关联关系 $builder = Painter::with('paintings'); // 如果你使用的是数据仓库,则可以这样指定关联关系 // $repository = new Painter(['paintings']); return Form::make($builder, function (Form $form) { $form-&amp;gt;display('id', 'ID'); $form-&amp;gt;text('username')-&amp;gt;rules('required'); $form-&amp;gt;textarea('bio')-&amp;gt;rules('required'); $form-&amp;gt;hasMany('paintings', function (Form\NestedForm $form) { $form-&amp;gt;text('title'); $form-&amp;gt;textarea('body'); $form-&amp;gt;datetime('completed_at'); }); $form-&amp;gt;display('created_at', 'Created At'); $form-&amp;gt;display('updated_at', 'Updated At'); // 也可以设置label // $form-&amp;gt;hasMany('paintings', '画作', function (Form\NestedForm $form) { // ... // }); });</code></pre> <p>效果</p> <p><img src="{{public}}/assets/img/screenshots/has-many.png" alt="" /></p> <p>&lt;a name=&quot;has-many-table&quot;&gt;&lt;/a&gt;</p> <h3>表格模式 (table)</h3> <p>如果你想要显示表格模式,可以这样使用</p> <pre><code class="language-php">use Dcat\Admin\Support\Helper; $form-&amp;gt;hasMany('paintings', function (Form\NestedForm $form) { ... })-&amp;gt;useTable();</code></pre> <p>效果</p> <p>&lt;a href=&quot;{{public}}/assets/img/screenshots/has-many-table.png&quot; target=&quot;_blank&quot;&gt; &lt;img src=&quot;{{public}}/assets/img/screenshots/has-many-table.png&quot; style=&quot;box-shadow:0 1px 6px 1px rgba(0, 0, 0, 0.12)&quot; width=&quot;100%&quot;&gt; &lt;/a&gt;</p> <p>&lt;a name=&quot;embeds&quot;&gt;&lt;/a&gt;</p> <h2>内嵌 (embeds)</h2> <p>&gt; {tip} 内嵌表单不支持图片和文件上传表单。</p> <p>用于处理<code>mysql</code>的<code>JSON</code>类型字段数据或者<code>mongodb</code>的<code>object</code>类型数据,也可以将多个field的数据值以<code>JSON</code>字符串的形式存储在<code>mysql</code>的字符串类型字段中</p> <p>比如<code>orders</code>表中的<code>JSON</code>或字符串类型的<code>extra</code>字段,用来存储多个field的数据,先定义model:</p> <pre><code class="language-php">class Order extends Model { protected $casts = [ 'extra' =&amp;gt; 'json', ]; }</code></pre> <p>然后在form中使用:</p> <pre><code class="language-php">$form-&amp;gt;embeds('extra', function ($form) { $form-&amp;gt;text('extra1')-&amp;gt;rules('required'); $form-&amp;gt;email('extra2')-&amp;gt;rules('required'); $form-&amp;gt;mobile('extra3'); $form-&amp;gt;datetime('extra4'); $form-&amp;gt;dateRange('extra5', 'extra6', '范围')-&amp;gt;rules('required'); }); // 自定义标题 $form-&amp;gt;embeds('extra', '附加信息', function ($form) { ... });</code></pre> <p>回调函数里面构建表单元素的方法调用和外面是一样的。</p>

页面列表

ITEM_HTML