Uploading a file through AJAX with a Django Form - javascript

I've been trying to create a system that allows uploads of text and a file through my Django form. Whenever I try post the form I can only seem to get the message part of the form. I've been following this answer for reference but I've been running into trouble. First, my form looks like this:
class MessageForm(forms.Form):
message = forms.CharField(widget=forms.Textarea, required=False)
file = forms.FileField(label="Attachment", required=False)
and it's rendered to HTML like this:
<form id="message-form" enctype="multipart/form-data">
{{form.message}}<br>
{{form.file}}
<div class="sectio4-bottom">
<div class="right-bottom">
<input id="send-button" type="submit" value="Send"/>
</div>
</div>
</form>
The current version of my JS function I'm working with looks entirely like this:
$('html').on('submit', '#message-form', function(e){
e.preventDefault();
var data = new FormData($('#message-form').get(0));
$.ajax({
url: '#',
type: 'POST',
data: {
'data': data,
'csrfmiddlewaretoken': $('.csrftoken').text()
}
});
return false;
})
but the part I'm interested in is var data = new FormData($('#message-form').get(0));. I got this from the linked question but when it runs it gives me an empty object. I've also tried passing the data as 'data': $('#message-form').serialize() but when it gets to the backend and I look at request.POST I see that the only thing included in data is the message I send. request.FILES is empty.
How can I access the specified file?

Try adding:
data.append('file',$("#file").files[0]); #Assume 'file' is id of your file field
after
var data = new FormData($('#message-form').get(0));
Here an example function that I'm using
function saveVeichle() {
$(".sk-wave").show();
var dati = new FormData();
dati.append('csrfmiddlewaretoken','{{csrf_token}}');
dati.append('note',$("#note").val());
dati.append('dip',$("#dip-0").val());
dati.append('stato',$("#stato").val());
$("input").each(function(id,obj){
if (obj.type == 'checkbox') {
dati.append(obj.name,obj.checked);
} else {
dati.append(obj.id,obj.value);
}
});
dati.append('foto',$(".foto")[0].files[0]);
dati.append('libretto',$(".libretto")[0].files[0]);
$.ajax({
url: "/mezzi/api/salva_mezzo/",
type: "POST",
data: dati,
cache: false,
contentType: false,
processData: false,
}).done(function(data) {
if (data.res == 'ok') {
window.location = '/mezzi/' + data.id + '/';
} else {
if (data.errors) {
for (d in data.errors) {
noty_alert(d + ":" + data.errors[d]);
}
} else {
noty_alert('Errore Salvataggio Mezzo!');
}
$(".sk-wave").hide();
}
});
}

Related

Empty array when dd($request->all()) upload file via ajax laravel

first of all i try to do the file uploading via ajax , when i try dd($request->all())in my controller , it give result empty array
public function uploadFile(Request $request){
dd($request->all());
}
My blade view with ajax
<label for="inputfile">
<a title="Click here to upload record "><i class="fa fa-upload"></i></a>
</label>
<input id="inputfile" name="inputfile" type="file" />
<script>
$('#inputfile').on('change',function(ev){
ev.preventDefault();
var postData=new FormData();
postData.append('file',this.files[0]);
$.ajax({
url:'{{url('reporting/uploadFile')}}',
headers:{'X-CSRF-Token':$('meta[name=csrf_token]').attr('content')},
type:"get",
contentType:false,
data:postData,
processData:false,
dataType:'json',
success: function( data ) {
console.log(data)
},
error: function() {
alert('error');
} }); });
</script>
My laravel version is 5.8 . The flow is when the user upload attachment, it will directly store to file storage without clicking button submit . But when i try to retrieve $request->all() its return empty array which is i can't continue further step. Sorry if my explaination not clear .
Yes ok laravel can be a real pain sometimes especially when it comes to file uploads.
You can try this article for laravel 5.8 give it a try and let me know if it works.
https://www.w3adda.com/blog/laravel-5-8-jquery-ajax-form-submit
I think the main difference with this article is the way it sets the data in the ajax call. However you might need to check the whole article over and compare it to your code.
$.ajax({
url: "{{ url('jquery-ajax-form-submit')}}",
method: 'post',
data: $('#contact_us').serialize(),
Please ensure you are using the form multipart setting correctly.
This is usually the issue in most cases.
<form action="upload.php" method="post" enctype="multipart/form-data">
let files = $('#inputfile');
let image = files[0].files;
let form_data = new FormData();
if (image.length > 0) {
for (let i = 0; i < image.length; i++)
form_data.append('inputfile[]', image[i]);
}
$.ajax({
url:'{{url('reporting/uploadFile')}}',
headers:{'X-CSRF-Token':$('meta[name=csrf_token]').attr('content')},
type:"get",
contentType:false,
data:form_data,
processData:false,
dataType:'json',
success: function( data ) {
console.log(data)
},
error: function() {
alert('error');
}
});
});
try this.
You just need to set "Content-Type" in header.
You also have pass type get, for file upload must require post.
have you console.log(this.files[0]);
<script>
$('#inputfile').on('change',function(ev){
ev.preventDefault();
console.log(this.files[0]);
var postData=new FormData();
postData.append('file',this.files[0]);
$.ajax({
url:'{{url('reporting/uploadFile')}}',
headers:{
'X-CSRF-Token':$('meta[name=csrf_token]').attr('content'),
'Content-Type': undefined
},
type:"POST",
data:postData,
success: function( data ) {
console.log(data)
},
error: function() {
alert('error');
} }); });
</script>

POST Form Submission in JQuery/AJAX and PHP

I'm a bit new to working with form submissions in JQuery/AJAX and PHP, so I've been trying to follow some tutorials online and have run into a few issues.
I am trying to build a form that handles submissions through PHP. Here's what I have for my index.html file.
<body>
<h1>Food Preference</h1>
<p>Please let us know what types of foods you would like to see on the menu.</p>
<form id="food-form">
<label for="appetizer">Appetizer</label>
<input type="text" id="appetizer" required>
<label for="entree">Entree</label>
<input name="entree" type="entree" id="entree" required>
<label for="dessert">Dessert</label>
<textarea name="dessert" id="dessert" required></textarea>
<button id="submit_button" type="submit">Send</button>
<p id="form_content">
</p>
</form>
And here is my index.js file
jQuery.ajax({
url: "handler.php",
data: "appetizer=" + $("#appetizer").val() +
"&entree=" + $("#entree").val() +
"&dessert=" + $("#dessert").val(),
type: "POST",
success: function(data) {
$("#form_content").html(data);
},
error: function() {}
});
And here is handler.php
<?php
class runForm {
public function handle_food_form($request) {
if(opinion($_POST["appetizer"], $_POST["entree"], $_POST["dessert"])) {
print "<p class='success'>Thank you for your opinion.</p>";
return array('post_id' => $new_post_id );
}
}
}
runForm();
?>
It doesn't seem like my submission saves anywhere, or if it does, I'm not sure how to find it. Can anyone give any pointers for anything I might be doing wrong?
I am wondering if this line in handler.php is correct, since I haven't really defined "opinion".
if(opinion($_POST["appetizer"], $_POST["entree"], $_POST["dessert"]))
You have many issues in this code snippet, and you should first check the errors that PHP shows to you and try to resolve them first.
The PHP file (handler.php)
opinion() function is not defined.
runForm() is not a function , it's a name of a class, if you want to call handle_food_form() function, then you can make it a static function and call it like this runForm::handle_food_form();
The final version of your PHP file should be something like this
<?php
class RunForm {
public static function opinion($appetizer, $entree, $dessert)
{
// do your logic here and return true or false
return true;
}
public static function handle_food_form() {
if (!isset($_POST["appetizer"])) $_POST["appetizer"] = null;
if (!isset($_POST["appeentreetizer"])) $_POST["entree"] = null;
if (!isset($_POST["dessert"])) $_POST["dessert"] = null;
if(SELF::opinion($_POST["appetizer"], $_POST["entree"], $_POST["dessert"])) {
$htmlMsg = "<p class='success'>Thank you for your opinion.</p>";
/*
$con is a MySQLI object
$con->query("insert into table ........");
$new_post_id = $con->insert_id;
*/
return array('post_id' => $new_post_id, 'htmlMsg' => $htmlMsg );
} else {
return array('post_id' => null , 'htmlMsg' => "");
}
}
}
echo RunForm::handle_food_form()['htmlMsg'];
The client side
You should use encodeURIComponent() to encode the paramters of the URL to prevent something like this dessert=cheesecake&pancake from corrupting the URL, or pass an object of the parameters as the data to ajax function and jquery will do the encoding for you internally
jQuery.ajax({
url: "handler.php",
data: {
appetizer: $("#appetizer").val(),
entree: $("#entree").val(),
dessert: $("#dessert").val()
},
type: "POST",
success: function(data) {
$("#form_content").html(data);
},
error: function() {}
});
Separate the variables with commas.
In jQuery.ajax, do as like:
jQuery.ajax({
url: "handler.php",
data: "appetizer=" + $("#appetizer").val(),
"entree=" + $("#entree").val(),
"dessert=" + $("#dessert").val(),
type: "POST",
success: function(data) {
$("#form_content").html(data);
},
error: function() {}
});

Is there a way to upload file before custom button click,and then using ajax send it to controller action method?

I am quite new to Telerik Html Kendo. My aim is to upload a file first. Then, invoke the corresponding action method in 'Administration' controller through ajax that should take the uploaded file and other parameters on clicking the 'Submit' button as shown in image below.
Most of Telerik examples show asynchronous upload feature which invokes controller method to upload file. I don't want to do this way.
However, I have tried to upload file with onSelect event of kendo upload. It shows that file gets included however it doesn't upload.
As a result, I am unable to see any info. about uploaded file in onSuccess and onComplete event.
I used formData on 'Submit' button click. However I receive null at the action method all time.
Any correct way of doing this?
Here is my html code for file upload:
<div class="well well-sm" style="width:inherit;text-align: center;float:left;">
<!--form method="post"-->
<!--div class="demo-section k-content">
<input name="files" id="files" type="file" value="Upload a Data File"/>
</div-->
<!--/form-->
#(Html.Kendo().Upload()
.Name("files")
.Multiple(false)
.Messages(m => m.Select("Please upload a Data File"))
.HtmlAttributes(new { aria_label = "file" })
.Events(events => events
.Complete("onComplete")
.Select("onSelect")
.Success("onSuccess")
.Upload("onUpload")
.Progress("onProgress"))
//.Async(a=>a.AutoUpload(false))
.Validation(v => v.AllowedExtensions(new string[] { ".csv", ".xls", ".xlsx", ".txt" }))
)
</div>
Here is the javascript code for all the js events I want to invoke.
<script>
var _files;
function onSelect(e) {
var files = e.files;
alert(files[0].name);
_files = files[0];
//file = files[0].name;
var acceptedFiles = [".xlsx", ".xls", ".txt", ".csv"]
var isAcceptedFormat = ($.inArray(files[0].extension, acceptedFiles)) != -1
if (!isAcceptedFormat) {
e.preventDefault();
$("#meter_addt_details").addClass("k-state-disabled");
//$("#submit_btn").addClass("k-state-disabled");
document.getElementById("submit_btn").disabled = true;
alert("Please upload correct file. Valid extensions are xls, xlsx,txt,csv");
}
else {
/* Here I tried to upload file didn't work out */
$("#meter_addt_details").removeClass("k-state-disabled");
// $("#submit_btn").removeClass("k-state-disabled");
document.getElementById("submit_btn").disabled = false;
#*
$("#files").kendoUpload({
async: {
saveUrl: '#Url.Action("ReadMeterFile","Administration")',
autoUpload: false
}
}); *#
$("#files").kendoUpload();
//$(".k-upload-selected").click();
#*var upload = $("#files").data("kendoUpload");
upload.upload(); *#
}
}
#*
function onUpload(e) {
$(".k-upload-selected").trigger('click');
//console.log("Upload :: " + getFileInfo(e));
}
function onSuccess(e) {
console.log(files[0].name);
_files = e.files[0];
}
function onProgress(e) {
console.log("Upload progress :: " + e.percentComplete);
}
function onComplete(e) {
console.log("Complete");
}
function onSubmitButtonClick(e) {
var formData = new FormData();
alert(_files.name);
formData.append('files', _files);
formData.append('order_num', $("#order").val());
formData.append('purchase_order', $("#purchase_order").val());
$.ajax({
url: '#Url.Action("ReadFile","Administration")',
data: formData,
type: 'POST',
processData: false,
contentType: false,
dataType: "json",
success: function (data) {
alert("Good");
}
});
}
</script>
Here is my controller:
public ActionResult ReadFile(IEnumerable<HttpPostedFileBase> files,string order_num, string purchase_order)
{
System.Diagnostics.Debug.WriteLine("File length:"+files.ToList().Capacity);
foreach(var f in files)
{
System.Diagnostics.Debug.WriteLine(f.FileName);
var fileName = Path.GetFileName(f.FileName);
var destinationPath = Path.Combine(Server.MapPath("~/App_Data"), fileName);
f.SaveAs(destinationPath);
}
//System.Diagnostics.Debug.WriteLine(file);
/*
System.Diagnostics.Debug.WriteLine("File:"+files);
System.Diagnostics.Debug.WriteLine("Order:"+order_num);
System.Diagnostics.Debug.WriteLine("Purchase Order:"+purchase_order);
return Content("");
}
Here is some code I used before for manually uploading from the kendo upload widget. From your question I think what you are looking for is the way to correctly get the info on the controller side. However, I will add the code I have used which should help you out. (My code uploads a PDF)
#(Html.Kendo().Upload()
.Name("pdf-file")
.Multiple(false)
.Validation(v => v.AllowedExtensions(new string[] { "pdf" }))
.Events(ev => ev.Select("pdfSelected"))
)
function pdfSelected(e) {
if (e.files != null && e.files.length > 0 && e.files[0] != null) {
var file = e.files[0];
if (file.validationErrors != null && file.validationErrors.length > 0) {
return; //These errors will show in the UI
}
var formData = new FormData();
formData.append('PdfFile', file.rawFile);
formData.append('AdditionalValue', 'Some String');
$.ajax({
type: 'post',
url: '[SOMEURL]',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: pdfUploaded
});
}
}
function pdfUploaded(data) {
//Whatever you want.
}
Inside of pdfSelected is the code that actually posts the file. If you want to do it all at the same time along with other properties, via a submit button. Then instead of performing the upload there. Do nothing but your validation for the upload or don't implement pdfSelected and wait until submit is clicked to perform the validation(probably better). Then on your button click
//Or course check files.length to avoid errors. Not added to keep it short
var files = $('#pdf-file').data('kendoUpload').getFiles();
var file = files[0];
Everything from "var formData = new FormData();" down, from the code above remains the same. Here is the controller code.
public ActionResult MyAction() {
string additionalValue = (string) this.Request.Form["AdditionalValue"];
HttpPostedFileBase file = this.Request.Files["PdfFile"];
//Do whatever you need to with them.
}
The file's rawFile property is what you need not just the file object because that is kendo specific.

Create PDF with Ajax

I am using FPDF to create my report.
$pdf = new Report('P','mm','A4', $_POST);
$pdf->AddPage();
$pdf->Output('file.pdf','I');
And I use ajax to make requisition to the PHP.
$.ajax({
type: 'POST',
url: '../reports/report.php',
data: { id: id }
}).done(function(data){
window.open(data);
})
I want to show the report in a new tab
I think you should success key. So it would be something like this
$.ajax({
type: 'POST',
url: '../reports/report.php',
data: { id: id },
success: function(data){
var blob = new Blob([data]);
window.open(URL.createObjectURL(blob));
}
})
Resolved:
I did the different way:
In my report PHP, I generate one temporay file, passing the parameter 'F'.
$pdf->Output('file.pdf','F');
In Jquery Ajax I opne the file, rather than open the data retorned of ajax request.
$.ajax({
type: 'POST',
url: '../reports/report.php',
data: { id: id }
}).done(function(data){
var fileName = "file.pdf";
$('#modalRel').modal('show');
var object = "<object data=\"{FileName}\" type=\"application/pdf\" width=\"500px\" height=\"300px\">";
object += "If you are unable to view file, you can download from here";
object += " or download <a target = \"_blank\" href = \"http://get.adobe.com/reader/\">Adobe PDF Reader</a> to view the file.";
object += "</object>";
object = object.replace(/{FileName}/g, "../Files/" + fileName);
$("#body-rel").html(object);
})
I hope to have helped who one day to need.

Passing javascript variables(array) to php

I have a function where the user inputs are stored in a variable in javascript.
$('#btnsubmit').click(function() {
var seat = [], item;
$.each($('#place li.' + settings.selectingSeatCss + ' a'), function (index, value) {
item = $(this).attr('title');
seat.push(item);
});
var bookseats = seat;
$.ajax({
type: 'POST',
url: 'confirm.php',
data: {'bookseats': bookseats},
});
});
When the user clicks on the #btnsubmit button, I want to send this variable(actually an array) to a PHP file named confirm.php.
<form method="POST" action="confirm.php">
<div align="center"><input type="Submit" id="btnsubmit" value="Submit" /></div>
</form>
In my PHP file, I've written the code to get the sent variable as follows.
$bookseats = "";
if(isset($_POST['bookseats']))
{
$bookseats = $_POST["bookseats"];
print_r($bookseats);
}
When executed, nothing happens in the PHP file(doesn't print the bookseats).Is there something wrong with this code?
You're not using a "success" callback to get the output of the PHP code. See success callback
$.ajax({
type: 'POST',
url: 'confirm.php',
data: {'bookseats': bookseats},
success: function(data) {
console.log(data); // or alert(data);
}
});
Also, I think you should stop the propagation of the default behavior of the button, to prevent the browser to redirect the page to the form's action URL:
$('#btnsubmit').click(function(ev) {
ev.preventDefault();
As #Malovich pointed out, as of jQuery 1.8, you could also use .then():
$.ajax({
type: 'POST',
url: 'confirm.php',
data: {'bookseats': bookseats}
}).then(function(data) {
console.log(data); // or alert(data);
}, function(){
console.log("Error");
});

Categories

Resources