layui multi file upload with progress bar

The original link address is https://my.oschina.net/u/3656204/blog/3086255.
The upload.js file, html and JS methods provided by the original author can be used for reference. The problem is that they were made according to the author's plan, but they failed. But pit, 98% completed, the remaining 2% is very difficult to work out.

The steps are as follows: Pit one

toUpload?id=5221282942990596404:227 Uncaught ReferenceError: xhrOnProgress is not defined

The author gave a more complete js method, but missed a key custom variable method.
xhrOnProgress should be defined as follows:

var xhrOnProgress = function (fun) {
            xhrOnProgress.onprogress = fun; //Binding monitoring
            //Using closures to implement listening binding
            return function () {
                //Get the XMLHttpRequest object through $. ajaxSettings.xhr()
                var xhr = $.ajaxSettings.xhr();
                //Judge whether the listening function is a function
                if (typeof xhrOnProgress.onprogress !== 'function')
                    return xhr;
                //If there is a listener function and xhr object supports binding, bind the listener function
                if (xhrOnProgress.onprogress && xhr.upload) {
                    xhr.upload.onprogress = xhrOnProgress.onprogress;
                }
                return xhr;
            }
        }

Pit two

The picture has been uploaded successfully, and the background method has been requested, but the progress bar remains unchanged.
The problem is with the layui reference module. Because the user-defined upload.js is referenced, there is no need to load the 'upload' module in layui.use.
upload on the way should be removed

The code is as follows

var upload
    layui.use(['element', 'form','layer'], function () {
        var id = "${id}"
        upload = layui.upload
        var element = layui.element;
        var xhrOnProgress = function (fun) {
            xhrOnProgress.onprogress = fun; //Binding monitoring
            //Using closures to implement listening binding
            return function () {
                //Get the XMLHttpRequest object through $. ajaxSettings.xhr()
                var xhr = $.ajaxSettings.xhr();
                //Judge whether the listening function is a function
                if (typeof xhrOnProgress.onprogress !== 'function')
                    return xhr;
                //If there is a listener function and xhr object supports binding, bind the listener function
                if (xhrOnProgress.onprogress && xhr.upload) {
                    xhr.upload.onprogress = xhrOnProgress.onprogress;
                }
                return xhr;
            }
        }

        var files;
        //Multi file list example
        var demoListView = $('#demoList')
            , uploadListIns = upload.render({
            elem: '#fileList'
            , size: 102400 //Limit file size in kilobytes
            , exts: 'zip|rar|7z|doc|docx|pdf|txt|xls|ppt|xlsx|pptx|img|jpg|png|gif|bmp|jpeg' //Only compressed files can be uploaded
            , url: '${ctx}/contract/contract/uploadAppendix'
            , accept: 'file'
            , multiple: false
            , auto: false
            , bindAction: '#fileListAction'
            ,
            xhr: xhrOnProgress,
            progress: function (value) {//Upload progress callback value progress value
                element.progress('demoList', value + '%')//Set page progress bar
            },
            xhr: function (index, e) {
                var percent = e.loaded / e.total;//Calculate percentage
                percent = parseFloat(percent.toFixed(2));
                element.progress('progress_' + index + '', percent * 100 + '%');
                console.log("-----" + percent);
            }
            // , data: JSON.stringify(Param)
            , choose: function (obj) {
                var files = this.files = obj.pushFile(); //Append each selected file to the file queue
                //Read local file
                obj.preview(function (index, file, result) {
                    var tr = $(['<tr id="upload-' + index + '">'
                        , '<td>' + file.name + '</td>'
                        , '<td>' + (file.size / 1014).toFixed(1) + 'kb</td>'
                        , '<td><div class="layui-progress layui-progress-big" lay-filter="progress_' + index + '" lay-showPercent="true"><div class="layui-progress-bar" lay-percent="58%"></div></div></td>'
                        , '<td>Waiting for uploading</td>'
                        , '<td>'
                        , '<button class="layui-btn layui-btn-xs demo-reload layui-hide">Retransmission</button>'
                        , '<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">delete</button>'
                        , '</td>'
                        , '</tr>'].join(''));

                    //Single retransmission
                    tr.find('.demo-reload').on('click', function () {
                        obj.upload(index, file);
                    });

                    //delete
                    tr.find('.demo-delete').on('click', function () {
                        delete files[index]; //Delete the corresponding file
                        tr.remove();
                        uploadListIns.config.elem.next()[0].value = ''; //Clear the input file value to avoid that the file with the same name is not optional after deletion
                    });

                    demoListView.append(tr);
                });
            }

            ,
            before: function (obj) {
                this.data = {
                    "id": id,
                    // "FLOW_ID": FLOW_ID,
                    // "FLOW_NODE_ID": FLOW_NODE_ID,
                    // "FILE_TYPE": FILE_TYPE
                }///Carry extra data
            }
            ,
            done: function (res, index, upload) {
                if (res.code == 0) { //Upload success
                    var tr = demoListView.find('tr#upload-' + index)
                        , tds = tr.children();
                    tds.eq(3).html('<span style="color: #5fb878; "> upload succeeded < / span > ';
                    tds.eq(4).html(''); //Emptying operation
                    //var url = webroot + "/guarantee/itemFile/getItemFileByFlow?FLOW_ID=" + FLOW_ID + "&BUSINESS_ID=" + BUSINESS_ID + "&FLOW_NODE_ID=" + FLOW_NODE_ID + "&FILE_TYPE=" + FILE_TYPE
                    //Refresh table
                    // table.reload('itemFileList', {
                    //     url: url
                    //     , where: {} / / set additional parameters for asynchronous data interface
                    //     //,height: 300
                    // });
                    return delete this.files[index]; //Delete file queue files that have been uploaded successfully
                } else if (res.code == 1) {
                    layer.msg(res.msg);
                }
                this.error(index, upload);
            }

            ,
            error: function (index, upload) {
                var tr = demoListView.find('tr#upload-' + index)
                    , tds = tr.children();
                tds.eq(2).html('<span style="color: #Ff5722; "> upload failed < / span > ';
                tds.eq(3).find('.demo-reload').removeClass('layui-hide'); //Display retransmission
            }
        })

    })

After removal, the implementation effect is as follows. Finally, there is progress bar.

html code also paste it out, you can copy the original page.
Original website: https://my.oschina.net/u/3656204/blog/3086255.
Please go to the baidu disk provided by the original website to download the upload.js file.

 <div class="layui-upload">
                <button type="button" class="layui-btn layui-btn-normal" id="fileList">Select multiple files</button>
                <div class="layui-progress">
                    <div class="layui-progress-bar" lay-filter="aaaa" lay-percent="10%"></div>
                </div>
                <div class="layui-upload-list">
                    <table class="layui-table">
                        <thead>
                        <tr>
                            <th>file name</th>
                            <th>Size</th>
                            <th>Upload progress</th>
                            <th>state</th>
                            <th>operation</th>
                        </tr>
                        </thead>
                        <tbody id="demoList"></tbody>
                    </table>
                </div>
                <button type="button" class="layui-btn" id="fileListAction">Start uploading</button>
            </div>

Note the reference order of layui.js and upload.js
It must be layui.js in front and upload.js in back, otherwise. The render method is always unexpected.

Summary: if you provide a solution to the problem, please be as detailed as possible. The absence of a punctuation mark for a variable in the code may lead to the unavailability of the whole program. I wanted to give help, but I didn't use it for a long time.
You can plant trees for future generations, but you can't hang knives on them... (laughter)

Keywords: Mobile JSON

Added by brainstorm on Tue, 14 Jan 2020 13:20:01 +0200