如何通过 table 构建器中的按钮将信息传递给表单构建器?

How to pass information via button in table builder to a form builder?

为简化起见,我在我的 pyrocms 应用程序中附加了公司和工人。在公司中(由 table 构建器在管理面板中自动创建),每个公司的原始文件中都有按钮。 edit 按钮是开箱即用的按钮之一。所以我想添加另一个按钮,比如 'Add Worker',然后打开我已经成功创建的工人创建页面。公司和工人之间存在 multiple 关系,因为一个工人可以在多家公司工作。你可以认为它是任意 post 的类别。我想要的是,在工人创建表单页面中,我想让 'Add worker' 按钮被点击的公司 出现 自动出现在工人的 'working companies' 字段中.实施这种想法的正确方法是什么?我可以使用 attributes 将 HTML 属性传递给按钮,但我不知道它是否有帮助。

这是 CompanyTableBuilder 中的 $buttons 数组。

/**
 * The table buttons.
 * @var array|string
 */
protected $buttons = [
    'edit',
    'add_worker' => [
        'attributes' => [
            'href' => '/admin/crm/workers/create',
        ],
        'text' => 'Add worker',
        'type' => 'success',
    ]
];

假设您有两组客户:工作人员和付款人

class ClientTableBuilder extends \Anomaly\UsersModule\User\Table\UserTableBuilder
{

    /**
     * The table model
     *
     * @var string
     */
    protected $model = UserModel::class;

    /**
     * The table views.
     *
     * @var array
     */
    protected $views = [
        'workers' => [
            'query'   => WorkersQuery::class,
            'buttons' => [
                'jobs' => [
                    'type' => 'info',
                ],
            ],
        ],
        'payers'  => [
            'query'   => PayersQuery::class,
            'buttons' => [
                'payments' => [
                    'type' => 'info',
                ],
            ],
        ],
    ];

}

当您按下工作按钮时,您将转到 admin/{addon}/clients/jobs/{user_id} 路线。所以你需要有下一个控制器:

class ClientsController extends AdminController
{

    /**
     * Shows the clients list.
     *
     * @param   ClientTableBuilder  $table  The table
     * @return  Response
     */
    public function clients(ClientTableBuilder $table)
    {
        return $table->render();
    }

    /**
     * Shows the client's jobs list.
     *
     * @param   UserRepositoryInterface  $users  The users
     * @param   ClientJobsTableBuilder   $table  The table
     * @param                            $id     The identifier
     * @return  Response
     */
    public function assignedJobs(
        UserRepositoryInterface $users,
        ClientJobsTableBuilder $table,
        $id
    ) {
        /* @var UserInterface $user */
        if (!$user = $users->find($id)) {
            return $this->response->json([
                'success' => false,
                'message' => "Can't find user with id {$id}!",
            ]);
        }

        if ($this->request->ajax()) {
            $table->setAjax(true);
        }

        return $table->setUser($user)->render();
    }

    /**
     * Shows modal with unassigned jobs list
     *
     * @param   UserRepositoryInterface       $users  The users
     * @param   ClientJobsLookupTableBuilder  $table  The table
     * @param                                 $id     The identifier
     * @return  Response
     */
    public function unassignedJobs(
        UserRepositoryInterface $users,
        ClientJobsLookupTableBuilder $table,
        $id
    ) {
        /* @var UserInterface $user */
        if (!$user = $users->find($id)) {
            return $this->response->json([
                'success' => false,
                'message' => "Can't find user with id {$id}!",
            ]);
        }

        return $table->setUser($user)->render();
    }

    /**
     * Attach a job to a client
     *
     * @param   int|str       $user  The user's id
     * @param   int|str       $job   The job's id
     * @return  JsonResponse
     */
    public function attach($user, $job)
    {
        if ($error = $this->dispatch(new AttachJobToUser($user, $job))) {
            return $this->response->json([
                'success' => false,
                'message' => $error,
            ]);
        }

        return $this->response->json([
            'success' => true,
            'user'    => (int) $user,
            'job'     => (int) $job,
        ]);
    }

    /**
     * Detach a job from a client
     *
     * @param   int|str       $user  The user's id
     * @param   int|str       $job   The job's id
     * @return  JsonResponse
     */
    public function detach($user, $job)
    {
        if ($error = $this->dispatch(new DetachJobFromUser($user, $job))) {
            return $this->response->json([
                'success' => false,
                'message' => $error,
            ]);
        }

        return $this->response->json([
            'success' => true,
            'user'    => (int) $user,
            'job'     => (int) $job,
        ]);
    }
}

然后值 TB 看起来像:

class ClientJobsTableBuilder extends ValueTableBuilder
{

    /**
     * Table's user
     *
     * @var UserInterface|null
     */
    protected $user = null;

    /**
     * Table's columns
     *
     * @var array
     */
    protected $columns = [
        'name' => [
            'heading' => 'Name',
            'value'   => '<strong>{entry.name}</strong>',
        ],
        'type' => [
            'heading' => 'Type',
        ],
        'categories' => [
            'heading' => 'Categories',
            'value'   => 'entry.type.categories.pluck("name")|join("<br>")',
        ],
    ];

    /**
     * Table's buttons
     *
     * @var string
     */
    protected $buttons = ClientJobsTableButtons::class;

    /**
     * Table's actions
     *
     * @var array
     */
    protected $actions = [];

    /**
     * Table's options
     *
     * @var array
     */
    protected $options = [
        'sortable' => true,
    ];

    /**
     * Table's assets
     *
     * @var array
     */
    protected $assets = [
        'scripts.js' => [
            '{YOUR_MODULE_FULL_NS}::js/detach.js',
        ],
    ];

    /**
     * Gets the user.
     *
     * @return  UserInterface|null  The user.
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Sets the user.
     *
     * @param   UserInterface  $user  The user
     * @return  self
     */
    public function setUser(UserInterface $user)
    {
        $this->user = $user;

        return $this;
    }

}

然后第一个值表按钮:

class ClientJobsTableButtons
{

    /**
     * Handle the table buttons
     *
     * @param  ClientJobsTableBuilder  $builder  The builder
     */
    public function handle(ClientJobsTableBuilder $builder)
    {
        /* @var UserInterface $user */
        if (!$user = $builder->getUser()) {
            return;
        }

        $builder->setButtons([
            'detach' => [
                'type'         => 'danger',
                'data-detach'  => '{entry.id}',
                'data-user'    => $user->getId(),
                'data-dismiss' => 'multiple',
            ],
        ]);
    }

}

查找 TB 也是如此:

class ClientJobsLookupTableBuilder extends TableBuilder
{

    /**
     * AJAX mode flag
     *
     * @var bool
     */
    protected $ajax = true;

    /**
     * Table's user
     *
     * @var UserInterface|null
     */
    protected $user = null;

    /**
     * Table's columns
     *
     * @var array
     */
    protected $columns = [
        'name' => [
            'heading' => 'Name',
            'value'   => '<strong>{entry.name}</strong>',
        ],
        'type' => [
            'heading' => 'Type',
        ],
        'categories' => [
            'heading' => 'Categories',
            'value'   => 'entry.type.categories.pluck("name")|join("<br>")',
        ],
    ];

    /**
     * Table's buttons
     *
     * @var string
     */
    protected $buttons = ClientJobsLookupTableButtons::class;

    /**
     * Table's actions
     *
     * @var array
     */
    protected $actions = [];

    /**
     * Table's options
     *
     * @var array
     */
    protected $options = [
        'sortable' => false,
    ];

    /**
     * Table's assets
     *
     * @var array
     */
    protected $assets = [
        'scripts.js' => [
            '{YOUR_MODULE_FULL_NS}::js/attach.js',
        ],
    ];

    /**
     * Gets the user.
     *
     * @return  UserInterface|null  The user.
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Sets the user.
     *
     * @param   UserInterface  $user  The user
     * @return  self
     */
    public function setUser(UserInterface $user)
    {
        $this->user = $user;

        return $this;
    }

}

并查找 TB 按钮:

class ClientJobsLookupTableButtons
{

    /**
     * Handle the table buttons
     *
     * @param  ClientJobsLookupTableBuilder  $builder  The builder
     */
    public function handle(ClientJobsLookupTableBuilder $builder)
    {
        /* @var UserInterface $user */
        if (!$user = $builder->getUser()) {
            return;
        }

        $builder->setButtons([
            'attach' => [
                'data-attach'  => '{entry.id}',
                'data-user'    => $user->getId(),
                'data-dismiss' => 'multiple',
            ],
        ]);
    }

}

之后你只需要为正确的行为编写一些 JS。

更新:这是*查询的例子class:

class WorkersQuery
{

    /**
     * Handle the query.
     *
     * @param  Builder                  $query  The query builder
     * @param  RoleRepositoryInterface  $roles  The roles repository
     */
    public function handle(Builder $query, RoleRepositoryInterface $roles)
    {
        /* @var RoleInterface $role */
        $role = $roles->findBySlug('worker');

        $query
            ->leftJoin(
                'users_users_roles',
                'users_users_roles.entry_id',
                '=',
                'users_users.id'
            )
            ->where('users_users_roles.related_id', $role->getId());
    }

}

以及 AttachJobToUser 命令的示例:

class AttachJobToUser
{

    /**
     * User's identifier
     *
     * @var mixed
     */
    protected $user;

    /**
     * Job's identifier
     *
     * @var mixed
     */
    protected $job;

    /**
     * Create a new instance of AttachJobToUser class
     *
     * @param $user
     * @param $job
     */
    public function __construct($user, $job)
    {
        $this->user = $user;
        $this->job  = $job;
    }

    /**
     * Handle the command
     *
     * @param   UserRepositoryInterface  $users  The users
     * @param   JobRepositoryInterface   $jobs   The jobs
     * @return  boolean|string
     */
    public function handle(
        UserRepositoryInterface $users,
        JobRepositoryInterface $jobs
    ) {
        /* @var UserInterface $user */
        if (!$user = $users->find($this->user)) {
            return "Can't find user with id '{$this->user}'";
        }

        /* @var JobInterface $job */
        if (!$job = $jobs->find($this->job)) {
            return "Can't find job with id '{$this->job}'";
        }

        if (!$job->addWorker($user)) {
            return "Can't attach a job with id '{$this->job}' to a worker with id '{$this->user}'";
        }

        return false;
    }

}