工具栏
<h1>工具栏</h1>
<h2>工具按钮</h2>
<p>在<code>model-grid</code>的头部默认有<code>批量删除</code>和<code>刷新</code>两个操作工具,如果有更多的操作需求,系统提供了自定义工具的功能,下面的示例添加一个性别分类选择的按钮组工具。</p>
<p><a name="outline"></a></p>
<h3>设置工具栏按钮样式</h3>
<p>工具栏按钮默认显示<code>outline</code>模式,效果如下</p>
<p>用法</p>
<pre><code class="language-php">$grid-&gt;toolsWithOutline();
// 禁止
$grid-&gt;toolsWithOutline(false);</code></pre>
<p>效果
<a href="{{public}}/assets/img/screenshots/outline.png" target="_blank">
<img style="box-shadow:0 1px 6px 1px rgba(0, 0, 0, 0.12)" width="100%" src="{{public}}/assets/img/screenshots/outline.png">
</a></p>
<p>禁用<code>outline</code>后的效果</p>
<p><a href="{{public}}/assets/img/screenshots/n-outline.png" target="_blank">
<img style="box-shadow:0 1px 6px 1px rgba(0, 0, 0, 0.12)" width="100%" src="{{public}}/assets/img/screenshots/n-outline.png">
</a></p>
<p>如果你希望某个按钮不使用<code>outline</code>模式,可以在按钮的<code>class</code>属性中加上<code>disable-outline</code></p>
<pre><code class="language-php">$grid-&gt;tools('&lt;a class=&quot;btn btn-primary disable-outline&quot;&gt;测试按钮&lt;/a&gt;');</code></pre>
<h3>自定义工具栏按钮</h3>
<p>先定义工具类<code>app/Admin/Extensions/Tools/UserGender.php</code>继承工具类的基类<code>Dcat\Admin\Grid\Tools\AbstractTool</code>:</p>
<pre><code class="language-php">&lt;?php
namespace App\Admin\Grid\Tools;
use Dcat\Admin\Admin;
use Dcat\Admin\Grid\Tools\AbstractTool;
class UserGender extends AbstractTool
{
protected function script()
{
$url = request()-&gt;fullUrlWithQuery(['gender' =&gt; '_gender_']);
return &lt;&lt;&lt;JS
$('input:radio.user-gender').change(function () {
var url = &quot;$url&quot;.replace('_gender_', $(this).val());
Dcat.reload(url);
});
JS;
}
public function render()
{
Admin::script($this-&gt;script());
$options = [
'all' =&gt; 'All',
'm' =&gt; 'Male',
'f' =&gt; 'Female',
];
return view('admin.tools.gender', compact('options'));
}
}</code></pre>
<p>视图<code>admin.tools.gender</code>文件为<code>resources/views/admin/tools/gender.blade.php</code>:</p>
<pre><code class="language-html">&lt;div class=&quot;btn-group&quot; data-toggle=&quot;buttons&quot;&gt;
@foreach($options as $option =&gt; $label)
&lt;label class=&quot;btn btn-default {{ request()-&gt;get('gender', 'all') == $option ? 'active' : '' }}&quot;&gt;
&lt;input type=&quot;radio&quot; class=&quot;user-gender&quot; value=&quot;{{ $option }}&quot;&gt;{{$label}}
&lt;/label&gt;
@endforeach
&lt;/div&gt;</code></pre>
<p>在<code>Grid</code>引入这个工具:</p>
<pre><code class="language-php">$grid-&gt;tools(new UserGender());</code></pre>
<p>在<code>model-grid</code>定义中接收到<code>gender</code>参数后,做好数据查询就可以了:</p>
<pre><code class="language-php">if (in_array($gender = request()-&gt;get('gender'), ['m', 'f'])) {
$grid-&gt;model()-&gt;where('gender', $gender);
}</code></pre>
<p>可以参考上面的方式来添加自己的工具。</p>
<h3>进阶用法</h3>
<p>如果你的工具按钮需要与后端API进行交互,则可以参考以下方式定义:</p>
<p>> {tip} <code>AbstractTool</code>类是属于<code>Dcat\Admin\Actions\Action</code>的子类,本质也是动作类的一种,更详细用法请参考<a href="action.md">动作类基本使用</a>。</p>
<pre><code class="language-php">&lt;?php
namespace App\Admin\Grid\Tools;
use Dcat\Admin\Grid\Tools\AbstractTool;
use Illuminate\Http\Request;
class SendMessage extends AbstractTool
{
/**
* 按钮样式定义,默认 btn btn-white waves-effect
*
* @var string
*/
protected $style = 'btn btn-white waves-effect';
/**
* 按钮文本
*
* @return string|void
*/
public function title()
{
return '发送提醒';
}
/**
* 确认弹窗,如果不需要则返回空即可
*
* @return array|string|void
*/
public function confirm()
{
// 只显示标题
// return '您确定要发送新的提醒消息吗?';
// 显示标题和内容
return ['您确定要发送新的提醒消息吗?', '确认信息内容,如没有可以留空'];
}
/**
* 处理请求
* 如果你的类中包含了此方法,则点击按钮后会自动向后端发起ajax请求,并且会通过此方法处理请求逻辑
*
* @param Request $request
*/
public function handle(Request $request)
{
// 你的代码逻辑
return $this-&gt;response()-&gt;success('发送成功')-&gt;refresh();
}
/**
* 设置请求参数
*
* @return array|void
*/
public function parameters()
{
return [
];
}
}</code></pre>
<p>使用</p>
<pre><code class="language-php">use App\Admin\Grid\Tools\SendMessage;
$grid-&gt;tools(new SendMessage());</code></pre>
<h3>添加工具类</h3>
<p><code>Grid::tools</code> 方法允许传入 <code>string</code>,<code>array</code>, <code>AbstractTool</code> 和 <code>闭包</code>等类型参数,下面是演示。</p>
<pre><code class="language-php">// 传入字符串
$grid-&gt;tools('&lt;a class=&quot;btn btn-sm btn-default&quot;&gt;工具按钮测试&lt;/a&gt;');
// 传入数组
$grid-&gt;tools([
'&lt;a class=&quot;btn btn-sm btn-default&quot;&gt;工具按钮测试&lt;/a&gt;',
new UserGender(),
]);
// 传入闭包
$grid-&gt;tools(function (Grid\Tools $tools) {
$tools-&gt;append(new UserGender());
});</code></pre>
<p><a name="batch"></a></p>
<h2>批量操作</h2>
<h3>禁用批量删除</h3>
<p>系统默认开启了批量删除操作的功能,如果要禁用批量删除操作:</p>
<pre><code class="language-php">$grid-&gt;tools(function ($tools) {
$tools-&gt;batch(function ($batch) {
$batch-&gt;disableDelete();
});
});
// 也可以这样
$grid-&gt;disableBatchDelete();
// 或
$grid-&gt;batchActions(function (Grid\Tools\BatchActions $batch) {
$batch-&gt;disableDelete();
});</code></pre>
<h3>自定义批量操作</h3>
<p>下面通过扩展一个对文章批量发布的功能来演示自定义批量操作的功能:</p>
<p>先定义操作类<code>app/Admin/Extensions/Tools/ReleasePost.php</code>,继承<code>Dcat\Admin\Grid\BatchAction</code>:</p>
<p>> {tip} <code>BatchAction</code>类是属于<code>Dcat\Admin\Actions\Action</code>的子类,本质也是动作类的一种,更详细用法请参考<a href="action.md">动作类基本使用</a>。</p>
<pre><code class="language-php">&lt;?php
namespace App\Admin\Extensions\Tools;
use Dcat\Admin\Grid\BatchAction;
use Illuminate\Http\Request;
class ReleasePost extends BatchAction
{
protected $action;
// 注意action的构造方法参数一定要给默认值
public function __construct($title = null, $action = 1)
{
$this-&gt;title = $title;
$this-&gt;action = $action;
}
// 确认弹窗信息
public function confirm()
{
return '您确定要发布已选中的文章吗?';
}
// 处理请求
public function handle(Request $request)
{
// 获取选中的文章ID数组
$keys = $this-&gt;getKey();
// 获取请求参数
$action = $request-&gt;get('action');
foreach (Post::find($keys) as $post) {
$post-&gt;released = $action;
$post-&gt;save();
}
$message = $action ? '文章发布成功' : '文章下线成功';
return $this-&gt;response()-&gt;success($message)-&gt;refresh();
}
// 设置请求参数
public function parameters()
{
return [
'action' =&gt; $this-&gt;action,
];
}
}</code></pre>
<p>看代码的实现,通过click操作发送一个post请求,把选中的行数据<code>id</code>通过数组的形式传给后端接口,后端接口拿到<code>id</code>列表和要修改的状态来更新数据,然后前端刷新页面(pjax reload),并弹出<code>toastr</code>提示操作成功。</p>
<p>在<code>model-grid</code>中加入这个批量操作功能:</p>
<pre><code class="language-php">$grid-&gt;batchActions([
new ReleasePost('发布文章', 1),
new ReleasePost('文章下线', 0)
]);
// 也可以这么写
$grid-&gt;batchActions(function ($batch) {
$batch-&gt;add(new ReleasePost('发布文章', 1));
$batch-&gt;add(new ReleasePost('文章下线', 0));
});
// 或
$grid-&gt;tools(function ($tools) {
$tools-&gt;batch(function ($batch) {
$batch-&gt;add(new ReleasePost('发布文章', 1));
$batch-&gt;add(new ReleasePost('文章下线', 0));
});
});</code></pre>
<h4>获取复选框选中的ID数组</h4>
<p>通过<code>getSelectedKeysScript</code>方法可以获取到复选框选中的ID数组,用法如下</p>
<p>> {tip} <code>getSelectedKeysScript</code>方法返回的是<code>js</code>代码,只能在<code>js</code>代码中使用。</p>
<pre><code class="language-php">&lt;?php
namespace App\Admin\Extensions\Tools;
use Dcat\Admin\Grid\BatchAction;
use Illuminate\Http\Request;
class ReleasePost extends BatchAction
{
protected $action;
public function __construct($title, $action = 1)
{
$this-&gt;title = $title;
$this-&gt;action = $action;
}
// 确认弹窗信息
public function confirm()
{
return '您确定要发布已选中的文章吗?';
}
// 处理请求
public function handle(Request $request)
{
...
}
/**
* 设置动作发起请求前的回调函数,返回false可以中断请求.
*
* @return string
*/
public function actionScript(){
$warning = __('No data selected!');
return &lt;&lt;&lt;JS
function (data, target, action) {
var key = {$this-&gt;getSelectedKeysScript()}
if (key.length === 0) {
Dcat.warning('{$warning}');
return false;
}
// 设置主键为复选框选中的行ID数组
action.options.key = key;
}
JS;
}
}</code></pre>
<h3>表单弹窗</h3>
<p>请参考文档<a href="widgets-form.md#modal">工具表单 - 弹窗</a></p>