T-DOC
  • Laravel-11
  • Laravel-10
  • Laravel-6X
  • Laravel-5.5
Dcat-Admin
  • Yii2
  • 重构2
  • Laravel-11
  • Laravel-10
  • Laravel-6X
  • Laravel-5.5
Dcat-Admin
  • Yii2
  • 重构2
  • 入门

    • 简介
    • 安装
    • 1.x升级指南
    • 版本升级
    • 快速开始
    • 开发前必读
    • 主题与颜色
    • 静态资源
    • 视图与自定义页面
    • 多应用 (多后台)
    • JS组件
    • 常见问题
    • Laravel Octane
  • 数据表格

    • 基本使用
    • 列的使用和扩展
    • 列的显示和扩展
    • 行的使用和扩展
    • 工具栏
    • 树状表格
    • 组合表头
    • 数据来源以及查询条件
    • 关联关系
    • 查询过滤
    • 列过滤器
    • 快捷搜索
    • 规格筛选器
    • 数据导出
    • 快捷创建
    • 行内编辑
    • 事件
    • 字段翻译
    • 数据软删除
    • 头部和脚部
    • 异步渲染
  • 数据表单

    • 基本使用
    • 图片/文件上传
    • 字段的使用
    • 字段扩展
    • 数据源
    • 表单弹窗
    • 关联关系
    • JSON表单
    • 分步表单
    • 表单验证
    • 工具表单
    • 事件以及表单响应
    • 初始化
    • 表单布局
    • 字段翻译
    • 字段动态显示
  • 数据详情

    • 基本使用
    • 字段显示
    • 关联关系
    • 字段显示扩展
    • 初始化
    • 字段翻译
  • 模型树

    • 基本使用
  • 数据仓库

    • 基本使用
  • 动作

    • 基本使用
    • 数据表格
    • 数据表单
    • 数据详情
    • 模型树
  • 多语言

    • 基本使用
  • 开发扩展

    • 扩展基本使用
    • 开发扩展
  • 页面组件

    • 异步加载
    • 图表
    • 数据统计卡片
    • 模态窗 (Modal)
    • 工具表单
    • 下拉菜单
    • 单/复选框
    • 选项卡
    • 警告框
    • 提示窗
    • Markdown
    • 卡片
  • 区块 (section)

    • 区块基本使用
  • 动作以及表单响应

    • 动作以及表单响应
  • 权限控制

    • 权限控制
  • 菜单

    • 菜单基本使用
  • 帮助函数

    • 帮助函数
  • 开发工具

    • 基本使用
  • 自定义登陆认证

    • 自定义登录
  • 自定义头部导航

    • 自定义头部导航条
  • 更新日志

    • BETA版本更新日志
    • 更新日志

工具表单

工具表单(Dcat\Admin\Widgets\Form)用来构建表单和处理提交数据,可以很方便的独立处理数据,而不需要额外注册路由。

基本使用

用命令admin:form来生成表单类文件:

php artisan admin:form Setting

将会生成表单文件app/Admin/Forms/Setting.php

<?php

namespace App\Admin\Forms;

use Dcat\Admin\Widgets\Form;
use Symfony\Component\HttpFoundation\Response;

class Setting extends Form
{
    // 处理表单提交请求
    public function handle(array $input)
    {
        // dump($input);

        // return $this->response()->error('Your error message.');

        return $this->response()->success('Processed successfully.')->refresh();
    }

    // 构建表单
    public function form()
    {
        // Since v1.6.5 弹出确认弹窗 
        $this->confirm('您确定要提交表单吗', 'content');

        $this->text('name')->required();
        $this->email('email')->rules('email');
    }

    /**
     * 返回表单数据,如不需要可以删除此方法
     *
     * @return array
     */
    public function default()
    {
        return [
            'name'  => 'John Doe',
            'email' => 'John.Doe@gmail.com',
        ];
    }
}

在上面的表单类里面,在form方法中构建表单项,使用方法和数据表单一致,default方法用来给这个表单项设置默认数据。

在页面中填入数据提交表单之后,请求会进入到handle方法中,在这里可以加入你的数据处理逻辑,处理完成之后可以通过success或error方法响应数据到前端:

    public function handle(array $input)
    {
        // $input是你接收到的表单数据
        // 在这里可以写你的处理逻辑


        // 第一个参数是响应的成功信息,第二个参数是要跳转的路由
        return $this->response()->success('Processed successfully.')->refresh();
    }

然后按照下面的方法将上面的表单放到你的页面中:

<?php

use App\Admin\Forms\Setting;
use App\Http\Controllers\Controller;
use Dcat\Admin\Widgets\Card;
use Dcat\Admin\Layout\Content;

class UserController extends Controller
{
    public function setting(Content $content)
    {
        return $content
            ->title('网站设置')
            ->body(new Card(new Setting()));
    }
}

弹出确认弹窗

第二个参数可忽略

$this->confirm('title', 'content');

响应方法

参考动作以及表单响应章节

自定义表单保存的后续行为

<?php

namespace App\Admin\Forms;

use Dcat\Admin\Widgets\Form;
use Symfony\Component\HttpFoundation\Response;

class Setting extends Form
{
    ...

    /**
      * 设置表单保存成功后执行的JS
      * 
     * @return string|void
     */
    protected function savedScript()
    {
        return <<<JS
        // data 为接口返回数据
        if (! data.status) {
            Dcat.error(data.message);

            return false;
        }

        Dcat.success(data.message);

        if (data.redirect) {
            Dcat.reload(data.redirect)
        }

        // 中止后续逻辑(默认逻辑)
        return false;
JS;
    }

    /**
     * 设置表单保存失败后执行的JS
     * 
     * @return string|void
     */
    protected function errorScript()
    {
        return <<<JS
        var errorData = JSON.parse(response.responseText);

        if (errorData) {
            Dcat.error(errorData.message);
        } else {
            console.log('提交出错', response.responseText);
        }

        // 终止后续逻辑执行(默认逻辑)
        return false;
JS;
    }
}

布局

column多列布局

<?php

use Dcat\Admin\Widgets\Form;

class Setting extends Form
{
    public function form()
    {
        $this->column(6, function () {
            $this->text('text1');

            ...
        });

        $this->column(6, function () {
            $this->text('text2');

            ...
        });
    }    
}

tab选项卡布局

<?php

use Dcat\Admin\Widgets\Form;

class Setting extends Form
{
    public function form()
    {
        $this->tab('选项卡1', function () {
            $this->text('text1');

            ...
        });

        $this->tab('选项卡2', function () {
            $this->text('text2');

            ...
        });
    }    
}

row多行布局

public function form()
{
    $this->row(function ($row) {
        $row->width(3)->text('text1');

        ...
    });

    $this->row(function ($row) {
        $row->width(3)->text('text2');

        ...
    });
} 

在弹窗中显示

Since v1.7.0

基本用法

使用命令生成工具表单php artisan admin:form ResetPassword,然后修改表单文件如下

<?php

namespace App\Admin\Forms;

use Dcat\Admin\Widgets\Form;

class ResetPassword extends Form
{
    // 处理请求
    public function handle(array $input)
    {
        $password = $input['password'] ?? null;

        // 逻辑操作

        return $this->response()->success('密码修改成功');
    }

    public function form()
    {
        $this->password('password')->required();
        // 密码确认表单
        $this->password('password_confirm')->same('password');
    }

    // 返回表单数据,如不需要可以删除此方法
    public function default()
    {
        return [
            'password'         => '',
            'password_confirm' => '',
        ];
    }
}

使用

use App\Admin\Forms\ResetPassword;
use Dcat\Admin\Widgets\Modal;

$modal = Modal::make()
    ->lg()
    ->title('修改密码')
    ->body(ResetPassword::make())
    ->button('修改密码');

异步加载

只需要让Form表单类实现Dcat\Admin\Contracts\LazyRenderable接口即可支持异步渲染功能,修改上面创建的工具表单类如下

<?php

namespace App\Admin\Forms;

use Dcat\Admin\Widgets\Form;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Contracts\LazyRenderable;

class ResetPassword extends Form implements LazyRenderable
{
    use LazyWidget; 

    // 处理请求
    public function handle(array $input)
    {
        // 获取外部传递参数
        $id = $this->payload['id'] ?? null;

        $password = $input['password'] ?? null;

        // 逻辑操作

        return $this->response()->success('密码修改成功');
    }

    public function form()
    {
        // 获取外部传递参数
        $id = $this->payload['id'] ?? null;

        $this->password('password')->required();
        // 密码确认表单
        $this->password('password_confirm')->same('password');
    }

    // 返回表单数据,如不需要可以删除此方法
    public function default()
    {
        // 获取外部传递参数
        $id = $this->payload['id'] ?? null;

        return [
            'password'         => '',
            'password_confirm' => '',
        ];
    }
}

使用代码与上面基本一致,并且我们可以用payload方法往表单里面传递自定义参数

use App\Admin\Forms\ResetPassword;
use Dcat\Admin\Widgets\Modal;

$modal = Modal::make()
    ->lg()
    ->title('修改密码')
    ->body(ResetPassword::make()->payload(['id' => '...'])) // 传递自定义参数
    ->button('修改密码');

表格行操作弹窗

下面通过一个数据表格修改密码的行操作功能来展示弹窗结合工具表单的用法:

使用命令生成工具表单php artisan admin:form ResetPassword,然后修改表单文件如下

<?php

namespace App\Admin\Forms;

use Dcat\Admin\Models\Administrator;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Dcat\Admin\Contracts\LazyRenderable;

class ResetPassword extends Form implements LazyRenderable
{
    use LazyWidget; // 使用异步加载功能

    // 处理请求
    public function handle(array $input)
    {
        // 获取外部传递参数
        $id = $this->payload['id'] ?? null;

        // 表单参数
        $password = $input['password'] ?? null;

        if (! $id) {
            return $this->response()->error('参数错误');
        }

        $user = Administrator::query()->find($id);

        if (! $user) {
            return $this->response()->error('用户不存在');
        }

        $user->update(['password' => bcrypt($password)]);

        return $this->response()->success('密码修改成功');
    }

    public function form()
    {
        // 获取外部传递参数
        //$id = $this->payload['id'] ?? null;

        $this->password('password')->required();
        // 密码确认表单
        $this->password('password_confirm')->same('password');
    }

    // 返回表单数据,如不需要可以删除此方法
    public function default()
    {
        return [
            'password'         => '',
            'password_confirm' => '',
        ];
    }
}

然后运行php artisan admin:action命令,选择选项2,生成数据表格行操作类,并修改如下:

<?php

namespace App\Admin\Actions\Grid;

use App\Admin\Forms\ResetPassword as ResetPasswordForm;
use Dcat\Admin\Widgets\Modal;
use Dcat\Admin\Grid\RowAction;

class ResetPassword extends RowAction
{
    protected $title = '修改密码';

    public function render()
    {
        // 实例化表单类并传递自定义参数
        $form = ResetPasswordForm::make()->payload(['id' => $this->getKey()]);

        return Modal::make()
            ->lg()
            ->title($this->title)
            ->body($form)
            ->button($this->title);
    }
}

使用

use App\Admin\Actions\Grid\ResetPassword;

$grid->actions([new ResetPassword()]);

效果

表格批量操作弹窗

如果你想在批量操作按钮中使用表单弹窗,可以参考以下例子:

这里我们仍然沿用上面用到的App\Admin\Forms\ResetPassword表单,并修改如下

<?php

namespace App\Admin\Forms;

use Dcat\Admin\Models\Administrator;
use Dcat\Admin\Widgets\Form;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Contracts\LazyRenderable;

class ResetPassword extends Form implements LazyRenderable
{
    use LazyWidget;

    // 处理请求
    public function handle(array $input)
    {
        // id转化为数组
        $id = explode(',', $input['id'] ?? null);
        $password = $input['password'] ?? null;

        if (! $id) {
            return $this->response()->error('参数错误');
        }

        $users = Administrator::query()->find($id);

        if ($users->isEmpty()) {
            return $this->response()->error('用户不存在');
        }

        // 这里改为循环批量修改
        $users->each(function ($user) use ($password) {
             $user->update(['password' => bcrypt($password)]);
        });

        return $this->response()->success('密码修改成功');
    }

    public function form()
    {
        $this->password('password')->required();
        // 密码确认表单
        $this->password('password_confirm')->same('password');

        // 设置隐藏表单,传递用户id
        $this->hidden('id')->attribute('id', 'reset-password-id');
    }

    // 返回表单数据,如不需要可以删除此方法
    public function default()
    {
        return [
            'password'         => '',
            'password_confirm' => '',
        ];
    }
}

然后运行php artisan admin:action命令,选择选项1,生成数据表格批量操作类,并修改如下:

<?php

namespace App\Admin\Actions\Grid;

use App\Admin\Forms\ResetPassword as ResetPasswordForm;
use Dcat\Admin\Widgets\Modal;
use Dcat\Admin\Grid\BatchAction;

class BatchResetPassword extends BatchAction
{
    protected $title = '修改密码';

    public function render()
    {
        // 实例化表单类
        $form = ResetPasswordForm::make();

        return Modal::make()
            ->lg()
            ->title($this->title)
            ->body($form)
            // 因为此处使用了表单异步加载功能,所以一定要用 onLoad 方法
            // 如果是非异步方式加载表单,则需要改成 onShow 方法
            ->onLoad($this->getModalScript())
            ->button($this->title);
    }

    protected function getModalScript()
    {
        // 弹窗显示后往隐藏的id表单中写入批量选中的行ID
        return <<<JS
// 获取选中的ID数组
var key = {$this->getSelectedKeysScript()}

$('#reset-password-id').val(key);
JS;
    }
}

使用

use App\Admin\Actions\Grid\BatchResetPassword;

$grid->batchActions([new BatchResetPassword()]);
Last Updated:
Contributors: Hans
Prev
表单验证
Next
事件以及表单响应