Image upload not working through ajax Laravel - javascript

Having a weird issue and I'm sure it's got something to do with the way my script is grabbing the value of the file input field.
I know the controller function works because I've been able to do it by manually submitting the form without using ajax.
I also know the ajax works in sending and receiving the request because I tested it by modifying it to parse a string back and forth which worked.
Additionally I can see that the script is grabbing the file as when I select a file, it shows the selected file in the console.
In my browser I'm getting a 500 error and in Laravel I'm only getting this:
Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function getClientOriginalExtension() on string in C:\123\app\Http\Controllers\MyController.php:156
I've tried updating the controller to use Request->logo instead with no success.
View:
<form enctype="multipart/form-data" class="form-horizontal" method="POST" action="{{ url('studio/uploadLogo') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('studioname') ? ' has-error' : '' }}">
<label for="imageInput" class="col-md-4 control-label">Logo</label>
<div class="col-md-6">
<input data-preview="#preview" name="logo" type="file" id="imageInput">
<img id="preview" src="" style="display: none"></img>
<input class="form-control" type="submit">
</div>
</div>
</form>
Script:
$('#imageInput').change(function (e) {
e.preventDefault();
var logo = $('#imageInput').val();
console.log(logo);
$.ajax({
type: "POST",
url: '/studio/uploadLogo',
data: {logo: logo},
success: function( data ) {
console.log(data);
}
});
});
Controller:
public function uploadLogo() {
$file = Input::file('logo')->getRealPath();
$photoName = str_random(20) . '.' . Input::file('logo')->getClientOriginalExtension();
Input::get('logo')->move(public_path('avatars'), $photoName);
$response = array(
'status' => 'success',
'data' => $photoName
);
return \Response::json($response);
}
Routes:
Route::post('/studio/uploadLogo', 'MyController#uploadLogo');
Route::get('/studio/uploadLogo', 'MyController#uploadLogo');

You just change a view js script to submit like below
$('.form-horizontal').submit(function(event){
event.preventDefault();
$.ajax({
type : 'POST',
url : "/studio/uploadLogo",
data : new FormData(this),
contentType:false,
processData:false,
})
.done(function(data,status){
//Your codes here
});
});
and
echo string response from controller like below
----------------
$file=$request->file('logo');
$uploaded_file_path='';
if($file!=null) {
$destinationPath = 'uploads';
$uploaded=$file->move($destinationPath,$file->getClientOriginalName());
$uploaded_file_path= $uploaded->getPathName();
$response = array(
'status' => 'success',
'data' => $uploaded_file_path
);
}else{
$response = array(
'status' => 'failed',
'data' => $uploaded_file_path
);
}
echo json_encode($response);
----------------

Try this in your controller
public function uploadLogo() {
$file = Input::file('logo')->getRealPath();
$photoName = str_random(20) . '.' . Input::file('logo')->getClientOriginalExtension();
Input::file('logo')->move(public_path('avatars'), $photoName);
$response = array(
'status' => 'success',
'data' => $photoName
);
return \Response::json($response);
}
You have given
Input::get('logo')->move(public_path('avatars'), $photoName);
Please change it to
Input::file('logo')->move(public_path('avatars'), $photoName);
and you should submit the form from ajax as like #jalin comment (https://stackoverflow.com/a/47906201/4049692)
Hope this should be the issue.
Thanks!.

Try adding processData: false, contentType: false in your script code
$('#imageInput').change(function (e) {
e.preventDefault();
var logo = $('#imageInput').val();
var form_data = new FormData();
form_data.append("logo",$("#imageInput")[0].files[0]);
console.log(logo);
$.ajax({
type: "POST",
url: '/studio/uploadLogo',
data: {form_data},
cache : false,
processData: false,
contentType: false
success: function( data ) {
console.log(data);
}
});
});
And try getting values in controller like $request->logo
Refer my answer here enter link description here

add data into FormData instance using 'this' and pass it to the data object in the ajax, also add contentType: false, processData: false
let formData = new FormData(this);
$.ajax({
type: "POST",
url: "{{ route('auth.societies.store') }}",
contentType: false,
processData: false,
});
then it will upload the form images

Related

Formdata is showing file but laravel's Request is showing null

I have a form in datatable as follows.
<form method="post" enctype="multipart/form-data">
<label for="file_'+row["course_id"]+'">
<i class="far fa-2x fa-file-pdf f-gray"></i>
</label>
<input type="file" id="file_'+row["course_id"]+'">
</form>
This shows a pdf button inside datatable for file upload. Onclick it will show a file browser for file selection.
Using javascript's FormData() I am passing the file to Laravel controller.
$(document).on("change", "[id^=file_]", function(e) {
var file_data = this.files[0];
var form_data = new FormData();
form_data.append("pdf_file", file_data);
$.ajax({
url: "/pdfUpload",
cache: false,
processData: false,
data: form_data,
type: 'post',
success: function(data) {
$('div.flash-message').html(data).fadeOut(5000);
}
});
});
The request headers is as follows:
But the following code says there is no file and is returning null.
public function upload(\Google_Service_Drive $service, Request $request){
if ($request->hasFile('pdf_file')) {
dump('yes');
}else{
dump('no');
}
dd($request->pdf_file);
$data = file_get_contents(?)
}
Output:
Any help on what I'm missing here?
Also, I need to get $data = file_get_contents(?) working. What should I pass here

why is my variable empty in my controller?

I am trying to make an upload function to upload multiple files. But everytime if i check in my controller where I send the data to the variable is empty. What am I doing wrong please help.
This is the form where i get the myfiles variable
<form name="Document" method="post" action enctype="multipart/form-data">
<div class="col-md-6">
<input type="file" id="documento" name="myFiles[]" required="required" multiple>
</div>
</form>
This is my script that i wrote that makes it an array and get the files based on the id documentto.
$(document).on('click', '#btnSaveUploadedFiles', function(e){
e.preventDefault();
var fileArray = [];
var fileBag = new FormData();
var files = document.getElementById('documento').files;
var arrayOfAllUploadedFiles = Array.from(files);
fileArray.forEach(file => fileBag.append("myFiles[]", file));
console.log(files);
$.ajax({
url: "{{ admin.generateUrl("uploadFiles") }}",
traditional: true,
data: {
"files": fileBag,
"uniqId": "{{ admin.uniqId }}",
"reservation": {{ admin.subject.id }}
},
processData: false,
contentType: false,
type: 'POST',
success: function () {
Swal.fire({
title: "test",
icon: "success",
confirmButtonText: "Sluiten"
});
},
});
});
This is my controller of symfony where i get the data from the {{ admin.generateurl.uploadfiles }}
public function uploadFilesAction(Request $request)
{
$reservationID = $request->get('reservation');
$files = $request->files;
dd($files);
$directory = "images/uploads/";
foreach ($files as $uploadedFile) {
// name the resulting file
$name = $reservationID;
$file = $uploadedFile->move($directory, $name);
// do something with the actual file
$this->doSomething($file);
}
// return data to the frontend
return new JsonResponse();
}
if you need more information ask me

Jquery throws an 'Illegal invocation' error

I'm trying to create a forum and jquery throws an 'illegal invocation' error.
Here is my jquery code:
$('#formSumbit').on('submit', function(e) {
e.preventDefault();
$.ajax({
url: 'data-get.php',
type: 'POST',
data: new FormData(this),
contentType: false,
dataType: 'json',
success: function(value) {
var serialize = $.parseJSON(value);
if (serialize.success == 'false') {
$('.alert').fadeIn().delay(3000).fadeOut();
$('.alert-msgText').html(serialize.datamsg);
}
}
});
});
And here is my PHP code:
<?php
$user = $_POST['user'];
$msg = $_POST['message'];
if(empty($user)&&empty($message)) {
$data = array(
'success' => 'false',
'datamsg' => 'Please fill the textboxes'
);
echo json_encode($data);
} else {
mysqli_query($con,"INSERT INTO forums(name,message) VALUES ('$user','$msg')");
$data = array(
'success' => 'true',
'datamsg' => 'Done!'
);
echo json_encode($data);
}
exit();
?>
When the textboxes are empty and i click the submit button, nothing seems to work and jquery throws an illegal invocation error. I don't understand what the problem is. Can you please help?
And thanks in advance!
1) You have a typo mismatch between your form and your JavaScript:
<form id="formSubmit" and $('#formSumbit') - it should be $('#formSubmit') to match the spellings.
2) Unless you are trying to upload files via this AJAX request, then you can simplify things by replacing data: new FormData(this), contentType: false, with just data: $(this).serialize(). This will get rid of the illegal invocation error.
3) Writing dataType: 'json' means that jQuery will automatically try to parse the data coming from the server as JSON, and convert it. Therefore, in your "success" function, value will already be parsed and converted to an object. In turn therefore, using $.parseJSON is not necessary. You can just access value.success directly, for instance.
Here's a fixed version:
$('#formSubmit').on('submit', function(e) {
e.preventDefault();
$.ajax({
url: 'data-get.php',
type: 'POST',
data: $(this).serialize(),
dataType: 'json',
success: function(value) {
if (value.success == 'false') {
$('.alert').fadeIn().delay(3000).fadeOut();
$('.alert-msgText').html(value.datamsg);
}
}
});
});
Working demo: https://jsfiddle.net/khp5rs9m/2/ (In the demo I changed your URL for a fake one, just so it would get a response, but you can see where I have altered it and left your settings in the commented-out part).

Serialzing form and posting ajax to function

I am trying to pass the form field values to a php function located into a file. The problem is that I can't understand how to pass that serialized form data to the function from this ajax to a function in php.
$('#insert_news').submit(function(event) {
event.preventDefault();
var form = $('#insert_news').serialize();
$.ajax({
type: 'POST',
url: 'includes/ajax.php',
data: {
action: 'insert_news',
$('#insert_news').serialize(); // how do I add this data here?
},
success: function(datas) {
$('#message').html(datas).show() /*fadeIn(1000).fadeOut(1000)*/ ;
}
});
});
This ajax passed the values to the file ajax.php right beyond. And from ajax.php is called the function located in functions.php.
ajax.php
if (isset($_POST['action']) && $_POST['action'] == 'insert_news') {
$cp->insert_into_table('newss', array(
'NewsTitle' => $_POST['title'],
'NewsDescrption' => $_POST['description'],
'Date' => date('Y-m-d H:i:s'),
'status' => '1'
)
);
}
function.php
public function insert_into_table($table_name, array $data){
foreach($data as $col=>$value) {
$cols[] = $col;
$values[] = '\''.$value.'\'';
}
$cols = implode(', ', $cols);
$values = implode(', ', $values);
$this->db->query("INSERT INTO $table_name ($cols) VALUES ($values)");
echo "INSERT INTO $table_name ($cols) VALUES ($values)";
}
The issue is serialize() produces a URL encoded key value paired string, so you can't mix that with your data object.
You can use serializeArray() to get an array of objects, representing the form elements, then iterate over them and add them to a data object:
var data = { action: 'insert_news' };
$.each($('#insert_news').serializeArray(), function(){
data[this.name] = this.value;
});
$.ajax({
type: 'POST',
url: 'includes/ajax.php',
data: data,
success: function(datas) {
$('#message').html(datas).show() /*fadeIn(1000).fadeOut(1000)*/ ;
}
});
Side note: your PHP code is vulnerable to SQL Injection. Consider using a Prepared Statement instead of concatenating user input into the SQL.
You can pass serialized data via ajax to a function the way you are doing but your code needs slight modification.
$('#insert_news').submit(function(event) {
event.preventDefault();
var form = $('#insert_news').serialize();
$.ajax({
type: 'POST',
url: 'includes/ajax.php',
data: {
action: 'insert_news',
serializedData: form // use variable to assign data here
},
success: function(datas) {
$('#message').html(datas).show() /*fadeIn(1000).fadeOut(1000)*/ ;
}
});
});
I think you can use alternate like this
First : add hidden input for action on your form
<input type="hidden" name="action" value="insert_news"/>
Then your ajax post like this
$('#insert_news').submit(function(event) {
event.preventDefault();
$.ajax({
type: 'POST',
url: 'includes/ajax.php',
data: $(this).serialize(), // $(this) is from <form id="insert_news">
success: function(datas) {
$('#message').html(datas).show() /*fadeIn(1000).fadeOut(1000)*/ ;
}
});
});
And then use print_r on your ajax.php
print_r($_POST);
$('#insert_news').submit(function(event) {
var name = $("#t1").val();
var pass = $("#t2").val(); //add more var as u need
var key = 0;
var formName = new FormData();
formName.append(key++,name)
formName.append(key++,pass) //append the the var to formdata
$.ajax({
url : 'includes/ajax.php',
dataType : 'text',
cache : false,
contentType : false,
processData : false,
data : formName,
type : 'post',
success : function(data){
$('#message').html(data).show() /*fadeIn(1000).fadeOut(1000)*/ ;
}
});
});
this works fine for me :-)

upload image using formdata ajax send to php

I newbie in this webpage area and I was try to upload image to my file by using ajax and send it to php. But I have done some coding here. Can some one correct me where I'am wrong ?
here is my form with file upload and a button
<form method="post" enctype="multipart/form-data" action="">
<input type="file" name="images" id="images" multiple="" />
<input type="submit" value="submit" id="harlo">
</form>
Once I click on button the file will send it here and receive the src and ajax to php file
but I guess is about getting source problem. Need some one correct it for me.
(function upload() {
var input2 = document.getElementById("harlo"),
formdata = false;
if (window.FormData) {
formdata = new FormData();
}
input2.addEventListener("click", function () {
var i = 0, len = $('input[type="file"]')[0].files;
for ( ; i < len.length; i++ ) {
file = len.files[i];
if (formdata) {
formdata.append("images", file);
}
}
if (formdata) {
$.ajax({
url: "upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
document.getElementById("response").innerHTML = res;
}
});
}
}, false);
}());
<?php
foreach ($_FILES["images"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$name = $_FILES["images"]["name"][$key];
move_uploaded_file( $_FILES["images"]["tmp_name"][$key], "uploads/" . $_FILES['images']['name'][$key]);
}
}
echo "<h2>Successfully Uploaded Images</h2>";
?>
Use something like:
$("form").on("submit", function(
// Your ajax request goes here
$.ajax({
url: "upload.php",
type: "POST",
data: $("form").serialize(),
processData: false,
contentType: false,
success: function (res) {
$("#response").innerHTML = res;
}
});
return false;
));
But there seems to be a problem with sending files trough ajax anyway. Cause they're missed by the serialize() method because JS has no access to files content on users computer. So the form must be sent to the server to get the file data.
See here: https://stackoverflow.com/a/4545089/1652031

Categories

Resources