iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Software Development

持續進化論系列 第 22

DAY22 - 3 2 1 Action !

  • 分享至 

  • xImage
  •  

每個 row 基本都有先附帶了 Show、Edit、Delete 三個基本的 Action,但如果還想要更多呢?那就必須要用到自定義的 Action 了,今天資訊量很大,安全帶繫好要出發了。

這次的範例會以設定 Product 與 Actor 的關聯來示範,首先先用指令建立 Action

php artisan admin:action
後面會遇到一些選項,依序設定

Which type of action would you like to make?
 [2] grid-row
Please enter a name of action class:
ProductActorAction
Please enter the namespace of action class [App\Admin\Actions\Grid]:
直接按下 Enter 不用改變

應該沒有人把上面這行字複製貼上吧?

完成之後裡面會有蠻多 Method 的,留下 handle 即可,其餘的先移除暫時先不會用到

補上兩個 use,功能後面會解釋

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

修改 title 屬性
protected $title = '<i class="fa fa-eye"></i> 演員設定';
i tag 是讓 action 有圖示

修改 handle Method

public function handle(Request $request)
{
    return $this->response();
}

新增 rendor Method

public function render()
{
    $form = ProductActorForm::make()->payload(['id' => $this->getKey()]);

    return Modal::make()
        ->lg()
        ->title('演員設定')
        ->body($form)
        ->button($this->title);
}

rendor Method 是讓點選 action 之後渲染出一個跟使用者互動的彈窗介面
payload 會讓 product_id 可以帶入到 form 來使用

接著要先增 ProductActorForm 這個 Class
php artisan admin:form ProductActorForm

這個 Class 的內容較多直接貼 Code

<?php

namespace App\Admin\Forms;

use App\Models\Actor;
use App\Models\ProductActor;
use Dcat\Admin\Widgets\Form;
use Dcat\Admin\Traits\LazyWidget;
use App\Admin\Renderable\ActorTable;
use Dcat\Admin\Contracts\LazyRenderable;
use Symfony\Component\HttpFoundation\Response;

class ProductReltationForm extends Form implements LazyRenderable
{
    use LazyWidget;
    /**
     * Handle the form request.
     *
     * @param array $input
     *
     * @return Response
     */
    public function handle(array $input)
    {

         $productActor = ProductActor::where('product_id', $this->payload['id'])->delete();

        foreach ($input['actor_id'] as $actor_id) {
            ProductActor::create([
                'product_id' => $this->payload['id'],
                'actor_id' => $actor_id,
            ]);
        }
    }

    /**
     * Build a form here.
     */
    public function form()
    {
        $this->multipleSelectTable('actor_id', '演員')
            ->title('演員')
            ->dialogWidth('75%')
            ->from(ActorTable::make())
            ->model(Actor::class, 'id', 'name')
            ->required();
    }

    /**
     * The data of the form.
     *
     * @return array
     */
    public function default()
    {
        return [

        ];
    }
}

要注意有用到 implements LazyRenderable 及 trait LazyWidget

接著手動先增一個 ProductTable Class
mkdir app/Admin/Renderable
touch app/Admin/Renderable/ActorTable.php
Code 如下

<?php

namespace App\Admin\Renderable;

use App\Models\Actor;
use Dcat\Admin\Grid;
use Dcat\Admin\Grid\LazyRenderable;

class ActorTable extends LazyRenderable
{
    public function grid(): Grid
    {
        return Grid::make(new Actor(), function (Grid $grid) {
            $grid->column('id');
            $grid->column('name', '演員名稱');
        });
    }
}

接著回去修改 Product Controller 的 Grid Method
移除 $grid->setActionClass(Grid\Displayers\Actions::class);
移除這個 setting 會讓原本直接橫列的 action 被收在點點裡
新增 $grid->actions(new ProductActorAction());
新增一個自定義的 ProductActorAction 到 action 列表

完成後即可在 List 看到 Action 有不同的內容了
https://ithelp.ithome.com.tw/upload/images/20220922/20115048sRllrAFdoW.png
https://ithelp.ithome.com.tw/upload/images/20220922/20115048hdODaijIOk.png
https://ithelp.ithome.com.tw/upload/images/20220922/20115048cw4W1XAsFs.png

今天花了大量的在實作,壓縮到了打文章的時間,但時間快到了必須交稿,只好明天再補充說明


上一篇
DAY21 - 最後一哩路,百斤扁擔不換肩
下一篇
DAY23 登出一下
系列文
持續進化論30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言