[Laravel Admin] 多图上传功能之扩展 -- 已上传图片之可拖拽排序
最近公司使用
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'); // 重点在这里
至此,问题解决。
敢竭鄙怀,恭疏短引;
一言均赋,四韵俱成。
请洒潘江,各倾陆海云尔。
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 5年前 自动加精
推荐文章: