I'm configuring a multiple file upload with Jquery and Ajax, here the source code.
HTML:
<div id="dropzone-zone">
<button type="submit" class="btn btn-primary btn-xs" id="add_file" name="add_file" form="upload-form" style="display:none;">Subir archivos</button>
<form action="" id="upload-form" method="post" enctype="multipart/form-data">
<div id="dropzone" class="drop-zone" style="display:none;">
<span class="drop-zone__prompt">Haga click o arrastre los archivos que desea subir.</span>
<input type="file" name="file-upload[]" style="display:none;" id="file-upload" class="drop-zone__input" multiple>
</div>
</form>
</div>
JS:
const inputElement = document.getElementById("file-upload");
const dropZoneElement = document.getElementById("dropzone");
dropZoneElement.addEventListener("dragover", (e) => { e.preventDefault(); });
dropZoneElement.addEventListener("drop", (e) => {
e.preventDefault();
inputElement.files = e.dataTransfer.files;
dropZoneElement.querySelector(".drop-zone__prompt").remove();
for(var i=0; i<inputElement.files.length; i++) {
var file = inputElement.files[i];
var formdata = new FormData();
formdata.append("file-upload", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", function (event){
if(event.lengthComputable){
var percent = (event.loaded / event.total) * 100;
document.getElementById("load-progress").value = Math.round(percent);
}
}, false);
ajax.open("POST", "pruebas.php");
ajax.send(formdata);
}
//document.getElementById('add_file').click();
});
With this code, I want that with more than one file, first proccesses the first file, uploading to the location defined in pruebas.php, and meanwhile, completing the progress bar.
After the first file, starts with the second file, uploading it and completing its bar.
And the third and the fourth, etc; until all have been completed, then the form is being submitted and the redirect is done.
Now it's working, I mean it uploads the files to the server, but I can't proccess the upload progress bar because it doesn't wait for the end of the first upload, and I don't know how can evaluate the end of the upalods to determine when I have to submit the form.
Can someone explain me what do I have to change, or some post related?
Thanks in advance.
XMLHttpRequest.open() is asnychronous by default. This means, that the Request is sent and the code is not halted. You can set the property in .open(METHOD, URL, ASYNC) async to false, therefore the .send() method wont return until the response is recieved. This would cause the for-loop to wait for the Upload to finish.
I've edited your code below, I simply added another parameter to .open() which determines of the Method should be executed asynchronously.
const inputElement = document.getElementById("file-upload");
const dropZoneElement = document.getElementById("dropzone");
dropZoneElement.addEventListener("dragover", (e) => { e.preventDefault(); });
dropZoneElement.addEventListener("drop", (e) => {
e.preventDefault();
inputElement.files = e.dataTransfer.files;
dropZoneElement.querySelector(".drop-zone__prompt").remove();
for(var i=0; i<inputElement.files.length; i++) {
var file = inputElement.files[i];
var formdata = new FormData();
formdata.append("file-upload", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", function (event){
if(event.lengthComputable){
var percent = (event.loaded / event.total) * 100;
document.getElementById("load-progress").value = Math.round(percent);
}
}, false);
// Changed the parameter for 'async' to false
ajax.open("POST", "pruebas.php", false);
ajax.send(formdata);
}
//document.getElementById('add_file').click();
});
Related
I have an HTML form that is used to upload a file to the server. This works correctly but now I am trying to expand the capability such that I select a tar file that consists of two binary files. Then untar the files and based on certain conditions either upload the first or the second file.
This is what I have done so far
use FileReader to read the tar file as ByteArray
use untar from js-untar to untar both file
I need help to figure out how to take the ByteArray for either files and add then to the FormData so that I can upload them.
Any help would be appreciated.
Here are snippets from my code
HTML Form
<form id="upform" enctype="multipart/form-data"
action="cgi-bin/upload2.cgi">
Firmware file: <input id='userfile' name="userfile" type="file" width=50 >
<input type
="submit" name="submitBtn" value="send file">
</form>
Untar code
function sendData() {
var formData = new FormData(form);
var action = form.getAttribute('action');
filesize = file.files[0].size;
var reader = new FileReader();
reader.onload = function() {
untar(reader.result).then(
function (extractedFiles) { // onSuccess
console.log('success');
formData.delete('userfile');
var reader2 = new FileReader();
reader2.onload = function() {
formData.append('userfile', reader2.result);
upload(formData);
}
var blob = new Blob([extractedFiles[0]], {type : 'multipart/form-data'});
reader2.readAsDataURL(blob);
// var f = URL.createObjectURL(blob);
},
function (err) {
console.log('Untar Error');
}
)
};
reader.readAsArrayBuffer(file.files[0]);
return;
}
function upload(formData) {
var action = form.getAttribute('action');
reqUpload.open('POST', action, true);
reqUpload.onreadystatechange = uploadState;
document.body.style.cursor = "wait";
var ld = document.getElementById("load");
ld.classList.add("loader");
reqUpload.send(formData);
document.getElementById('progress').style.display = "block";
progTimer = setInterval(ping, 10000);
uploadStarted = true;
return;
}
I am trying to make a UI for esp8226 html js, ajax everything works fine but when I try to upload the firmware(uxx.bin) file it doesn't work.
Reference : https://github.com/jeelabs/esp-link/blob/master/html/flash.js
Note : I am connected to same network using wifi and the html page loads quite good.
I am trying to upload two files 1 --> uxx.bin
once it uploads redirect to next page and upload 2 --> uyy.bin
Here is the code
Html
<form id="file-form" action="uxx.bin" method="POST">
<input type="file" id="file-select" name="user[]" multiple/>
<button type="submit" id="upload-button">Upload</button>
</form>
var form = document.getElementById('file-form');
var fileSelect = document.getElementById('file-select');
var uploadButton = document.getElementById('upload-button');
form.onsubmit = function(event) {
event.preventDefault();
// Update button text.
uploadButton.innerHTML = 'Uploading...';
var files = fileSelect.files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i];
// Check the file type.
if (!file.type.match('image.*')) {
continue;
}
// Add the file to the request.
formData.append('user[]', file, file.name);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', 'uxx.bin', true);
xhr.onload = function () {
if (xhr.status === 200) {
// File(s) uploaded.
uploadButton.innerHTML = 'Upload';
} else {
alert('An error occurred!');
}
};
xhr.send(formData);
if anyone can guide with the correct approach :-)
I want to create an uploader with js. Can anyone help me how to upload a file using javascript?
You can use html5 file type like this:
<input type="file" id="myFile">
You file will be in value:
var myUploadedFile = document.getElementById("myFile").files[0];
For more information see https://www.w3schools.com/jsref/dom_obj_fileupload.asp
and see example here: https://www.script-tutorials.com/pure-html5-file-upload/
You can upload files with XMLHttpRequest and FormData. The example below shows how to upload a newly selected file(s).
<input type="file" name="my_files[]" multiple/>
<script>
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (e) => {
const fd = new FormData();
// add all selected files
e.target.files.forEach((file) => {
fd.append(e.target.name, file, file.name);
});
// create the request
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
// we done!
}
};
// path to server would be where you'd normally post the form to
xhr.open('POST', '/path/to/server', true);
xhr.send(fd);
});
</script>
HTML Part:
<form enctype = "multipart/form-data" onsubmit="return false;" >
<input id="file" type="file" name="static_file" />
<button id="upload-button" onclick="uploadFile(this.form)"> Upload </button>
</form>
JavaScript Part:
function uploadFile(form){
const formData = new FormData(form);
var oOutput = document.getElementById("static_file_response")
var oReq = new XMLHttpRequest();
oReq.open("POST", "upload_static_file", true);
oReq.onload = function(oEvent) {
if (oReq.status == 200) {
oOutput.innerHTML = "Uploaded!";
console.log(oReq.response)
} else {
oOutput.innerHTML = "Error occurred when trying to upload your file.<br \/>";
}
};
oOutput.innerHTML = "Sending file!";
console.log("Sending file!")
oReq.send(formData);
}
In the above HTML, I'm using the form to capture the files and calling the JS function when the button is clicked. In the JS function, I'm using the XMLHttpRequest to send the file.
A detailed step-by-step document can be found here.
I am trying to make a facebook like image uploader with the most basic methods. I select the multiple images on the input and then it creates the per file progress bars with names. It shows it's loading but it doesn't send to the upload.php file. I have the HTML code section:
<div class="container">
<h1>Uploader</h1>
<hr>
<form action="#" id="image_form">
<input type="file" id='image' name="image" multiple>
</form>
<div class="container">
<div class="filelist">
</div>
<ul id="uploads">
</ul>
</div>
Then I have my javascript. The progress bars get created with the file names and the progress is tracked. I have tried it with largish files and it does take a long while to upload. Progress bar shows this accurately.
$('#image').change(function (event) {
var files = this.files;
// iterate over each file to upload, send a request, and attach progress event
for (var i = 0, file; file = files[i]; i++) {
var li = $("<li>" + file.name + "<div class='progress progress-striped active'><div class='progress-bar' style='width:0%'>" + file.size + "</div></div></li>");
// add the LI to the list of uploading files
$("#uploads").append(li);
// fade in the LI instead of just showing it
li.hide().fadeIn();
var xhr = new XMLHttpRequest();
xhr.upload.li = li;
xhr.upload.addEventListener('progress', function(e) {
var percent = parseInt(e.loaded / e.total * 100);
this.li.find(".progress-bar").width(percent+'%');
}, false);
// setup and send the file
xhr.open('POST', 'upload.php', true);
xhr.setRequestHeader('X-FILE-NAME', file.name);
xhr.send(file);
}
});
I have been struggling with this piece of code for the last week and have been through almost every topic on this site without success. Please could someone help me figure out why I can't post the file details to the php script.
I'm using this code to post files to PHP:
function postFile(action, file, postFileName) {
var fPostName = typeof postFileName === 'undefined' ? 'file' : postFileName;
/* Create a FormData instance */
var formData = new FormData();
/* Add the file */
formData.append(fPostName, file);
var requestUrl = rootUrl + action;
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('POST', requestUrl);
/* handlers */
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
console.log(formData);
/* send request */
xhr.send(formData);
});
}
// Sample usage
* <<< FILE upload >>>>>>
* var file = document.getElementById('f').files[0];
* console.log(file);
* postFile('your_processing_script.php', file).then(function (response) {
* console.log(response);
* },function (er) {
* console.log(er);
* });
and then in PHP you should have:
$_FILES["file"] or $_FILES[postFileName]
Hope this helps you.
Cheers
What techniques are used to load a file (ASCII or Binary) into a variable (var file = "text";) in JavaScript?
You want to use the new HTML5 File API and XMLHttpRequest 2.
You can listen to files being either selected via a file input or drag & dropped to the browser. Let's talk about the input[type="file"] way.
<input type="file">
Let's listen for files being selected.
var input; // let input be our file input
input.onchange = function (e) {
var files = input.files || [];
var file = files[0];
if (file) {
uploadFile(file);
}
};
What you need to create a real multipart file upload request is a FormData object. This object is a representation of the body of your HTTP POST request.
var uploadFile = function (file) {
var data = new FormData();
data.append('filename', file);
// create a HTTP POST request
var xhr = new XMLHttpRequest();
xhr.open('POST', './script.php', true);
xhr.send(data);
xhr.onloadend = function () {
// code to be executed when the upload finishes
};
};
You can also monitor the upload progress.
xhr.upload.onprogress = function (e) {
var percentage = 100 * e.loaded / e.total;
};
Ask if you need any clarification.
If you want to use the new HTML5 way this is how I did it... keep in mind that I made a method called File() and this is not a true HTML5 method its a wrapper to it... this might be changed in the future so beware (maybe rename it).
HTML:
<html>
<body>
<input type="file" id="files" name="file"/>
<button onclick="load()">Load File</button><br /><br />
<div id="content"></div>
<script>
function load() {
var fileObj = document.getElementById("files");
var fp = new File(fileObj);
fp.read(callback);
}
function callback(text) {
var content = document.getElementById("content");
content.innerHTML = text;
}
</script>
</body>
</html>
JavaScript:
function File(name) {
this.name = document.getElementById(name) ? document.getElementById(name).files : name.files ? name.files : name;
}
// Reads the file from the browser
File.prototype.read = function(callback) {
var files = this.name;
if (!files.length) {
alert('Please select a file!?');
return;
}
var file = files[0];
var reader = new FileReader();
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
callback(evt.target.result);
}
};
var data = file.slice(0, file.size);
reader.readAsBinaryString(data);
}
Have the JavaScript being generated inside a PHP or Rails (or whatever you use server-side) and include the file.
<?php
$my_string = file_get_contents('/path/to/file.txt');
?>
<script>
var my_js_file_string = "<?php echo $my_string; ?>";
...
document.write(my_js_file_string);
</script>