0

現在、Chrome と Firefox でのみ機能するファイル アップロード コードに取り組んでいます。ユーザーは、アップロードされたファイルをドラッグ アンド ドロップできます。アップロードの進行状況がグリッドに表示されます。

ここにhtmlがあります

<form id="fileUploadForm" action="home/upload" method="post" enctype="multipart/form-data">
    <input type="file" id="fileselect" name="files" multiple="multiple" />
    <div id="filedrag">Drop files here</div>
    <button type="submit" id="submitbutton">Upload Files</button>
</form>

<table class="datatable" data-bind="visible:files().length>0">
    <thead>
        <tr>
            <th>Name</th>
            <th>Status</th>
            <th>Upload progress</th>
            <th>Progress bar</th>
        </tr>
    </thead>
    <tbody data-bind="foreach:files">
        <tr>
            <td data-bind="text:name"></td>
            <td data-bind="text:status"></td>
            <td data-bind="text:percentUploaded"></td>
            <td>
              <progress max="100" data-bind="attr: {value:percentUploaded}"></progress>
              <span data-bind="text:$root.files().length"></span></td>
        </tr>

    </tbody>
</table>

<pre data-bind="text: ko.toJSON($data.files, null, 2)"></pre>

JavaScript は次のとおりです。

var File = function (f) {
    this.name = f.name;
    this.type = f.type;
    this.size = f.size;
    this.lastModified = f.lastModifiedDate.toDateString();
    this.status = ko.observable(f.status);
    this.percentUploaded = ko.observable(0);
};

var ViewModel = function () {
    var self = this,
      maxFileSize = 5000000,
      onFileSelecting = function (e) {
          e.stopPropagation();
          e.preventDefault();
          e.target.className = (e.type == "dragover" ? "hover" : "");
      },
    onFileSelected = function (e) {
        onFileSelecting(e);// cancel event and hover styling
        var files = e.target.files || e.dataTransfer.files;
        for (var i = 0, f; f = files[i]; i++) {
            var validationResult = validate(f);
            f.status = validationResult || 'Uploading';
            self.addFile(f);
            uploadFile(f);
        }
    },
    validate = function (f) {
        if (f.size > maxFileSize)
            return 'Too large, should be less than 5MB';
        if (f.type.indexOf("text") != 0)
            return 'Wrong file type';
    },
    uploadFile = function (f) {
        var file = self.files()[0];

        var fd = new FormData();
        fd.append("files", f, f.name);

        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", function (e) {
            file.status("Uploaded " + parseInt(e.loaded / e.total * 100) + "%");
            file.percentUploaded(parseInt(e.loaded / e.total * 100));
        }, false);

        xhr.onreadystatechange = function (e) {
            if (xhr.readyState == 4) {
                file.status((xhr.status == 200 ? "success" : "failure"));
            }
        };

        xhr.open("POST", $("#fileUploadForm")[0].action, true);
        xhr.setRequestHeader("X_FILENAME", file.name);
        xhr.send(fd);
    };

    self.files = ko.observableArray();
    self.addFile = function (f) { self.files.unshift(new File(f)); };

    $(document).ready(function () {
        if (window.File && window.FileList && window.FileReader) {
            var fileSelector = $("#fileselect"),
              fileDragArea = $("#filedrag"),
              submitButton = $("#submitbutton");

            fileSelector.change(onFileSelected);
            var xhr = new XMLHttpRequest();
            if (xhr.upload) {
                filedrag.addEventListener("dragover", onFileSelecting, false);
                filedrag.addEventListener("dragleave", onFileSelecting, false);
                filedrag.addEventListener("drop", onFileSelected, false);
                filedrag.style.display = "block";
                submitbutton.style.display = "none";
                fileSelector.hide();
            }
        }
    });
};

var model = new ViewModel();
ko.applyBindings(model);

一連のファイルをドラッグ アンド ドロップすると、すべて正常に動作します。ただし、別のセットをドラッグ アンド ドロップすると、ファイル配列は更新されますが、グリッドには追加の行が表示されません。

ただし、この HTML5 マークアップを取り出すと、すべて正常に動作します。

<progress max="100" data-bind="attr: {value:percentUploaded}"></progress>

私はフィドルを作成しました(http://jsfiddle.net/9aJtG/1)が、他の問題があります-1)フィドルのドラッグアンドドロップはファイルを開くだけです(理由はわかりません)2)ファイルをドロップするとファイル送信されますが、JSFiddle フォームの投稿で動作するサーバー側のコードはありません

この問題がない別の例でプログレスバーを試しましたhttp://jsfiddle.net/bxfXd/800/

何か案は?

どうもありがとう!

4

0 に答える 0