基本設定可參考此連結:https://laravel-admin.org/docs/zh/1.x/model-grid-custom-actions
從版本1.7.3開始grid的操作就變成下拉選項,但我並不需要編輯、顯示、刪除等功能,反而是要增加一個按鈕可以操作ajax,而且我還需要在ajax.data多傳一個額外的參數進去,所以決定模仿$actions->add(new Replicate)的方式,自己另外寫一個。
首先我們先下個指令增加RowAction的操作,我們可以將資料夾名稱對應所使用的Controller Name,例如我現在新增的RowAction是要對應ProductController,那麼路徑就設成Product\\XXXX,以後管理起檔案來才方便。
php artisan admin:action Product\\AddCart --grid-row --name="購物車"
如果是第一次新增,app/Admin會多增加一個叫Actions的資料夾,底下就是我們剛剛新增的Product/AddCart.php。
接著我們開始撰寫程式,我這次是想要在grid裡新增一個button,可以讓我直接將商品丟入購物車中。
<?php
namespace App\Admin\Actions\Product;
use App\Models\Cart;
use Encore\Admin\Actions\RowAction;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Encore\Admin\Facades\Admin;
class AddCart extends RowAction
{
public $name = '購物車';
public function handle(Model $model, Request $request)
{
// $model ...
$cart = new Cart();
$cart->sale_id = $request->get('_saleid');
$cart->product_id = $this->getKey();
$cart->sale_amount = 1;
...
$cart->save();
return $this->response()->success('選購成功');
}
}
然後找到要使用此RowAction的ProductController.php,因為我們沒有要直接使用$actions->add(new Replicate),所以需要自行編寫javascript,其實也不難,直接copy $actions->add(new Replicate)所產生的javascript文字來改寫就好。
提供一下我寫的grid column部份
$grid->column('id','操作')->display(function ($id) {
return "<a class='btn btn-s btn-success btn-add-to-cart' data-_key='{$id}'><i class='fa fa-cart-plus'></i> 選購</a>";
});
data-_key一定要照著這麼寫哦,不然AddCart.php裡的$this->getKey()會取不到值。
接著我們來產生javascript吧!在Controller底下增加一個function,因為最底下有個process.then(actionResolver).catch(actionCatcher),所以我們必須要補上actionResolver跟actionCatcher的定義,因為我有個值是在URL上,所以寫了一個取params的javascript,然後我增加了一個ajax.data→_saleid: urlParams.get('saleid'),如果使用自行定義是沒辦法增加data的,又或許可以?我沒找到相關的範例就是了。
use Encore\Admin\Admin; protected function iScript() { $script = <<<EOT var actionResolver = function (data) { var response = data[0]; var target = data[1]; if (typeof response !== 'object') { return $.admin.swal({type: 'error', title: 'Oops!'}); } var then = function (then) { if (then.action == 'refresh') { $.admin.reload(); } if (then.action == 'download') { window.open(then.value, '_blank'); } if (then.action == 'redirect') { $.admin.redirect(then.value); } if (then.action == 'location') { window.location = then.value; } }; if (typeof response.html === 'string') { target.html(response.html); } if (typeof response.swal === 'object') { $.admin.swal(response.swal); } if (typeof response.toastr === 'object' && response.toastr.type) { $.admin.toastr[response.toastr.type](response.toastr.content, '', response.toastr.options); } if (response.then) { then(response.then); } }; var actionCatcher = function (request) { if (request && typeof request.responseJSON === 'object') { $.admin.toastr.error(request.responseJSON.message, '', {positionClass:"toast-bottom-center", timeOut: 10000}).css("width","500px") } }; var urlParams = new URLSearchParams(window.location.search); $('.btn-add-to-cart').off('click').on('click', function() { var data = $(this).data(); var target = $(this); Object.assign(data, {"_model":"App_Models_Product"}); var process = new Promise(function (resolve,reject) { Object.assign(data, { _token: $.admin.token, _action: 'App_Admin_Actions_ProductSale_AddCart', _saleid: urlParams.get('saleid'), }); $.ajax({ method: 'POST', url: '../_handle_action_', data: data, success: function (data) { resolve([data, target]); }, error:function(request){ //reject(request); debug用 reject('選購失敗'); } }); }); process.then(actionResolver).catch(actionCatcher); }); EOT; Admin::script($script); }
完成後,我們回到grid裡加上剛剛寫的script function。
protected function grid()
{
$this->iScript();
$grid = new Grid(new Product());
...
}
好了,完成了,下篇要介紹在同個頁面上可以查看目前選購商品的按鈕。
沒有留言:
張貼留言