現在、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/
何か案は?
どうもありがとう!