Why my django form is not submitting while submitting via AJAX? - javascript

I am trying to upload an image via AJAX with a Django view. Here is my HTML form.
<form class="BackgroundImageUplaoder" action="/uplaod" id="form2">{% csrf_token %}
<input type="file" accept="/image*" name="image" multiple="false" />
<button type="submit">Uplaod</button>
While the corresponding ajax is:-
$(document).ready(function(){
$('#form2').submit(function(){
var csrftoken = $("[name=csrfmiddlewaretoken]").val();
var formdata={
'image':$('input[name=image]').val(),
};
console.log("Formvalue is taken");
console.log(formdata.image);
$.ajax({
type:'POST',
url:'/Upload/Background/',
data:formdata,
dataType:'json',
encode:true,
headers:{
"X-CSRFToken": csrftoken
},
processData:false,
contentType:false,
})
.done(function(data){
console.log(data);
if(!data.success){//we will handle error
if (data.password){
console.log(data.password);
$('#password_error').text(data.password);
}
return false;
}
else{
window.location='/';
}
});
event.preventDefault();
});
});
and django view is:-
def uploadbackground(request):
if request.method=="POST":
form=BackgroundImageUplaod(request.POST,request.FILES)
if form.is_valid():
instance=form.save(commit=False)
myobject=HomeScreen.objects.get(profile__user=request.user)
if myobject:
myobject.image=instance
myobject.save()
return JsonResponse({'success':True})
else:
sample=HomeScreen(profile__user=request.user,image=instance)
sample.save()
return JsonResponse({'success':True})
else:
form=BackgroundImageUplaod()
return JsonResponse({'image':'An error is encountered while uplaoding','errors': [(k, v[0]) for k, v in form.errors.items()]})
The console is showing following error
According to my view, The form is not validating.After validating my forming. I am checking that whether the instance correponding to current logged in user exist or not.If yes i am updating that instance otherwise creating new object

Your issue is that you cannot send an image via an AJAX JSON POST, which only accepts strings and integers. You need to use formData.
https://webkul.com/blog/send-images-through-ajax/

Related

Ajax returning empty string in Django view

I am developing a web application through Django and I want to get information from my javascript to a view of Django in order to access to the database.
I am using an ajax call as this post shows.
I am calling the js in html by an onclick event :
sortedTracks.html
...
<form action="{% url 'modelReco:sortVideo' video.id %}">
<input type="submit" value="Validate" onclick="ajaxPost()" />
</form>
...
clickDetection.js
//defined here
var tracksSelected = [];
//function that fill tracksSelected
function tagTrack(track_num){
if(tracksSelected.includes(track_num)){
var index = tracksSelected.indexOf(track_num);
tracksSelected.splice(index, 1);
}else{
tracksSelected.push(track_num);
}};
//ajax function
function ajaxPost(){
$.ajax({
method: 'POST',
url: '/modelReco/sortedTracks',
data: {'tracksSelected': tracksSelected},
success: function (data) {
//this gets called when server returns an OK response
alert("it worked! ");
},
error: function (data) {
alert("it didnt work");
}
});
};
So the information I want to transfer is tracksSelected and is an array of int like [21,150,80]
views.py
def sortedTracks(request):
if request.is_ajax():
#do something
print(request)
request_data = request.POST
print(request_data)
return HttpResponse("OK")
The ajax post works well but the answer I get is only an empty Query Dict like this :
<QueryDict: {}>
And if I print the request I get :
<WSGIRequest: GET '/modelReco/sortedTracks/?tracksSelected%5B%5D=25&tracksSelected%5B%5D=27&tracksSelected%5B%5D=29'>
I have also tried to change to request_data=request.GET but I get a weird result where data is now in tracksSelected[]
I've tried to know why if I was doing request_data=request.GET, I get the data like this tracksSelected[] and get only the last element of it.
And I found a way to avoid to have an array in my data (tracksSelected) on this link
This enables me to have :
in views.py
def sortedTracks(request):
if request.is_ajax():
#do something
print(request)
request_data = request.GET.getlist("tracksSelected")[0].split(",")
print(request_data)
and in clickDetection.js
function ajaxPost(){
tracksSelected = tracksSelected.join();
$.ajax({
method: 'POST',
url: '/modelReco/sortedTracks',
data: {'tracksSelected': tracksSelected},
success: function (data) {
//this gets called when server returns an OK response
alert("it worked! ");
},
error: function (data) {
alert("it didnt work");
}
});
};
This little trick works and I am able to get the array data like this,
print(request_data) returns my array such as [21,25,27]
Thank you for helping me !
According to me to access the data which is sent in the ajax request can be directly accessed .
For Example:
def sortedTracks(request):
if request.method == 'POST':
usersV = request.POST.get('tracksSelected')[0]
for users in usersV:
print users
return HttpResponse("Success")
else:
return HttpResponse("Error")
The correct syntax is data: {tracksSelected: tracksSelected},

Why is this ajax code not working?

I'm trying to submit a form with ajax with the code below, but apparently doesn't seem to work.
Any suggestion to fix this problem?
$(".dialog-set-new-message").on('keyup', '.ctxtareados', function(b){
if(b.keyCode == 8){return false;}
if(b.keyCode == 13){
//
$("#submit_new_message_cbox").submit(function(eventmsg){
$(".loader-wait-gif-con").fadeIn(500);
eventmsg.preventDefault();
$.ajax({
url: "https://www.mypage.com/success/set_new_cbox_message.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs representing form fields and values
contentType: false, // The content type used when sending data to the server. Default is: "application/x-www-form-urlencoded"
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false (i.e. data should not be in the form of string)
success: function(data) // A function to be called if request succeeds
{
$(".dialog-new-chat-open-con").load("../success/refresh_new_cbox.php", function(){
$(".loader-wait-gif-con").fadeOut(500);
$(".con-sub-nav-chat h3").html("Messages updated.");
$(".con-sub-nav-chat").css("display", "block");
$(".con-sub-nav-chat").fadeOut(7000);
$(".all-msg-new-chat-box").animate({scrollTop: $("#sldum").offset().top}, 1000);
});
$('#submit_new_message_cbox')[0].reset();
}
});
});
//
}
});
--FIXED--
I Added a input[submit] in the php file and modified the code as follow:
PHP Code added:
<input style="visibility: hidden;" id="submitnmcbox" type="submit">
JS Code Modified (same as above):
$(".dialog-set-new-message").on('keyup', '.ctxtareados', function(b){
if(b.keyCode == 8){return false;}
if(b.keyCode == 13){
$("#submitnmcbox").click();
}
});
//Set new msg chat
$("#submit_new_message_cbox").on('submit', function(eventmsg){
$(".loader-wait-gif-con").fadeIn(500);
eventmsg.preventDefault();
$.ajax({
url: "https://www.dudoby.com/success/set_new_cbox_message.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs representing form fields and values
contentType: false, // The content type used when sending data to the server. Default is: "application/x-www-form-urlencoded"
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false (i.e. data should not be in the form of string)
success: function(data) // A function to be called if request succeeds
{
$(".dialog-new-chat-open-con").load("../success/refresh_new_cbox.php", function(){
$(".loader-wait-gif-con").fadeOut(500);
$(".con-sub-nav-chat h3").html("Se han actualizado los mensajes.");
$(".con-sub-nav-chat").css("display", "block");
$(".con-sub-nav-chat").fadeOut(7000);
$(".all-msg-new-chat-box").animate({scrollTop: $("#sldum").offset().top}, 1000);
});
$('#submit_new_message_cbox')[0].reset();
}
});
});
//
I think you are using FormData() constructor wrongly. According to MDN, FormData() constructor accept HTML DOM form element (optional). Example:
<form name="myForm">
<input type="text" name="text_field_1" value="test1" /><br /><br />
<input type="text" name="text_field_2" value="test2" /><br /><br />
<input type="text" name="text_field_3" value="test3" /><br />
</form>
<script type="text/javascript">
var myForm = document["myForm"];
var formData = new FormData(myForm);
console.log(formData.get("text_field_2")); // returns "test2"
</script>

Accessing type="file" input from POST method on server side

Having some difficulty understanding how to access type="file" input on the server side. Below is the code I'm using. I use AJAX because I want my web app to not require refreshing, and am using a slightly roundabout way of submitting my form so I can have a better UI.
My HTML:
<form id="updateProfileImageForm" enctype="multipart/form-data">
<div class="updateProfileImageContainer">
<img src="images/profile/generic.png" class="updateProfileImage">
<div class="updateProfileImageOverlay" onclick="changeImageToUpload()">
<div class="updateProfileImageOverlayText">Upload new image</div>
</div>
<input type="file" id="imageToUpload" name="image" style="display: none;" onChange="$(this).closest('form').trigger('submit');"></input>
</div>
</form>
My JS:
function changeImageToUpload() {
$('#imageToUpload').trigger('click');
}
$('#updateProfileImageForm').submit(function(e) {
e.preventDefault();
var form_data = new FormData(this);
$.ajax({
type: 'POST',
url: '/changeProfile',
data: form_data,
processData: false,
success: function(response) {
if(response.message != null) {
alert(response.message);
} else {
// Change profile image displayed
$('.updateProfileImage').attr("src", response.newProfileImage);
alert('Profile picture successfully updated! Refresh your browser to update your window!');
}
}
})
});
My Server PHP:
if (isset($_FILES['image'])) {
$image = $_FILES['image'];
}
Var_dump on $_FILES shows an empty array, while var_dump on $_POST shows a lot of information (which I'm assuming is my data file). However, accessing the 'image' property on either $_POST or $_FILES (through either $_POST['image'] or $_FILES['image']) gives me either "undefined index" or "undefined variable".
Would you guys be so kind as to educate me on:
What's the difference between $_POST and $_FILES?
How should I be accessing the file in this case?
Thanks!
You're missing a necessary config option in your ajax request, you need to set contentType to false
$.ajax({
type: 'POST',
url: '/changeProfile',
data: form_data,
processData: false,
contentType: false,
success: function(response) {
if(response.message != null) {
alert(response.message);
} else {
// Change profile image displayed
$('.updateProfileImage').attr("src", response.newProfileImage);
alert('Profile picture successfully updated! Refresh your browser to update your window!');
}
}
})
jQuery.ajax sets the content type by default to application/x-www-form-urlencoded which is incorrect for your FormData object, if you set it to false it will be set correctly by the underlying XMLHTTTPRequest object.
Idea behind it.
Instead of using file as post to PHP, simply convert image to base64 and receive that string using ajax in php.
Refer to this URL

Laravel: no data being sent via ajax

I made a custom Jquery plugin to help me easily send data via Ajax to the server that has been tailored to suit laravel, but apparently I am not able to send any data. when I use dd($request->all()) to check what has been sent to the laravel server, I receive an empty array in console implying that I have not sent anything. Below is my code
JS
(function($){
'use strict'
$.fn.lajax=function(options){
//overwrite options
var optns=$.extend({
dataType: 'json',
debug:false,
processData: true,
headers:{
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
acceptedInputFile:'/*/',
//functions that are very similar to the ajax optns but differ a little
//as the paramters give easy access to the ajax form element
lajaxBeforeSend: function(form,formData,jqXHR,settings){},
lajaxSuccess: function(form,formData,data,textStatus,jqXHR){},
lajaxError: function(form,formData,jqXHR,textStatus,errorThrown){},
},options);
//loop through every form, 'this' refers to the jquery object (which should be a list of from elements)
this.each(function(index,el){
$(el).submit(function(e){
//prevent submission
e.preventDefault();
//form jquery instance & form data
var $form=$(this);
var formData = new FormData($form[0]);
//catch url where the ajax function is supposed to go
var url=$form.attr('action');
//check if REST based method is assigned
if($form.find('input[name="_method"]').length)
{
var method=$(this).find(':input[name="_method"]').val().toUpperCase();
if(optns.debug)
console.log("'"+method+"' method registered for form submission");
}
//If no REST method is assigned, then check method attr
else if($form.attr('method'))
{
var method=$form.attr('method').toUpperCase();
if(optns.debug)
console.log("'"+method+"' method registered for form submission");
}
//method is not assigned
else
{
var method='GET';
if(optns.debug)
console.log('The form that submitted has no method type assigned. GET method will be assigned as default');
}
//object that will be fed into jquerys ajax method
var ajax_options={
url: url,
method: method,
beforeSend: function(jqXHR,settings){
console.log(jqXHR);
console.log(settings);
if(optns.debug)
console.log('executing beforeSend function');
optns.lajaxBeforeSend($form,formData,jqXHR,settings);
},
success: function(data,textStatus,jqXHR){
if(optns.debug)
console.log('executing success function');
optns.lajaxSuccess($form,formData,data,textStatus,jqXHR)
},
error: function(jqXHR,textStatus,errorThrown){
if(optns.debug)
console.log('error encountered. ajax error function procked');
optns.lajaxError($form,formData,jqXHR,textStatus,errorThrown);
var errors = jqXHR.responseJSON;
console.log(errors);
},
}
//check if files are included in the submitted form if the method is not GET
if($form.find('input:file').length && method!='GET'){
ajax_options.processData=false;
ajax_options.contentType=false;
ajax_options.cache=false;
ajax_options.data=formData;
}
if(optns.debug)
console.log('About to send ajax request');
//sending request here
$.ajax(ajax_options);
if(optns.debug)
console.log('finished with form '+$form+'. Looping to next form if exists');
return false;
});
});
return this;
}
}(jQuery));
HTML
<form class="lajax" action="{{ action('AlbumController#store') }}" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label>Album Name</label>
<input type="text" name="name" class="form-control">
</div>
<div class="form-group">
<label for="coverFile">Album Cover Image</label>
<input name="cover" type="file" id="coverFile">
<p class="help-block">Example block-level help text here.</p>
</div>
<div class="form-group">
<label for="albumFiles">Album Images</label>
<input type="file" name="photos[]" multiple>
</div>
<button type="submit" class="btn btn-primary">Create Album</button>
</form>
I think my JS is not sending my data over to the server but im not sure why. Please help
Did you define a Post route in your route file that exactly point to AlbumController#store Controller method

AJAX to PHP without page refresh

I'm having some trouble getting my form to submit data to my PHP file.
Without the AJAX script that I have, the form takes the user through to 'xxx.php' and submits the data on the database, however when I include this script, it prevents the page from refreshing, displays the success message, and fades in 'myDiv' but then no data appears in the database.
Any pointers in the right direction would be very much appreciated. Pulling my hair out over this one.
HTML
<form action='xxx.php' id='myForm' method='post'>
<p>Your content</p>
<input type='text' name='content' id='content'/>
<input type='submit' id='subbutton' name='subbutton' value='Submit' />
</form>
<div id='message'></div>
JavaScript
<script>
$(document).ready(function(){
$("#subbutton").click(function(e){
e.preventDefault();
var content = $("#content").attr('value');
$.ajax({
type: "POST",
url: "xxx.php",
data: "content="+content,
success: function(html){
$(".myDiv").fadeTo(500, 1);
},
beforeSend:function(){
$("#message").html("<span style='color:green ! important'>Sending request.</br></br>");
}
});
});
});
</script>
A couple of small changes should get you up and running. First, get the value of the input with .val():
var content = $("#content").val();
You mention that you're checking to see if the submit button isset() but you never send its value to the PHP function. To do that you also need to get its value:
var submit = $('#subbutton').val();
Then, in your AJAX function specify the data correctly:
$.ajax({
type: "POST",
url: "xxx.php",
data: {content:content, subbutton: submit}
...
quotes are not needed on the data attribute names.
On the PHP side you then check for the submit button like this -
if('submit' == $_POST['subbutton']) {
// remainder of your code here
Content will be available in $_POST['content'].
Change the data atribute to
data:{
content:$("#content").val()
}
Also add the atribute error to the ajax with
error:function(e){
console.log(e);
}
And try returning a var dump to $_POST in your php file.
And the most important add to the ajax the dataType atribute according to what You send :
dataType: "text" //text if You try with the var dump o json , whatever.
Another solution would be like :
$.ajax({
type: "POST",
url: "xxxwebpage..ifyouknowhatimean",
data: $("#idForm").serialize(), // serializes the form's elements.
dataType:"text" or "json" // According to what you return in php
success: function(data)
{
console.log(data); // show response from the php script.
}
});
Set the data type like this in your Ajax request: data: { content: content }
I think it isnt a correct JSON format.

Categories

Resources