I'm trying to implement a HTML5 ajax file upload with the help of HTML5's File API. It is based on Afzaal Ahmad Zeeshan's answer to this question.
My main aim would be to be able to let users upload .xls and .xlsx spreadsheet for later use.
HTML
<form class="form-uploadXLS" method="post" action="php/uploadXLS.php" enctype="multipart/form-data">
<div class="form-group">
<div class="col-md-12">
<input type="file" name="xls" class="xls" />
</div>
</div>
<input type="button" value="Upload" class="btn-uploadXLS" />
</form>
<progress></progress>
And here are the jQuery event handlers, just like in the above mentioned answer:
File input onChange event:
$('.xls').on('change', function () {
var file = this.files[0];
var fileName = file.name;
var fileType = file.type;
var fileSize = file.size;
console.log("file name: " + fileName + ", type: " + fileType + ", size: " + fileSize);
});
This works correctly, the file's name, type and size gets logged to the server.
Upload button's onClick event:
$('.btn-uploadXLS').on('click', function (event) {
event.preventDefault();
console.log("Upload button clicked");
var formData = new FormData($('.form-uploadXLS')[0]);
$.ajax({
url: 'php/uploadXLS.php', //Server script to process data
type: 'POST',
xhr: function () { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { // Check if upload property exists
myXhr.upload.addEventListener('progress', progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
//Ajax events
beforeSend: function (stuff) {
console.log("BeforeSend");
console.log(stuff);
},
success: function (data) {
console.log("Success!");
console.log(data);
},
error: function (error) {
console.log("Error!");
console.log(error);
},
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
});
On server side, I'm using this PHP code to check if the file has been sent to the server
if(!empty($_FILES['xls'])) {
echo '<pre>',print_r($_FILES,1),'</pre>';
}
else {
die('no $_FILES variable');
}
And here's the result of print_r:
Array
(
[xls] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)
)
According to the documentation, error code 4 means: UPLOAD_ERR_NO_FILE Value: 4; No file was uploaded.
What am I doing wrong?
Edit:
If I disable the click event listener and submit the form as normal, the file gets uploaded without problems.
I've noticed, that the formData variable doesn't have any value. This is the value of formData after it's been set: FormData { append=append()}
For some reason the problem was with the formData variable, previously defined as such:
var formData = new FormData($('.form-uploadXLS')[0]);
I've changed the index to 1 like this..
var formData = new FormData($('.form-uploadXLS')[1]);
.. and for some reason it works now.
Instead of:
if(!empty($_FILES['xls'])) {
try this:
if(!empty($_FILES['xls']['name'])) {
type = $_FILES['xls']['type'])
tmp = $_FILES['xls']['tmp_name'])
Related
I have set up my code to pass formdata via Ajax to my php file. My code works until I actually select an image and then I get a parsing error in my php file. I get an undefined index error. I have a form named "AddItemForm". My image input line looks like this:
<input type="file" id="_ni_image_in" onchange="readURL(this);" name="ni_image" accept="image/png, image/jpeg">
My javascript/ajax code looks like this which gets called when submit button is selected on form:
function AddItem(){
var form = document.forms["AddItemForm"];
var name = document.forms["AddItemForm"]["ni_name"].value;
var tag = document.forms["AddItemForm"]["ni_tag"].value;
var description = document.forms["AddItemForm"]["ni_description"].value;
var weight = document.forms["AddItemForm"]["ni_weight"].value;
var date = document.forms["AddItemForm"]["ni__date"].value;
var color = document.forms["AddItemForm"]["ni_color"].value;
var itag2 = document.forms["AddItemForm"]["ni_tag2"].value;
var itag3 = document.forms["addcowform"]["ni_tag3"].value;
var useremail= "<?php echo $_SESSION['UserEmail']; ?>";
var itemdata = new FormData();
var filedata = document.getElementById("_nc_image_in").files[0];
itemdata.append('Item_Image', filedata);
itemdata.append('Name', name);
itemdata.append('Tag_Num', tag);
itemdata.append('Description', description);
itemdata.append('Weight', weight);
itemdata.append('Date', date);
itemdata.append('Color', color);
itemdata.append('Tag_Num2', itag2);
itemdata.append('Tag_Num3', itag3);
itemdata.append('User_Email', useremail);
var isValid = false;
$.ajax({
type: "POST",
url: "/AddNewItem.php",
data: itemdata,
processData: false,
contentType: false,
success: function(resp){
console.log(resp);
if(resp.reply == "Success")
{
isValid = true;
form.submit();
}
else
{
isValid = false;
}
},
error: function(data, status){
console.log(data, status);
alert("error")
}
}); //end Ajax
console.log(isValid);
return isValid;
};
In my php file, I am retrieving image like this:
$itemmage = $_REQUEST["Item_Image"];
It is working if I don't select an image, so something is wrong with how I am getting my image or retrieving it. Please help.
Use $_FILES instead of $_REQUEST
Edit
if(isset($_FILES['image']) && $_FILES['image']['name']!=""){
$image_name= $_FILES['image']['name'];
move_uploaded_file( $_FILES['image']['tmp_name'], "images/$image_name");
}
$_FILES has an array for each image:
[name] => MyFile.jpg
[type] => image/jpeg
[tmp_name] => /tmp/php/php6hst32
[error] => UPLOAD_ERR_OK
[size] => 98174
See http://php.net/manual/en/reserved.variables.files.php
I am trying to make an upload form with AJAX/jQuery. The problem is i can't upload multiple files from a single input. With this code I can upload 1 file:
HTML:
<form name="myform" id="myform" enctype="multipart/form-data">
<input name="file[]" type="file" multiple />
<input type="button" value="Upload" />
</form>
jQuery:
$(document).ready(function(){
$(':button').click(function(){
var formData = new FormData();
formData.append('file', $('input[type=file]')[0].files[0]);
$.ajax({
url: 'upload.php',
type: 'POST',
dataType:"json",
async: true,
success: function(data) {
console.log(data.Result);
},
data: formData,
cache: false,
contentType: false,
processData: false
});
});
});
I changed the formData part to this:
var formData = new FormData($('input[name^="file"]'));
$.each($('input[name^="file"]')[0].files, function(i, file){
formData.append(i, file);
});
the PHP part:
foreach($_FILES as $index => $file)
{
// for easy access
$fileName = $file['name'];
// for easy access
$fileTempName = $file['tmp_name'];
// check if there is an error for particular entry in array
if(!empty($file['error'][$index]))
{
// some error occurred with the file in index $index
// yield an error here
return false;
}
// check whether file has temporary path and whether it indeed is an uploaded file
if(!empty($fileTempName) && is_uploaded_file($fileTempName))
{
// move the file from the temporary directory to somewhere of your choosing
move_uploaded_file($fileTempName, ROOT_DIR . '/uploads/xPhoto/' . $fileName);
// mark-up to be passed to jQuery's success function.
echo '<p>Click <strong>' . $fileName . '</strong> to download it.</p>';
}
}
So my question is, how can I upload multiple files with a single input?
This works for me. Let's you upload multiple files from single input. All accessible from the $_FILES global in php.
var formData = new FormData();
var files = $('#files_input').prop('files');
$.each(files, function(i, file) {
formData.append("file_" + i, file);
});
I have the exact method of gathering the files in one of my (old) projects.
HTML
<input id="files" type="file" name="files[]" multiple />
jQuery
var fd = new FormData();
$.each($('#files')[0].files, function(i, file) {
fd.append(i, file);
});
// Other form data can be set and passed using:
// fd.append('POST_key', $input_object.val());
$.ajax({
url: var_your_file_handler,
type: 'POST',
data: fd,
processData: false, // tell jQuery not to process the data
contentType: false, // tell jquery not to set content type
...
)};
I believe - it's an old project - that processData and contentType need to be false in order for the fd object to be sent in the request as it would have been during a normal form submission. As long as the AJAX request is POST, files can be gathered in PHP using $_FILES.
HTML:
<input type="text" name="description">
<input type="file" name="image" accept=".jpg">
How can I use $.ajax to upload the image and text value? I have no problem producing an object to submit text data, but have no idea where to start with the image.
I am using PHP server-side, so encoding the image in base64 or similar methods are perfectly acceptable.
it’s easiest to use the FormData() class:
So now you have a FormData object, ready to be sent along with the XMLHttpRequest. and append fields with FormData Object
<script type="text/javascript">
$(document).ready(function () {
var form = $('form'); //valid form selector
form.on('submit', function (c) {
c.preventDefault();
var data = new FormData();
$.each($(':input', form ), function(i, fileds){
data.append($(fileds).attr('name'), $(fileds).val());
});
$.each($('input[type=file]',form )[0].files, function (i, file) {
data.append(file.name, file);
});
$.ajax({
url: '/post_url_here',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (c) {
//code here if you want to show any success message
}
});
return false;
});
})
</script>
and forcing jQuery not to add a Content-Type header for you, otherwise, the upload file boundary string will be missing from it.
Use jQuery form js to upload images using ajax.
Check https://github.com/malsup/form/
var options = {
url : 'url',
success : function(responseText) { "event after success "}
};
$(" form id ").ajaxSubmit(options);
and get image in php file and upload images
I'm trying to upload files through Ajax call and jQuery. Each input[type="file"] is handled dynamically as you will see on the code below and are created on the change event for the Select2 element.
var tipoRecaudo = $('#tipoRecaudo'),
tipo_recaudo = tipoRecaudo.val(),
selectedIdsTipoRecaudo = [];
tipoRecaudo.select2({
ajax: {
dataType: 'json',
url: function () {
return Routing.generate('obtenerRecaudosTramite');
},
data: function (tipo_recaudo) {
return {
filtro: tipo_recaudo
}
},
results: function (data) {
var myResults = [];
$.each(data.entities, function (index, item) {
if (selectedIdsTipoRecaudo.indexOf(item.id.toString()) === -1) {
myResults.push({
'id': item.id,
'text': item.nombre
});
}
});
return {
results: myResults
};
}
},
formatAjaxError: function () {
return Translator.trans('mensajes.msgNoConexionServidor', {}, 'AppBundle');
}
}).change(function () {
var id = $(this).val(),
selectedData = tipoRecaudo.select2("data"),
htmlTpl = '<table class="table"><caption>'+ selectedData.text + '</caption><tbody><tr><td>';
htmlTpl += '<input type="hidden" name="tipoRecaudos[]" id="tipoRecaudo ' + id + '" value="' + selectedData.id + '" /><div class="row"><div class="col-xs-6"><div class="form-group"><input type="file" id="recaudosNombreArchivo' + id + '" name="recaudos[nombre_archivo][]" multiple="multiple" class="form-control" /></div></div></div></div>';
htmlTpl += '</td></tr></tbody></table>';
selectedIdsTipoRecaudo.push(id);
$('#recaudoContainer').append(htmlTpl);
});
$('#recaudoContainer').on('change', 'input[type=file]', function (event) {
$("input:file").filestyle({
buttonText: "Seleccionar archivo",
iconName: "fa fa-upload",
buttonName: "btn-primary"
});
});
$('#btnGuardarPasoSieteAgregarProducto').on("click", function (event) {
event.stopPropagation(); // Stop stuff happening
event.preventDefault(); // Totally stop stuff happening
// Create a formdata object and add the files
var formData = $('#formRecaudosTramites').serialize();
$.each($('#formRecaudosTramites')[0].files, function (key, value) {
formData = formData + '&recaudos[]=' + value;
});
$.ajax({
url: Routing.generate('rpniSubirRecaudos'),
type: 'POST',
data: formData,
cache: false,
dataType: 'json',
contentType: 'multipart/form-data',
processData: false, // Don't process the files
//contentType: false // Set content type to false as jQuery will tell the server its a query string request
}).done(function (data, textStatus, jqXHR) {
if (typeof data.error === 'undefined') {
console.log('SUCCESS: ' + data.success);
} else {
// do something with error
}
}).fail(function (jqXHR, textStatus, errorThrown) {
// do something with fail callback
// STOP LOADING SPINNER
});
});
What is happening is: no filenames exists on query string, no files are upload or send through the Ajax call, instead it's sending a [object Object], what I'm doing wrong? Can any give me some working code for this stuff?
EDIT:
After reads the post referenced by user I change my code as the one before and now the error turns on:
TypeError: a is undefined
...rCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e...
What is wrong there?
Note: Yes, I know there are tons of plugins for handle this like jQuery File Upload from Blueimp, Dropzone and some others but I leave them out since I start using jQuery File Uploader from inside OneupUploaderBundle on my Symfony2 project and spent 4 days without success so I move to the other side: made things by myself so I can learn something else and improve my knowledge
i think this will help you,
var fd = new FormData();
//name is the key on the page of php to access the file
fd.append('name', $('#aob_file')[0].files[0]);
pass this fd object to your data field in ajax,
I have followed a very helpful tutorial online to upload a file through AJAX in a HTML form.
Below is my HTML code then jQuery code.
HTML
<input type="file" id="myFile" name="myFile" />
<input type="button" id="upload" value="upload" />
<br />
<progress id="prog" value="0" min="0" max="100"></progress>
jQuery
$("#upload").on("click",function() {
$("#myFile").upload("xhr2.php", function(success) {
},$("#prog"));
});
How can I access the uploaded file in PHP to process the data and output any errors to the page?
EDIT
// data is optional
$.fn.upload = function(remote,data,successFn,progressFn) {
// if we dont have post data, move it along
if(typeof data != "object") {
progressFn = successFn;
successFn = data;
}
return this.each(function() {
if($(this)[0].files[0]) {
var formData = new FormData();
formData.append($(this).attr("name"), $(this)[0].files[0]);
// if we have post data too
if(typeof data == "object") {
for(var i in data) {
formData.append(i,data[i]);
}
}
// do the ajax request
$.ajax({
url: remote,
type: 'POST',
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload && progressFn){
myXhr.upload.addEventListener('progress',function(prog) {
var value = ~~((prog.loaded / prog.total) * 100);
// if we passed a progress function
if(progressFn && typeof progressFn == "function") {
progressFn(prog,value);
// if we passed a progress element
} else if (progressFn) {
$(progressFn).val(value);
}
}, false);
}
return myXhr;
},
data: formData,
dataType: "json",
cache: false,
contentType: false,
processData: false,
complete : function(res) {
var json;
try {
json = JSON.parse(res.responseText);
} catch(e) {
json = res.responseText;
}
if(successFn) successFn(json);
}
});
}
});
};
This is going to be a tough job to do, since your form upload and the file upload are happening in different requests. This being said the only way you can reference your file is to have it be uploaded before the form data. There are different ways you can reference your file, through a session, pass it as an additional queryString parameter to your form, use databases ( which would be dull ), it's really up to you. The main problem is that they are in separate requests and you need to establish a connection between them. Good luck!