前端js实现文件多次添加累加上传和选择删除(django+js)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

前言

原本的多文件上传功能在选择文件时只能通过同一范围的鼠标框选或者ctrl/shift多选取选择文件这样选择文件很不灵活而且在确定之后如果漏选了文件再次点击上传按钮时会清空表单里的文件信息只能重复之前的操作去选文件再加上漏选的文件十分不方便。

所以在大部分网站上选择图片上传都是可以累加的就是在第一次选择完文件点击确定后第二次再点击上传按钮选文件会自动跟第一次的接在一起然后展示在界面上方便用户单独进行删除。文章的主旨就是在不用插件的情况下实现这样的效果。

一.实现效果

1.第一次添加1个文件

在这里插入图片描述

2.第二次添加2个文件

在这里插入图片描述
可多次添加多个文件点击删除图标可进行文件的移除

二.代码实现

该项目用的是django+js前端部分基本都差不多废话不多说直接上代码吧。
这里贴主要的代码如有问题可评论或私信。

1.html部分

form表单

{% block main %}
<!--根据自己项目目录路径引入自定义上传的组件的样式fileUpload.css文件-->
<link href="../../../static/public/css/fileUpload.css" rel="stylesheet"/>
...
	<form id="dataStructureForm" method="post" class="container">
		
		...
	    <!--add attachment-->
	    <div class="form-group">
	        <label class="font-weight-bold">Add attachments:</label>
	        <input class="choose-file-clip" type="file" id="selectFile" name="uploadFileBase" multiple="multiple">
	        <label for="selectFile" class="choose-file"><i class="fa fa-paperclip"></i> Choose File</label>
	        <div id="showFileName" class="upfile-list-mes"></div>
	        <span class="form-text text-muted">所有文件大小不超过50M。</span>
	    </div>
	    ...
	</form>
	...
{% endblock %}

<!-- 此处为django模板加载js的写法 -->
{% block script %}
    <script src="../../../static/pages/xxxxxxxxxxxx/xxxxxxxxx/addDataStructure.js"
            type="text/javascript"></script>
{% endblock %}

自定义上传的组件的样式fileUpload.css文件

.choose-file-clip {
    position: absolute;
    clip: rect(0, 0, 0, 0);
}

.choose-file {
    padding: 5px 20px;
    font-size: larger;
    background: #2ECA8B;
    border-radius: 4px;
    color: white;
    cursor: pointer;
}

.upfile-list-mes {
    color: #00bfff;
}

.icon-remove {
    cursor: pointer;
    color: #FD5373;
    font-size: medium;
}

.file-name {
    /*color: #00bfff;*/
    color: #161C2D;
    font-size: medium;
    margin: 0;
}

2.js部分

最重要的部分文件追加逻辑 fileUpload.js

var fileLists = [];
var fileNameList = []

// 选择文件
$("#selectFile").on('change', function (event) {
    let _files = this.files;
    // console.log(_files)
    if (_files.length > 0) {
        _files = Array.from(_files); //将伪数组专为真数组修改
        for (let i = 0; i < _files.length; i++) {
            // 文件去重处理
            if (fileNameList.indexOf(_files[i].name) === -1) {
                console.log('not found-->' + _files[i].name)
                fileLists.push(_files[i]);
                fileNameList.push(_files[i].name)
                let html = "<p class='file-name'>" + _files[i].name + sizeToStr(_files[i].size) + "&nbsp;&nbsp;&nbsp;&nbsp;   <span class='icon-remove'><i class='fa fa-trash'></i></span></p>"
                $('.upfile-list-mes').append(html);
            }
        }
    }
    console.log(fileLists)
})

function sizeToStr(size) {
    var data = "";
    if (size < 0.1 * 1024) { //如果小于0.1KB转化成B
        data = size.toFixed(2) + "B";
    } else if (size < 0.1 * 1024 * 1024) { //如果小于0.1MB转化成KB
        data = (size / 1024).toFixed(2) + "KB";
    } else if (size < 0.1 * 1024 * 1024 * 1024) { //如果小于0.1GB转化成MB
        data = (size / (1024 * 1024)).toFixed(2) + "MB";
    } else { //其他转化成GB
        data = (size / (1024 * 1024 * 1024)).toFixed(2) + "GB";
    }
    var sizestr = data + "";
    var len = sizestr.indexOf("\.");
    var dec = sizestr.substr(len + 1, 2);
    if (dec === "00") { //当小数点后为00时 去掉小数部分
        return '&nbsp;&nbsp;(' + sizestr.substring(0, len) + sizestr.substr(len + 3, 2) + ')';
    }
    return '&nbsp;&nbsp;(' + sizestr + ')';
}

// 删除文件
$(document).on('click', '.icon-remove', function (event) {
    let ind = $(this).parent().index();
    $(this).parent().remove();
    fileLists.splice(ind, 1);
    fileNameList.splice(ind, 1);
    console.log(fileLists)
});

下面是前端提交form表单数据包含文件到后台的js,也就是django模板加载的addDataStructure.js

// 导入上传附加的js
document.write('<script src="../../../../static/public/js/fileUpload.js" type="text/javascript" charset="utf-8"></script>');

function SubmitForm() {
    var submitbtn1 = document.getElementById("SubmitTop");
    var submitbtn2 = document.getElementById("SubmitBottom");
    var title = document.getElementById("id_title").value;
    var full_name = document.getElementById("id_full_name").value;
    var knowledge_category = document.getElementById("id_knowledge_category").value;
    var team = document.getElementById("id_team").value;
    console.log(title, full_name, knowledge_category, team)
    //确认必选项是否都已填
    if (title === '' || full_name === '' || knowledge_category === '' || team === '') {
        submitbtn2.disabled = false;
        submitbtn1.disabled = false;
        $.messager.alert("提示", 'Must input all items with * !', "warning");
        return false;
    }
    var formData = new FormData($("#dataStructureForm")[0]);
    if (fileLists.length > 0) {
        var fileSize = 0
        // 判断文件大小
        for (let i = 0; i < fileLists.length; i++) {
            fileSize += fileLists[i].size
            if (fileSize > 50 * 1024 * 1024) {
                console.log('file size:', sizeToStr(fileSize))
                $.messager.alert("提示", '所有文件大小不能超过50M!', "warning");
                return
            }
        }
        // 将文件添加到form表单中
        $(fileLists).each(function (i, e) {
            formData.append('uploadFile', e)
        })
    }
    submit(formData)
}

function submit(formData) {
    var submitbtn1 = document.getElementById("SubmitTop");
    var submitbtn2 = document.getElementById("SubmitBottom");
    submitbtn2.disabled = true;
    submitbtn1.disabled = true;
    submitbtn1.value = "loading...";
    submitbtn2.value = "loading...";
    $.ajax({
        url: server_url + '/teams/add_data_structure/',
        method: 'POST',
        data: formData,
        dataType: "json",
        processData: false,
        contentType: false,
        cache: false,
        success: function (data) {
            console.log("data:" + data);
            console.log("data:" + data.res);
            if (data.status === 200) {
                $.messager.alert("提示", data.msg, "info");
                console.log("data:" + data.msg);
                window.setTimeout("window.location=server_url+'/teams/data_structure'", 500);
                return;
            }
            submitbtn2.disabled = false;
            submitbtn1.disabled = false;
            submitbtn1.value = "Submit";
            submitbtn2.value = "Submit";
            console.log(data)
            $.messager.alert("提示", data.msg, "info");
        },
        //请求失败包含具体的错误信息
        error: function (data) {
            console.log(data.msg);
        }
    });
}

3.django后端

附上django后台处理上传文件的接口代码仅供参考这里用的是序列化器写的。
接口url

urlpatterns = [
    path('add_data_structure/', AddDataStructureView.as_view(), name='add_data_structure'),
]
class AddDataStructureView(APIView):
    def get(self, request):
        ds = DataStructure()
        knowledge_category = [i[1] for i in ds.CATEGORY_CHOICES]
        teams = [i[1] for i in ds.TEAM_CHOICES]
        context = {
            'add_knowledge_category': knowledge_category,
            'add_teams': teams,
        }
        return render(request, 'teams/data_structure/add_data_structure.html', context)

    @transaction.atomic
    def post(self, request):
        # print(request.data)
        serializer = DataStructureSerializer(data=request.data)
        if serializer.is_valid():
            # serializer.
            ds = serializer.save()
            # handle file
            files_obj = request.FILES.getlist('uploadFile')
            if files_obj:
                handle_files(request, files_obj, ds, TeamFileSerializer)
            return api_success('信息保存成功Data loading')
        return api_bad_request('表单数据输入有误,认证失败,数据无法保存!')
        

def handle_files(request, files_obj, obj, FileSerializer):
    """
    封装好的文件处理函数更新和添加都可调用
    """

    files = []
    for file_obj in files_obj:
        filename = file_obj.name
        suffix = filename.rsplit(".", 1)[1]
        file_data = {
            'file': file_obj,
            'filename': filename,
            'suffix': suffix,
        }
        if request.method == 'PUT':
            # 1.本地文件删除
            obj_files = obj.attachments.all()
            for file in obj_files:
                file.file.delete()
            # 2.文件数据记录删除先删除子表数据记录
            obj_files.delete()
        fs = FileSerializer(data=file_data)
        if fs.is_valid():
            new_file = fs.save()
            new_file.content_object = obj
            new_file.save()
        files.append(fs.data.get('id'))

    if request.method == 'POST':
        obj.attachments.add(*files)
    if request.method == 'PUT':
        obj.attachments.set(files)

ok至此文件的多次累加上传功能完成文件的编辑回显会在单独发文介绍若是该文对你有帮助还望可以点赞收藏加关注哦3Q!

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: go
返回列表

上一篇:Vue组件化

下一篇:HR相关表

“前端js实现文件多次添加累加上传和选择删除(django+js)” 的相关文章