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

前情说明:自己写的这个插件方式比较老套,主要是快速构建:图片上传是同表单提交一起提交,必须要引入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
    评论
动软图片分享社区是基于动软分享社区系统开发的一套新模板,包括图片分享,视频分享,个人动态分享,小组,专辑等功能,非常适合于专注于图片互动的社区网站。支持多图片批量上传,一键采集其他网站图片,可基于地理位置和城市进行分享,且支持多种格式的缩略图及云存储功能。动软强大的模板机制,可以实现更多,更好的不同类型网站应用。内置两套模板。 动软分享社区系统(图片分享社区) 1.9 升级内容:2013.11.11 1.新增自定义商品链接分享,支持任意平台的导购。没有淘宝客权限也不怕了。这个功能也可以去做线下的营销推广功能。 2.新增模板功能,支持后台2套模板可以切换。 3.新增社区商品列表后台的批量下架功能。 4.新增后台支持设置淘点代码参数功能。 5.新增视频页面seo设置。 6.新增社区后台,商品分类管理,显示商品分类的ID功能。 7.修复了导入联盟数据,价格接口修改。 8.修复了导入联盟数据,数据量比较大的情况下变慢问题。 9.修复了后台seo关联链接里面出现重复的关键字问题。 10.修复了后台全部动态中文字动态删不掉问题。 11.修复了生成静态化后,前台没有自动获取用户信息问题。 12.修复了前台当性别改为男的时依然显示的女性图标问题。 13.修复了后台图片标签编辑功能不可用,没有添加功能问题。 14.修复了社区在英文系统安装后出现乱码问题。。 该版本重点自定义商品链接分享,支持任意平台的导购! 功能: 基础功能 安装部署简单,实现系统在线自动化一键安装过程。 多平台账号统一登陆,无需繁琐注册; 图片商品页面瀑布流效果展现,超强用户体验。 集成分享推广插件,绑定微博、人人、淘宝等账号,一键分享。 网站个性设置,站内消息,邮件通知等功能。 社交互动 收藏、喜欢、好友分享的图片商品,发现自己喜欢。 关注自己喜欢的人和动态,寻找相同兴趣爱好的朋友。 建立自己的粉丝团,让自己变成意见领袖。 社区达人 用户可申请达人,可以提升用户的积极性。 达人排行榜,可以让用户获得更高的荣誉感。多种类型的达人评选,展现达人多姿风采。 本期和历期达人排行榜,期期精彩,用户活跃无限。 运营支持 灵活的广告位管理,可招商,可投放广告获得广告佣金 ; 强大SEO优化配置功能,让搜索引擎快速发现,提升网站流量 ; 完整的内容后台审核体系,敏感字过滤。良好的运营监控体系 ; 标签管理,标签化管理碎片数据; 淘宝客账号灵活配置,轻松赚取淘宝佣金。 网站图片支持批量生成缩略图的功能。 强大的系统架构 采用最新MVC模式,界面模板分离,实现快速界面定制 ; 支持网站界面多套模板一键切换功能; 高性能的缓存机制,确保网站访问速度 ; 网站支持全站页面生成静态化功能; 强大的安全机制,防止各种注入式攻击等漏洞 ; 充分考虑了底层大数据量并发的性能问题 ; 图片上传支持云存储解决方案,不占带宽,无并发,高速访问; 多元化分享 发布心情、微博、个人动态、话题等; 照片分享,建立搭配,晒货,抓拍,旅游等图片分享社区; 分享推荐商品导购链接,为社区提供清晰盈利渠道; 分享视频,音乐,丰富网站内容,支持优酷,土豆,酷6等主流视频网站。 专辑功能,内容的评论、转发与回复功能,让信息无限传播。 淘宝客 淘宝客接口API集成,淘宝商品条件筛选一键采集,乐享佣金; 分享推荐商品导购链接,淘宝导购,赚取佣金; 商品点评,喜欢,转发分享,形成社会化营销渠道; 支持淘点金和淘宝联盟商品导入,没有淘宝客权限,也照样做淘宝客; 完善的积分体系 后台可自定义配置积分规则,各种积分方式灵活实现 ; 查询积分明细,建立用户等级,实现用户的成就; 支持实现类似积分兑换功能,激发用户活跃度; 群组功能 用户可自发建立不同的兴趣群组,邀请好友加入。 群组可设置管理员及组长等角色,会员申请加入,组长审核。 多人群聊,发表小组主题帖,文件共享,评论分享,群组互动。 权限审核管理,完备的后台权限配置和内容审核机制,维护网站的安全。 数据挖掘 用户属性分析,用户行为分析。 用户关注度分析,商品的展示与分享数据统计。 实现更精准化的用户营销,实现社会化营销;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值