[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 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
关于 LearnKu
推荐文章: