自定义图片追加插件实现图片动态追加(一般电商的商品列使用)

前情说明:自己写的这个插件方式比较老套,主要是快速构建:图片上传是同表单提交一起提交,必须要引入layer

效果:

先上css代码:

.my-ui-img-div{
    display: inline-block;
    margin-left: 10px;
    margin-top:5px;
    border:1px solid #96c2f1;
    background:#eff7ff;
    border-radius:5px;
}
.my-ui-img-div .my-ui-img-file{
    display: none;
}
.img-circle.my-ui-img{
    width: 60px;
    height: 60px;
}

因为用了bootstrap,所以用了bootstrap的属性:上面的img-circle就是,表示图片设置为圆形,如果没用的话,就用border-radius:5px;自己调整,同时后面用到的js里面这一块也要自己修改

在上html代码:

<!--追加图片列表样例,用在添加时-->
<div class="form-group">
        <label class="col-sm-3 control-label">画廊图片:</label>
        <div class="col-sm-8">
               <div id="galleryDiv">
                   <div id="div_0" class="my-ui-img-div">
                       <input type="file" id="file_0" class="my-ui-img-file" onchange="replace_file_img('galleryDiv','div_','file_','files','img_',0)">
                       <a href="javascript:;"><img th:src="@{/img/img-add.png}" class="img-circle my-ui-img" id="img_0" onclick="click_file_img('file_',0)"></a>
                   </div>
               </div>
        </div>
</div>

说明一下:有两个方法:

replace_file_img('galleryDiv','div_','file_','files','img_',0)"

这个方法传入参数什么意思呢,div的id为galleryDiv这个里面的所有内容是一个整体

下面说下参数意思:

第一个参数:这个整体的div最外层div的id值,记住,该div内部的所有元素的id值都是前缀加索引的形式,建议索引从0开始

第二个参数:内部第二个div的前缀

第三个参数:隐藏的file文件id的前缀

第四各参数:这一组file文件统一的file的name属性值,因为是动态的,所以需要自己指定

第五个参数:显示图片id的前缀

第六个参数:所有元素的起始索引值

click_file_img('file_',0)"

这个方法更简单了,只需要传入file文件id的前缀和统一开始索引

因为用到了图片,所以图片如下:

 

js代码如下:

//保存删除图片个数的全局对象
var deleteObj = {deleteName:[],deleteNumber:[]};

//点击图片触发文件选择
function click_file_img(filePref,index) {
    $("#"+filePref+index).click();
}

/**
 * 替换图片,divId:最外层div的id值
 * divPref,第二层div的id数值的前缀
 * filePref:file输入框id的数值前缀
 * fileName: 向后台传输的file文件的统一命名
 * imgPref:图片索引的前缀
 * index:统一的索引值,建议从0开始,name上面那些id的命名要遵循  前缀+索引  ,例如file_0,img_0
 * imgName:这个参数不用管,不用传递这个参数值
 */
function replace_file_img(divId,divPref,filePref,fileName,imgPref,index,imgName) {
    if(deleteObj.deleteName.indexOf(divId) === -1){
        deleteObj.deleteName.push(divId);
        deleteObj.deleteNumber.push(0);
    }
    var deleteIndex = deleteObj.deleteName.indexOf(divId);
    var deleteNumber = deleteObj.deleteNumber[deleteIndex];

    var length = $("#"+divId+" :file").length;//得到该部分文件的个数

    var blob_img = $("#"+filePref+index)[0].files[0];
    console.log(blob_img);
    if((blob_img.type).indexOf("image/") === -1){
        if(length === 1 || ((index+1-deleteNumber) === length)){
            layer.msg("请选择图片");
        }else{
            layer.msg("请选择图片,因不是图片,所以该部分文件将被删除");
            setTimeout(function(){
                $("#"+divPref+index).remove();
                deleteNumber++;
                deleteObj.deleteNumber.splice(deleteIndex,1,deleteNumber);
            },2000);
        }
        $("#"+filePref+index).attr("name","");//清空最后一个选择图标的name,不传往后台
        return;
    }

    if($("#"+imgName+index).length > 0) {//判断隐藏域参数是否存在,存在就修改为false,表示不存在
        var imgUrlDataUrl = $("#"+imgName+index).val();
        var imgUrlData = JSON.parse(imgUrlDataUrl);
        $("#"+imgName+index).val('["'+imgUrlData[0]+'","false"]');
        $("#"+filePref+index).attr("name",fileName);//修改name值
    }

    var url = window.URL.createObjectURL(blob_img);
    //替换url图片url
    $("#"+imgPref+index).attr("src",url);

    if((index+1-deleteNumber) === length){
        $("#"+filePref+index).attr("name",fileName);//修改name值,因为在添加新的file是要讲之前的name值加上
        add_file_img(divId,divPref,filePref,fileName,imgPref,index);
        var elem = '<a href="javascript:;" onclick="img_file_delete(\''+divId+'\',\''+divPref+'\','+(index)+')" onmouseover="OverHint(this)" onmouseout="OutHint()">' +
            '<img src="'+ctx+'img/img_remove.png" style="width: 20px;;position: relative;left: 0px;top:20px">' +
            '</a>';
        $("#"+imgPref+index).after(elem);

    }

}
function add_file_img(divId,divPref,filePref,fileName,imgPref,index) {
    var elem1 = '<div id="'+divPref+(index+1)+'"style="display: inline-block;margin-left: 10px;margin-top:5px;border:1px solid #96c2f1;background:#eff7ff;border-radius:5px">';
    var elem2 = '<input type="file" id="'+filePref+(index+1)+'" style="display: none" onchange="replace_file_img(\''+divId+'\',\''+divPref+'\',\''+filePref+'\',\''+fileName+'\',\''+imgPref+'\','+(index+1)+')">';
    var elem3 = '<a href="javascript:;"><img src="'+ctx+'img/img-add.png" class="img-circle" id="'+imgPref+(index+1)+'" style="width: 60px;height: 60px" onclick="click_file_img(\''+filePref+'\','+(index+1)+')"></a>';
    var elem4 = '</div>';
    $("#"+divPref+index).after(elem1+elem2+elem3+elem4);
}

/**
 * 删除图片及文件
 * @param divId 最外层div的id名字
 * @param divPref 第二层div的id数值的前缀
 * @param index 统一的索引值,建议从0开始,name上面那些id的命名要遵循  前缀+索引  ,例如file_0,img_0
 */
function img_file_delete(divId,divPref,index,imgName,fileName) {
    var length = $("#"+divId+" :file").length;
    var deleteIndex = deleteObj.deleteName.indexOf(divId);
    var deleteNumber = deleteObj.deleteNumber[deleteIndex];
    if((index+1-deleteNumber) != length){

        if($("#"+imgName+index).length > 0) {//判断隐藏域参数是否存在,存在就修改为false,表示不存在
            var imgUrlDataUrl = $("#"+imgName+index).val();
            var imgUrlData = JSON.parse(imgUrlDataUrl);
            $("#"+imgName+index).val('["'+imgUrlData[0]+'","false"]');
            // $("#"+filePref+index).attr("name",fileName);//修改name值
        }

        $("#"+divPref+index).remove();
        deleteNumber ++;
        deleteObj.deleteNumber.splice(deleteIndex,1,deleteNumber);
        layer.close(tip_index);
    }
}
var tip_index;
function OverHint(obj) {
    var that = obj;
    tip_index = layer.tips('删除', that,{
        tips : [ 1, '#00C9BA' ],
        time : 4000
    });
}
function OutHint(obj) {
    layer.close(tip_index);
}

/**
 * 在做修改时动态追击数据
 * @param imgList 后台得到的图片列表数组
 * @param imgName 数据库对应img字段对应的【用来接收数据集合的属性名】
 * @param divId 最外层div的id值
 * @param divPref 第二层div的id值的前缀名,不包括数字索引  这种格式为:前缀+索引  ,例如file_0,img_0
 * @param filePref input文件框的id值的前缀名
 * @param fileName 要向后台传输的file的统一命名
 * @param imgPref img标签id的不包括索引值的前缀
 */
function appendImgListOnUpdate(imgList,imgName,divId,divPref,filePref,fileName,imgPref){
    console.log("加载更新包;e");
    var endIndex = 0;
    if(imgList != null && imgList.length != 0){
        imgList.forEach(function (currentValue, index, arr) {
            console.log(currentValue);
            var elem0 = '<input type="hidden" id="'+imgName+index+'" name="'+imgName+'" value=\'["'+currentValue+'","true"]\'>';
            var elem1 = '<div id="'+divPref+(index)+'"style="display: inline-block;margin-left: 10px;margin-top:5px;border:1px solid #96c2f1;background:#eff7ff;border-radius:5px">';
            var elem2 = '<input type="file" id="'+filePref+(index)+'" style="display: none" onchange="replace_file_img(\''+divId+'\',\''+divPref+'\',\''+filePref+'\',\''+fileName+'\',\''+imgPref+'\','+(index)+',\''+imgName+'\')">';
            var elem3 = '<a href="javascript:;"><img src="'+currentValue+'" class="img-circle" id="'+imgPref+(index)+'" style="width: 60px;height: 60px" onclick="click_file_img(\''+filePref+'\','+(index)+')"></a>';
            var elem4 = '</div>';
            var elem = '<a href="javascript:;" onclick="img_file_delete(\''+divId+'\',\''+divPref+'\','+(index)+',\''+imgName+'\',\''+fileName+'\')" onmouseover="OverHint(this)" onmouseout="OutHint()">' +
                '<img src="'+ctx+'img/img_remove.png" style="width: 20px;;position: relative;left: 0px;top:20px">' +
                '</a>';
            if(index === 0){
                $("#"+divId).append(elem0+elem1+elem2+elem3+elem4);
                $("#"+imgPref+index).after(elem);
                endIndex ++;
            }else {
                $("#"+divPref+(index-1)).after(elem0+elem1+elem2+elem3+elem4);
                $("#"+imgPref+index).after(elem);
                endIndex ++;
            }
        })
    }

    var elem1 = '<div id="'+divPref+(endIndex)+'"style="display: inline-block;margin-left: 10px;margin-top:5px;border:1px solid #96c2f1;background:#eff7ff;border-radius:5px">';
    var elem2 = '<input type="file" id="'+filePref+(endIndex)+'" style="display: none" onchange="replace_file_img(\''+divId+'\',\''+divPref+'\',\''+filePref+'\',\''+fileName+'\',\''+imgPref+'\','+(endIndex)+')">';
    var elem3 = '<a href="javascript:;"><img src="'+ctx+'img/img-add.png" class="img-circle" id="'+imgPref+(endIndex)+'" style="width: 60px;height: 60px" onclick="click_file_img(\''+filePref+'\','+(endIndex)+')"></a>';
    var elem4 = '</div>';
    if(endIndex === 0){
        $("#"+divId).append(elem1+elem2+elem3+elem4);
    }else {
        $("#"+divPref+(endIndex-1)).after(elem1+elem2+elem3+elem4);
    }
}

说明一下:因为我没有直接写css引用class,所以你看到这里面追加的样式也在里面;所以你需要把里面的图片地址换一下,也就是上面两张图片的地址

 

以上是做增加的时候:

那么做修改呢,因为要将图片显示出来,删除也要做处理

所以修改时html代码:

<!--修改时样例,调用下方方法-->
<div class="form-group">
       <label class="col-sm-3 control-label">画廊图片:</label>
       <div class="col-sm-8">
               <div id="galleryDiv">
               </div>
       </div>
</div>

是不是感觉更简单了

上面的js是通用的,引入就行了,但是你自己必须调用一个函数,见代码

<script type="text/javascript" th:inline="javascript">
    var imgsList =[[${imgsList}]];//假设这是从后台查出来放在model中的数据,那么用这种方式可以拿到,取出图片列表数组数据,调用下方方法

    //模拟数据,图片画廊做修改时,点开方法可以查看传输值的含义,可以对照添加时的标签结构理解
    var imgList = ["http://pic37.nipic.com/20140113/8800276_184927469000_2.png","http://pic40.nipic.com/20140331/9469669_142840860000_2.jpg"];
    appendImgListOnUpdate(imgList,'imgName','galleryDiv','div_','file_','files','img_');

</script>

看出来了吧,只需要调用appendImgListOnUpdate()方法即可:

* 在做修改时动态追击数据
* @param1 imgList 后台得到的图片列表数组
* @param2 imgName 数据库对应img字段对应的【用来接收数据集合的属性名】
* @param3 divId 最外层div的id值
* @param4 divPref 第二层div的id值的前缀名,不包括数字索引  这种格式为:前缀+索引  ,例如file_0,img_0
* @param5 filePref input文件框的id值的前缀名
* @param6 fileName 要向后台传输的file的统一命名
* @param7 imgPref img标签id的不包括索引值的前缀
看出来了吧,属性跟追加时是一样的,只是多了个要显示的图片集合和后台到时候接收这个集合的属性名

 

规则是这样的,因为所有的文件是统一提交的,所以在做删除的时候,这些接受到的集合是隐藏域,没显示的,隐藏域中的值是json格式的数据

显示效果:

这是隐藏域的内容,看出来了么,name,就是之前指定的后台接收这个存在的数据的属性,必须是个集合接收

这个拿到的数据在隐藏域中是json格式的,是个数组,第一个值表示的就是图片地址,第二个表示是否存在

开始的时候是存在的,所以是true

当我们删除之后呢

可以看到变成了false,这就很好办了,传到后台后,可以通过把这个集合里面的数据通过fastJson转换一下,就可以判断这条数据存在不存在了,不存在就将条数据删除了就行了,

我存在数据库中这样的多图是json格式存的,就是这样:["地址一",“地址二”],这种,所以我的处理方式是

新建集合,将这些为true的数据装进新的集合,false的不管,然后再将接受的file文件上传得到地址装进这个新集合,将这个新集合直接转换成json数据替换原有的该字段的数据

 

前端ajax一定要指定 mimeType: "multipart/form-data"

var data = getFormDateReturnForm("form-customer-add");//得到表单数据

var files = new Array();
$("input[name='files']").each(function(){
   files.put($(this).files[0]);
});
data.append("files", files);

$.ajax({
     cache: true,
     type: "POST",
     url: ctx + "vip/customer/add",
     data: data,
     contentType: false,
     processData: false,
     mimeType: "multipart/form-data",
     async: false,
     error: function (request) {
          $.modal.alertError("系统错误");
     },
     success: function (data) {
          $.operate.saveSuccess(JSON.parse(data));
     }
 });
//拿到表单中的数据,返回表单对象,传入的是form表单的id
function getFormDateReturnForm(id) {
	var form = new FormData();
	var t = $('#' + id).serializeArray();
	$.each(t, function() {
		form.append(this.name,this.value);
	});
	return form;
}

后台:这样就拿到相应的内容和file文件了

@LoggerManage("保存新增用户")
@RequiresPermissions("item:goods:add")
@PostMapping(value = "/add", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public JsonResult addSave(Goods goods,
                           @RequestPart(value = "files", required = false) MultipartFile[] files) throws IOException {

    //里面的内容忽略
        
        return ;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值