php Uploading multiple files with ajax - javascript

I've managed to upload multiple files using my current php and html form and wanted to fancy it up a bit with some ajax and automatically submitting the form. I've hidden the 'file' input and submit button so the form is handeled by the js (mentioning this incase it may affect form submission, form does submission and I've checked via HTTP headers). The ajax section of my js is what I normally use for ajax and standard forms, however when i submit the form my $_FILES is empty so I guess I'm not using the ajax correctly here? What do I need to change in my ajax to handle file uploads?
$("#add_button").click(function(e)
{
e.preventDefault();
$("#folder_open_id").trigger("click");
$("#folder_open_id").change(function()
{
$("#folder_upload").submit();
});
});
$("#folder_upload").submit(function(event)
{
var formdata = $(this).serialize();
event.preventDefault();
$.ajax
({
url: "index.php",
type: "POST",
data: formdata,
success: function(response) { $("#response_div").html(response); },
error: function(response) { alert(response); }
});
});
php
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
if(!empty($_FILES['files']['name'][0]))
{
$files = $_FILES['files'];
define('CPATH', $_SERVER['DOCUMENT_ROOT'] . "/uploads/");
$uploaded = array();
foreach($files['name'] as $position => $file_name)
{
$file_temp = $files['tmp_name'][$position];
$file_new = "./uploads/" . $files['name'][$position];
if(move_uploaded_file($file_temp, $file_new))
echo "success";
else
echo "fail, temp: " . $file_temp . " new: " . $file_new;
}
}
else
echo '<pre>', print_r($_POST, 1), '</pre>';
}
so empty($_FILES['files']['name'][0]is returning true and the print_r($_POST) is empty it seems.
html form
<form id="folder_upload" action="" method="post" enctype="multipart/form-data">
<input type="file" class="hide" name="files[]" id="folder_open_id" multiple directory webkitdirectory mozdirectory/>
<input type="submit" class="hide" value="upload" id="folder_open_upload" />
</form>
Here is my js after Mephoros answer, my $_FILES array still seems to be empty:
$.ajax
({
url: "index.php",
type: "POST",
data: new FormData($(this)),
processData: false,
contentType: 'multipart/form-data; charset=UTF-8',
success: function(response) { $("#response_div").html(response); },
error: function(response) { alert(response); }
});

Based on some preliminary research, utilize FormData and set processing and contentType to false.
$.ajax({
// ...
data: new FormData($(this)),
processData: false,
contentType: false,
// ...
});
Sources:
http://portfolio.planetjon.ca/2014/01/26/submit-file-input-via-ajax-jquery-easy-way/
http://abandon.ie/notebook/simple-file-uploads-using-jquery-ajax
See: http://api.jquery.com/jquery.ajax/
See: https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects

Related

I get an empty error when submitting multiple forms with file uploads with ajax in laravel

my problem is while posting multiple forms with ajax in laravel, I am sending the form data without any problem, but I cannot send the file.
File is empty error. I've been dealing with this for 2 days, there is no method I haven't tried, please help me.
Apart from that, I added multipart to the form, but it still didn't work, I'm sharing my codes with you.
Sorry for my bad english.
I want it to upload 2 photos in the normal 4th form until the createProduct3 form, I tried to get them by doing the normal new formData() and I tried otherwise and I couldn't succeed.
It sends it to Laravel server side as [Object File].
My Form
<form class="form" id="createProduct4" method="POST" action="">
<input type="file" class="upload-box-title" id="urun-fotografi" name="urun_fotografi" value="Fotoğraf Seç">
<input type="file" class="upload-box-title" id="urun-dosyasi" name="urun_dosyasi" value="Dosya Seç">
</form>
My blade ajax:
function createProducts()
{
var dataString = $("#createProduct1, #createProduct2, #createProduct3, #createProduct4").serialize();
let photo = document.getElementById("urun-dosyasi").files[0];
let photo2 = document.getElementById("urun-fotografi").files[0];
console.log(photo,photo2);
$.ajax({
url: "{{ route('user.product.create') }}",
type: "POST",
data: dataString+"&urun_dosyasi="+photo+"&urun_fotografi="+photo2,
success: function( data ) {
},
error: function(xhr)
{
console.log(xhr);
}
});
}
Server Function
public function createProduct(Request $request)
{
$file = $request->file('urun_dosyasi');
$file2 = $request->file('urun_fotografi');
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$filename2 = $file2->getClientOriginalName();
$extension2 = $file2->getClientOriginalExtension();
echo $filename,$extension."2. doc: ".$filename2.$extension;
}
Use multipart/form-data when your form includes any <input type="file"> elements :
<form ... enctype="multipart/form-data">
Ajax :
var form = $('#createProduct4')[0];
var data = new FormData(form);
$.ajax({
url: "{{ route('user.product.create') }}",
type: "POST",
enctype: 'multipart/form-data',
data: data,
processData: false,
contentType: false,
success: function (data) {
console.log("SUCCESS : ", data);
},
error: function (e) {
console.log("ERROR : ", e);
}
});

Ajax upload not working codeigniter

I am using codeigniter 3.1 . I want to post upload data using ajax.
Ajax upload file not working. But when i post the simple form without ajax, it working fine.
I don't know why but no error in console.
HTML
<?php echo form_open_multipart(site_url("upload/post"), ['id' => 'uploader']) ?>
<input type="file" name="userfile" value="">
<input type="submit" value="Submit" />
<?php echo form_close() ?>
JAVASCRIPT
$('#uploader').submit(function (event) {
event.preventDefault();
$.ajax({
url: window.location.href + '/post',
type: "POST",
dataType: 'json',
data: new FormData(this)
});
});
CONTROLLERS
public function post()
{
$this->load->helper('url');
$this->load->helper('form');
$this->load->library("upload");
$file = $this->common->nohtml($this->input->post("userfile"));
$this->upload->initialize(array(
"upload_path" => 'upload',
"overwrite" => FALSE,
"max_filename" => 300,
"encrypt_name" => TRUE
));
$this->upload->do_upload('userfile');
$data = $this->upload->data();
$image_file = $data['file_name'];
}
Another approach to this would be passing to PHP the file encoded in base64:
get the selected file from #userfile field using $('#userfile').prop('files')[0];
transform the contents of that file into a base64 encoded string using FileReader.readAsDataURL(). We're going to call this content; Here's a similar question showing how to do and expanding the answer & possibilities;
send the AJAX passing both the filename and content strings;
now on CI, fetch the POST data;
base64_decode() the content;
fwrite() the result into a file using the filename.
That way also you could avoid POSTing all form fields.
try this..
Post data using FormData() formdata post file also.
To get all your form inputs, including the type="file" you need to use FormData object.
$('#post').on('click', function (e) {
var file_data = $("#userfile").prop("files")[0];
var form_data = new FormData();
form_data.append("userfile", file_data)
$.ajax({
url: window.location.href+'/post',
type: 'POST',
data: form_data,
async: false,
success: function (data) {
alert(data)
},
cache: false,
contentType: false,
processData: false
});
return false;
});
For more...https://abandon.ie/notebook/simple-file-uploads-using-jquery-ajax
One of the issues is that file uploading uses a different mechanism than the other form <input> types. That is why $this->input->post("userfile") isn't getting the job done for you. Other answers have suggested using javascript's FormData and this one does too.
HTML
A very simple form for picking a file and submitting it. Note the change from a simple button to <input type="submit".... Doing so makes it a lot easier for the javascript to use the FormData object.
FormData documentation
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="https://code.jquery.com/jquery-2.2.2.js"></script>
<title>Upload Test</title>
</head>
<body>
<?= form_open_multipart("upload/post", ['id' => 'uploader']); ?>
<input type="file" name="userfile">
<p>
<input type="submit" value="Upload">
</p>
<?php echo form_close() ?>
<div id="message"></div>
<script>
$('#uploader').submit(function (event) {
event.preventDefault();
$.ajax({
url: window.location.href + '/post',
type: "POST",
dataType: 'json',
data: new FormData(this),
processData: false,
contentType: false,
success: function (data) {
console.log(data);
if (data.result === true) {
$("#message").html("<p>File Upload Succeeded</p>");
} else {
$("#message").html("<p>File Upload Failed!</p>");
}
$("#message").append(data.message);
}
});
});
</script>
</body>
</html>
JAVASCRIPT
Use FormData to capture the fields.
Note that instead of handling the button click we handle the submit event.
$('#uploader').submit(function (event) {
event.preventDefault();
$.ajax({
url: window.location.href + '/post',
type: "POST",
dataType: 'json',
data: new FormData(this),
processData: false,
contentType: false,
success: function (data) {
//uncomment the next line to log the returned data in the javascript console
// console.log(data);
if (data.result === true) {
$("#message").html("<p>File Upload Succeeded</p>");
} else {
$("#message").html("<p>File Upload Failed!</p>");
}
$("#message").append(data.message);
}
});
});
CONTROLLER
I've added some code that "reports" results to ajax and will display it on the upload page.
class Upload extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->helper(['form', 'url']);
}
public function index()
{
$this->load->view('upload_v');
}
public function post()
{
$this->load->library("upload");
$this->upload->initialize(array(
"upload_path" => './uploads/',
'allowed_types' => 'gif|jpg|png|doc|txt',
"overwrite" => FALSE,
"max_filename" => 300,
"encrypt_name" => TRUE,
));
$successful = $this->upload->do_upload('userfile');
if($successful)
{
$data = $this->upload->data();
$image_file = $data['file_name'];
$msg = "<p>File: {$image_file}</p>";
$this->data_models->update($this->data->INFO, array("image" => $image_file));
} else {
$msg = $this->upload->display_errors();
}
echo json_encode(['result' => $successful, 'message' => $msg]);
}
}
This will upload your file. Your work probably isn't done because I suspect that your are not saving all the file info you need to the db. That, and I suspect you are going to be surprised by the name of the uploaded file.
I suggest you study up on how PHP handles file uploads and examine some of the similar codeigniter related questions on file uploads here on SO.
Controller
public function upload()
{
$this->load->library('upload');
if (isset($_FILES['myfile']) && !empty($_FILES['myfile']))
{
if ($_FILES['myfile']['error'] != 4)
{
// Image file configurations
$config['upload_path'] = './upload/';
$config['allowed_types'] = 'jpg|jpeg|png';
$this->upload->initialize($config);
$this->upload->do_upload('myfile');
}
}
}
View
<form id="myform" action="<?php base_url('controller/method'); ?>" method="post">
<input type="file" name="myfile">
("#myform").submit(function(evt){
evt.preventDefault();
var url = $(this).attr('action');
var formData = new FormData($(this)[0]);
$.ajax({
url: url,
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function (res) {
console.log(res);
},
error: function (error) {
console.log(error);
}
}); // End: $.ajax()
}); // End: submit()
Let me know if any query
you need to submit the form not on click but on submit ... give the form an id and then on submit put ajax
HTML
<?php $attributes = array('id' => 'post'); ?>
<?php echo form_open_multipart(site_url("upload/post",$attributes), ?>
<input type="file" id="userfile" name="userfile" value="">
<button id="post">Submit</button>
<?php echo form_close() ?>
JAVASCRIPT
$('#post').on('submit', function () {
var formData = new FormData();
formData.append("userfile",$("#userfile")[0].files[0]);
$.ajax({
url: window.location.href+'/post',
type: "POST",
data: formData
});
CONTROLLERS
public function post()
{
$this->load->library("upload");
$file = $this->common->nohtml($this->input->post("userfile"));
$this->upload->initialize(array(
"upload_path" => 'upload',
"overwrite" => FALSE,
"max_filename" => 300,
"encrypt_name" => TRUE,
));
$data = $this->upload->data();
$image_file = $data['file_name'];
$this->data_models->update($this->data->INFO, array(
"image" => $image_file
)
);
}

Trying to upload a file from HTML form to server via AJAX and PHP?

I've researched many posts about this and am still experiencing trouble, which is why I decided to post a question about it.
I have an html form with a file input:
<form id='AddFile' action='AddFile.php' method='post' enctype='multipart/form-data'>
<input type='file' id='fileAdd' name='fileAdd'>
Friendly Name: <input type='text' id='friendlyname-Add'>
</form>
I have some JavaScript that prepares the file for upload:
var form = $('AddFile')[0];
var formData = new FormData(form);
$.ajax({
url: "AddFile.php",
type: 'POST',
data: formData,
cache: false,
dataType: 'json',
contentType: false,
processData: false,
success: function(data){
alert("file uploaded!");
...
and PHP that handles the data:
<?php
$uploaddir = 'path';
$uploadfile = $uploaddir . basename($_FILES['fileAdd']['name']);
echo $uploadfile;
if (move_uploaded_file($_FILES['fileAdd']['tmp_name'], $uploadfile)) {
...
}else{
...
}
?>
Typo:
var form = $('AddFile')[0];
^---no #
without a # or ., jquery is looking for a <AddFile> tag, which obviously doesn't exist.
If you had even minimal error handling on the PHP code, you'd have seen that no upload was being performed. There's a ['error'] parameter in $_FILES for a reason:
if($_FILES['fileAdd']['error'] !== UPLOAD_ERR_OK) {
die("Upload failed with error code " . $_FILES['fileAdd']['error']);
}

AJAX redirect after php post return true or no error

I have very very little knowledge of javascript but somehow I managed to post form data to a php file.
Now I am facing a little problem, there are some validations on php file, what I want is if there is any validation fails and the php file returns $error = 'Invalid data'; I want this ajax request to simply display the error message.
Or, if it returns no error, or $error = ''; this ajax request redirect to thankyou.php page.
HTML file:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function (e){
$("#frmContact").on('submit',(function(e){
e.preventDefault();
$.ajax({
url: "data.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData:false,
success: function(data){
if (data == 'true') {
window.location.href="thankyou.php";
};
if (data !== 'true') {
$("#status").html(data);
};
},
error: function(){
}
});
}));
});
<form id="frmContact" action="" method="post">
<div id="status"></div>
<div>
<label>Email</label>
<span id="userEmail-info" class="info"></span><br/>
<input type="text" name="userEmail" id="userEmail" class="demoInputBox">
</div>
<div>
<input type="submit" value="Send" class="btnAction" />
</div>
</form>
data.php
<?php
// PHP code above...
//Lets add $error variable for test purpose...
$error = 'Invalid data';
?>
Change only success function like this
success: function(data){
if (data === 'Invalid data') {
$("#status").html(data);
}
else {
window.location.href="thankyou.php";
}
}
and in php you should echo $error
Echo out "Success" if everything goes according to what you wanted in the posted data i.e all validations passed or echo out any specific validation error. The echoed response will be the response according to which our JS will act accordingly.
$(document).ready(function (e){
$("#frmContact").on('submit',(function(e){
e.preventDefault();
$.ajax({
url: "data.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData:false
})
.done(function(response){
if(response=="Success")
window.location.href="thankyou.php";
else
$("#status").html(response);
});
}));
});

Passing file through ajax in laravel

I'm trying to upload an image through ajax in laravel.
I have this code for the ajax.
$("#stepbutton2").focus(function(){
var formData = new FormData($("#form1"));
$.ajax({
url: '/nominations/upload/image',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data.url);
},
error: function(err){
alert(err);
}
});
});
and php file:
public function image(){
$file = Input::file('largeImage');
$ext = $file->getClientOriginalExtension();
$newName = md5(time()).".$ext";
$path= "uploads/{$this->getDate()}";
$file->move($path, $newName);
$imageUrl = $path.'/'.$newName;
return Response::json(["success"=>"true", "url"=>$imageUrl]);
}
#stepbutton2 is a button type and not submit.
I'm getting the alert [Object object] but it should be the uploaded URL.
The markup is something like:
<form id='form1'>
<input type='file' id='largeImage' name='largeImage'>
<input type='button' id='stepbutton2'>
</form>
where did I go wrong? I need to use this url to populate another field in the same form and continue filling the form to the next steps.

Categories