最近公司使用
laravel(v5.5)
框架開發電商專案,後臺使用的是 laravel-admin(v1.5) 擴充套件包。laravel-admin
是一款優秀的laravel
後臺擴充套件,感謝作者一直持續維護專案,並給出詳盡的開發文件,也是有心了,致敬~
然鵝,使用過程中也有一些不順手的地方,其中之一便是: Form 元件多圖上傳功能未能實現圖片可拖拽排序功能。
經過一天時間的除錯工作,該功能已被補充至公司線上專案,並執行正常。接下來,將功能擴充套件之開發流程分享一下,以期對其它laravel-admin
使用者有所助益。
解決思路
- 首先,通過追溯專案程式碼
$form->multipleImage('photos', '相簿')
,閱讀PHP
類檔案vendor/encore/laravel-admin/src/Form/Field/MultipleImage.php
與vendor/encore/laravel-admin/src/Form/Field/MultipleFile.php
,發覺該多圖片/檔案上傳功能是藉由HTML5
檔案上傳外掛 bootstrap-fileinput 實現的。 - 通過閱讀該外掛的中文文件中的事件部分,猜想圖片拖拽排序行為觸發的應該是
filesorted
事件。 - 至此,解決思路比較清晰了,需要修改
laravel-admin
擴充套件包PHP
類檔案MultipleFile.php
,然後在前端頁面引入js
檔案,捕捉相關form
表單元素節點的filesorted
事件,做非同步Ajax
提交實現多圖上傳之圖片拖拽排序功能。
具體方案
- 參考 bootstrap-fileinput 中文文件中的首頁介紹,圖片拖拽排序功能的實現依賴於
js
子外掛sortable.min.js
的引入,因此,修改laravel-admin
擴充套件包PHP
類檔案MultipleFile.php
:@vendor/encore/laravel-admin/src/Form/Field/MultipleFile.php on Line:27 protected static $js = [ '/vendor/laravel-admin/bootstrap-fileinput/js/plugins/canvas-to-blob.min.js?v=4.3.7', '/vendor/laravel-admin/bootstrap-fileinput/js/plugins/purify.min.js?v=4.3.7', // 視需求而定 '/vendor/laravel-admin/bootstrap-fileinput/js/plugins/sortable.min.js?v=4.3.7', // 重點在這裡 '/vendor/laravel-admin/bootstrap-fileinput/js/fileinput.min.js?v=4.3.7', ];
- 開啟後臺路由檔案
app/Admin/routes.php
,為該圖片拖拽排序功能新增一條路由規則,以備Ajax
請求使用。另,在對應的後臺控制類檔案內,form()
方法下追加<input type="hidden">
標籤,為Ajax
請求提供相關資料準備,具體資料內容視業務需求而定:if ($this->mode == Builder::MODE_EDIT) { // 判斷:經由 edit() 方法呼叫該 form() 方法 ... $form->hidden('some_key')->default('some_value'); $form->hidden('another_key')->default('another_value'); ... }
- 引入前端
js
檔案,根據 laravel-admin 官方文件介紹,開啟後臺bootstrap
檔案(app/Admin/bootstrap.php
):@app/Admin/bootstrap.php Admin::js('path/to/your/js');
- js 部分程式碼之主要邏輯:
@path/to/your/js var file_input_element = $('input.photos[name="photos[]"]'); file_input_element.on('filesorted', function (event, params) { // console.log(params); // console.log(params.stack); // console.log('File sorted ', params.previewId, params.oldIndex, params.newIndex, params.stack); var token = $('input[name="_token"]').val(), some_photos = $('input.some_photos[name="some_photos"]').val(), sort_photos_url = $('input.sort_photos_url[name="sort_photos_url"]').val(); var sorted_photos = params.stack, old_photos = JSON.parse(some_photos), new_photos = {}; var photo_count = sorted_photos.length; for (var i = 0; i < photo_count; i++) { new_photos[i] = old_photos[sorted_photos[i].key]; } var some_data = { _token: token, photos: new_photos, }; $.ajax({ type: "post", url: sort_photos_url, data: some_data, success: function (data) { console.log("Some Photos Sorted!"); }, error: function (error) { console.log(error); } }); });
補刀
經同事點撥,發覺之前 具體方案
中,通過修改laravel-admin擴充套件包原始檔來實現js
外掛引入的操作很傻,不利於新增程式碼版本控制,正確的操作應該是醬紫的:
@app/Admin/bootstrap.php
Admin::js('/vendor/laravel-admin/bootstrap-fileinput/js/plugins/purify.min.js?v=4.3.7'); // 視需求而定
Admin::js('/vendor/laravel-admin/bootstrap-fileinput/js/plugins/sortable.min.js?v=4.3.7'); // 重點在這裡
至此,問題解決。
敢竭鄙懷,恭疏短引;
一言均賦,四韻俱成。
請灑潘江,各傾陸海云爾。