AJAX POST not actually sending POST data with Django - javascript

I want to submit a form to my Django back end using an AJAX post. I have multiple forms on the page but only want the one the user submits to be the one that sends.
The form is held in a modal:
<div class="modal-body">
<div class='content-section'>
<form method="POST" id="form{{ prod.id }}" class="showform" value="{{ prod.id }}" >
<input type="hidden" value="{{ prod.id }}" name="prodid">
{% csrf_token %}
<fieldset class='form-group'>
{{ form|crispy}}
</fieldset>
</form>
</div>
</div>
<div class="modal-footer">
<div class='form-group'>
<button class="btn btn-outline-info submit-form" value={{prod.id}} form="form{{ prod.id }}"
>Save
To Profile</button>
</div>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
When the submit button is pressed, it triggers the following AJAX :
$(document).on('click', '.submit-form', function () {
var thisButton = $(this)[0]
var prodID = $(this).val();
var form = $("form" + prodID);
$.ajax({
type: 'post',
headers:{
"X-CSRFToken": '{{ csrf_token }}'
},
url: '/ajax/validate_showadd/',
dataType: 'json',
contentType: 'json',
data: {
'form': form.serialize(),
"prodID":prodID,
},
success: function (data) {
console.log("sent")
},
error: function(data) {
console.log("error")
}
});
return false;
});
However, within Django whenever I try access any of these values it just returns 'None' and the QueryDict for the POST request is empty.
Thank you

Related

Displaying comments using Ajax

i am working on a project using Django. There are lists of users posts in homepage and each post has a comment form. I was able to implement comment properly on views, but the issue now is when I submit a comment it display empty string instead of the comment, the comment display in chrome console. How do i display comment on each post by user when a form is submitted. I attached an image to my questioin to clarify my question.
home.html
<div id="newfeeds-form">
{% include 'ajax_newfeeds_comments.html' %}
</div>
ajax_newfeeds_comments.html
<!-- New Feeds comment Text -->
{% for post in all_images %}
<div class="container newfeeds-comment" id="display-comment">
{% for comment in post.comments_set %}
<div class="row">
<div class="col-1 col-md-1 col-lg-1">
{% if comment.user.profile.profile_pic %}
<img src="{{ comment.user.profile.profile_pic.url }}" class="d-flex rounded-circle" alt="image" height="28" width="28">
{% endif %}
</div>
<div class="col-10 col-md-10 col-lg-10 p-2 ml-1" id="user-commentpost">
<span class="comment-post truncate">
<span class="name text-lowercase">{{ comment.user }}</span>
{{ comment.comment_post }}</span>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
<span class="md-form">
<form enctype="multipart/form-data" class="feeds-form form-inline md-form form-sm" method="POST" action="{% url 'site:home' %}" id="newfeeds-form{{ post.id }}">
{% csrf_token %}
<input type="hidden" value={{post.id}} name="post_comment">
<img src="{{ request.user.profile.profile_pic.url }}" class="rounded-circle avatar-img" height="28" width="28">
<textarea name="comment_post" class="textinput textInput animated fadeIn" placeholder="Add a comment..." required="" id="id_comment_post{{ post.id }}" onkeyup=""></textarea>
<button type="submit" class="submit" id="submit1-{{post.id}}"><i class="fas fa-paper-plane"></i></button>
</form
</span>
Views:
def home_view(request):
#All posts in new feed
all_images = Post.objects.filter(
Q(poster_profile=request.user, active=True)|
Q(poster_profile__from_user__to_user=request.user, active=True)|
Q(poster_profile__to_user__from_user=request.user, active=True)|
Q(poster_profile__profile__friends__user=request.user, active=True)).distinct().exclude(
Q(hide_post=request.user, active=True)|
Q(poster_profile__profile__blocked_users__user=request.user, active=True))
#Comment form homepage
if request.method == 'POST':
post_id = request.POST.get("post_comment")
post_obj = Post.objects.get(pk=post_id)
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.user = request.user
comment.commented_image = post_obj
comment.save()
# messages.info(request,'You submitted a comment')
#return redirect('/')
else:
form = CommentForm()
context = {
'form': form,
'all_images': all_images,
}
if request.is_ajax():
html = render_to_string('ajax_newfeeds_comments.html', context, request=request)
return JsonResponse({'form': html})
return render(request,'home.html', context)
Ajax:
<script type="text/javascript">
//HomeFeeds Comment
$(document).ready(function() {
$('.feeds-form').on('submit', onSubmitFeedsForm);
$('.feeds-form .textinput').on({
'keyup': onKeyUpTextInput,
'change': onKeyUpTextInput
});
function onKeyUpTextInput(event) {
var textInput = $(event.target);
textInput.parent().find('.submit').attr('disabled', textInput.val() == '');
}
function onSubmitFeedsForm(event) {
event.preventDefault();
console.log($(this).serialize());
var form = $(event.target);
var textInput = form.find('.textinput');
var hiddenField = form.find('input[name="post_comment"]');
$.ajax({
type: 'POST',
url: "{% url 'site:home' %}",
data: form.serialize(),
dataType: 'json',
beforeSend: function() {
form.find('.submit').attr('disabled', true);
},
success: function(response) {
$('#newfeeds-form' + hiddenField.val()).html(response.form);
textInput.val('');
var numberOfCommentsElement = $('#number-of-comments');
numberOfCommentsElement.text(parseInt(numberOfCommentsElement.text()) + 1);
},
error: function(rs, e) {
console.log(rs.resopnseText);
},
complete: function() {
textInput.trigger('change');
}
});
}
});
</script>
You don't need ajax actually, you can simply:
let value = $('myInput').val();
$('myCommentContainer').prepend(`
Format the comment as you want ${value}
`)
$('myInput').val('') // To empty the value
now call the ajax normally:
$({
type: 'POST',
url: "{% url 'site:home' %}",
data: form.serialize(),
dataType: 'json',
beforeSend: function() {
form.find('.submit').attr('disabled', true);
},
success: function(response) {}
})
Done, leave the success empty
appending it within the ajax success will make it slower anyway!

Submit form without form id

I need to submit form using through Ajax call but I'm having trouble selecting the form. I don't want to use form ID because I'm having multiple forms and I need to setup one code for all
$(".pay").on("click",function(){
var form = $(this).closest(".card-body").find("form");
//$(form).submit(function(e) {
e.preventDefault();
var formData = $(form).serialize();
$.ajax({
type: 'POST',
url : "php/pay.php",
data: formData
})
.done(function(response) {
})
//});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card" >
<div class="card-header">
<h1>XXX</h1>
</div>
<div class="card-body" >
<form>
<input name="user" value="mat" type="hidden">
<input name="id" value="12" type="hidden">
</form>
<button class="btn btn-success pay" value="pay">pay</button>
<button class="btn btn-danger decline" value="decline" >decline</button>
</div>
</div>
No need to add form submit code because you are preventing submit, so when will you click just fetch data from the form and call your AJAX service.
I added one console log where you can see your form data.
$(".pay").on("click",function(){
var form = $(this).closest(".card-body").find("form");
var formData = $(form).serialize();
console.log(formData);
$.ajax({
type: 'POST',
url : "php/pay.php",
data: formData
})
.done(function(response) {});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card">
<div class="card-header">
<h1>XXX</h1>
</div>
<div class="card-body" >
<form>
<input name="user" value="mat" type="hidden">
<input name="id" value="12" type="hidden">
</form>
<button class="btn btn-success pay" value="pay">pay</button>
<button class="btn btn-danger decline" value="decline" >decline</button>
</div>
</div>
This will help you to reduce duplicating the code..
$(document).ready(function() {
$('form').on('submit', function(e){
e.preventDefault();
Var action = $(this).action;
Var method = $(this).method;
Var data = $(this).serialize();
// perform ajax operation here with data, action and method
});
});
Happy coding :)
Your code is creating submit handler everytime the button is clicked, all you want is to send ajax call onclick, so just do that part.
$(".pay").on("click",function(){
var form = $(this).closest(".card-body").find("form");
// below code is creating submit handler everytime the button is clicked
$(form).submit(function(e) {
e.preventDefault();
var formData = $(form).serialize();
$.ajax({
type: 'POST',
url : "php/pay.php",
data: formData
})
.done(function(response) {
})
});
});
Also .find returns jQuery object, no need to make it Jquery object again, simple form will do instead of $(form).. rather declare like var $form = $(this).closest(".card-body").find("form")
Something like below, try
$(".pay").on("click",function(){
var $form = $(this).closest(".card-body").find("form");
e.preventDefault();
var formData = $form.serialize();
submitForm(formData);
});
function submitForm(formData){
$.ajax({
type: 'POST',
url : "php/pay.php",
data: formData
})
.done(function(response) {
})
}
I've created below sample to refer
$(function() {
$(".pay").on("click", function(e) {
var $form = $(this).closest(".card-body").find("form");
e.preventDefault();
var formData = $form.serialize();
console.log(formData)
submitForm(formData);
});
function submitForm(formData) {
alert("submitting form with " + formData)
$.ajax({
type: 'POST',
url: "php/pay.php",
data: formData
})
.done(function(response) {})
}
});
.card {
width: 50%;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card">
<div class="card-header">
<h1>XXX</h1>
</div>
<div class="card-body">
<form>
<input name="user" value="mat" type="hidden">
<input name="id" value="12" type="hidden">
</form>
<button class="btn btn-success pay" value="pay">pay</button>
<button class="btn btn-danger decline" value="decline">decline</button>
</div>
</div>
<div class="card">
<div class="card-header">
<h1>YYY</h1>
</div>
<div class="card-body">
<form>
<input name="user2" value="mat2" type="hidden">
<input name="id2" value="122" type="hidden">
</form>
<button class="btn btn-success pay" value="pay">pay2</button>
<button class="btn btn-danger decline" value="decline">decline2</button>
</div>
</div>
Erm.. Why not just put the two buttons inside the form, to avoid any confusion or off-chance that the script might trigger another one of the "multiple forms" and refer to the nameless form through the parent element instead, like?
html:
<form>
<input name="user" value="mat" type="hidden">
<input name="id" value="12" type="hidden">
<button class="btn btn-success pay" value="pay">pay</button>
<button class="btn btn-danger decline" value="decline">decline</button>
</form>
script:
$(function() {
$(".pay").on("click", function(e) {
var $form = $(this).parent();
e.preventDefault();
var formData = $form.serialize();
submitForm(formData);
});

Using Ajax to post a form, no response

Django version 1.11.1
I have a form on my template, wanna use ajax to post it which can only change the form, my form code like:
<form action="" class="poster" id="posterForm">
{% csrf_token %}
<input type="file" accept="image/png,image/gif,image/jpeg" id="img_input" class="file_btn">
<input type="button" class="file_front_btn" value="选择图片" name="image">
<input type="text" name="title" id="title" class="title_area" placeholder="标题(不超过20字):">
<span class="img_root">已选图片:<span id="img_root" class="hidden">无</span></span>
<textarea name="content" id="content" name="content" class="content_area" placeholder="输入内容(不超过2000字):"></textarea>
<div id="title_error"></div>
<div id="content_error"></div>
<input type="button" class="submit" id="submitBtn" value="发布">
<div id="img_error"></div>
</form>
And my jQuery:
$(function(){
$('#submitBtn').on('click', function(){
$.ajax({
cache: false,
type: "POST",
url:"{% url 'community:poster' %}",
data:$('#posterForm').serialize(),
async: true,
success: function(data) {
if(data.status == 'success'){
$('#posterForm')[0].reset();
alert("发布成功")
}else if(data.status == 'fail'){
$('#img_error').html(data.msg)
}
},
});
});
})
And my views is:
class PosterView(View):
def post(self, request):
poster_form = PostForm(request.POST)
if poster_form.is_valid():
poster = poster_form.save(commit=True)
return HttpResponse("{'status':'success'}", content_type='application/json')
else:
return HttpResponse("{'status':'fail', 'msg':{0}}".format(poster_form.errors), content_type='application/json')
I use a ModelForm to commit the form, the forms is:
class PostForm(forms.ModelForm):
class Meta:
model = Posts
fields = ['image', 'title', 'content']
urls:
urlpatterns =[
url(r'^allpost/$', AllPosts.as_view(), name='allpost'),
url(r'^poster/$', PosterView.as_view(), name='poster'),
]
I can't see where the problem is, but when I click the submit button, nothing happened, no fail status.

My twitter typehead and django-haystack solr config is not returning any results

Not very good with anything javascript, jquery. I am trying to return results from solr and run it through the typehead and have a dropdown list in a google or bing type fashion. Iv'e been kinda messing around with it but I'm deadlocked. I created a drop down list but it doesn't look nice. Heres my code
views.py
def search_title(request):
posts = SearchQuerySet().models(Post).autocomplete(content_auto=request.GET.get('search_text', ''))
context = {
"posts": posts
}
# context.update(csrf(request))
return render(request, "posts/ajax_search.html", {"posts": posts})
posts/urls.py
urlpatterns = [
url(r'^$', post_list, name='list'),
......
url(r'^search_f/$', search_title),
....
]
ajax_search.html
{% if posts.count > 0 %}
{% for post in posts %}
<div>{{ post.title }}</div>
{% endfor %}
{% else %}
<li class="list-group-item"> None to show</li>
{% endif %}
snippet of nav.html
<form method="GET" action="{% url 'posts:search-page' %}" class="navbar-form navbar-right" role="search">
<div>
<div class="input-group">
<input type="text" class="form-control" autocomplete="off" name="q" id="search" placeholder="search" value="{{ request.GET.q }}">
<span class="input-group-btn">
<button type="submit" class="btn btn-default">search</button>
</span>
</div><!-- /input-group -->
<div class="list-group" id="search-results" style="margin: 5px 0 0 0; width: 172px">
</div>
</div><!-- /.col-lg-6 -->
</form>
ajax.js
$(function(){
$('#search').keyup(function() {
$.ajax({
type: "GET",
url: "/posts/search_f/",
data: {
'search_text': $('#search').val(),
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
success: searchSuccess,
dataType: 'html'
});
});
});
function searchSuccess(data, textStatus, jqXHR)
{
$('#search-results').html(data);
}
$('#search-results').typeahead({
name: 'user-search',
remote: '/posts/search_f/%QUERY' // you can change anything but %QUERY
});
I also need it to to be done so I won't get an error like this
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.
I recently spent hours trying to resolve this on google chrome only to have it resolove itself
EDIT
I did some research and even though it didn't work I feel like I'm on the right track
$(function() {
$("#search").typeahead({
source:function(query,process) {
$.ajax({
url:'posts/search_f',
type:'GET',
data: {
'search_text': $('#search').val(),
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
//dataType: 'JSON',
async: true,
success: function(data) {
console.log(data)
}
})
}
})
});

stay on page after submission of ajax form

I have a small popbox window which users are supposed to use to send a message to another user. After clicking the send button I send the data to views.py in my flask application.
At that point I would like the popbox to close and nothing else. Instead what happens is that I get a print out on my site with
{
"data": null
}
my ajax command is
<script type='text/javascript'>
$(".send_recommend").click(function() {
var data = $("form").serialize();
$.ajax({
url: "/send_recommend",
type: "GET",
async: true,
cache: false,
contentType: "application/json; charset=utf-8",
data: { send_dummy_id: document.getElementById("send_dummy_id").value, data: data },
});
});
</script>
and the flask part of this looks like
#app.route('/send_recommend', methods=['GET', 'POST'])
def send_recommend():
if request.method == 'GET':
ret_data = {"data": request.args.get('data')}
#do something here
return jsonify(ret_data)
The html looks like
<div class='popbox' style="display: inline">
<button class="btn btn-primary open" href="#" data-id="{{ data['arxiv_id'] }}" role="button"><span class="glyphicon glyphicon-share"></span>Recommend this paper</button>
<div class='collapse_popbox'>
<div class='box'>
<div class='arrow'></div>
<div class='arrow-border'></div>
<form action="/send_recommend" method="GET" style="padding:10px;" align="right">
<p>
{{ form.From(size=30, readonly=true) }}
</p>
<p>
{{ form.To(size=30, placeholder='To') }}
</p>
<p>
{{ form.message(rows=3, cols=29, placeholder='Message') }}
</p>
<button class="btn btn-primary send_recommend">Send</button>
<button class="btn btn-default close1">Dismiss</button>
<input id="send_dummy_id" name="send_dummy_id" value="" type=hidden>
</form>
</div>
</div>
</div>
Basically my question is how can I prevent ajax from any feedback on the website? I used ajax because I do not want to reload the website after the form is submitted. Maybe ajax is the wrong tool?
thanks
fl
Prevent the default behavior on the item clicked like so:
<script type='text/javascript'>
$(".send_recommend").click(function(evt) {
evt.stopPropagation();
evt.preventDefault();
var data = $("form").serialize();
$.ajax({
url: "/send_recommend",
type: "GET",
async: true,
cache: false,
contentType: "application/json; charset=utf-8",
data: { send_dummy_id: document.getElementById("send_dummy_id").value, data: data },
});
});
</script>
$(".send_recommend").click(function(е) {
e.preventDefault();
...
});
or just end the function with return false;
Just remove the return jsonify(ret_data) line form your send_recommend() route.
#app.route('/send_recommend', methods=['GET', 'POST'])
def send_recommend():
if request.method == 'GET':
ret_data = {"data": request.args.get('data')}
#do something here
Because you are returning the JSON data back to your template.

Categories