I've implemented a basic checkout wherein a user may select a shipping address from a list of addresses via the 'address' class. It works on the server side, but I would like to use AJAX to avoid having the page refresh with each selection. The code is not posting any data, however. What am I doing wrong?
views.py
def pick_address(request):
if request.method == 'POST':
checkout = Checkout.objects.get(pk=request.POST.get('checkout'))
checkout.shipping_address = ShippingAddress.objects.get(pk=request.POST.get('address'))
checkout.save()
return HttpResponse('success')
pick_address.js
<script>
$('.address').click(function () {
$.ajax({
type: 'POST',
url: '{% url 'pick-address' %}',
dataType:'json',
data: {
checkout: {{ checkout.pk }},
address: {{ address.pk }},
csrfmiddlewaretoken: '{{ csrf_token }}'
},
success: function (data) {
if (data['success']) {
alert('success!');
}
}
});
});
</script>
In views.py
def pick_address(request):
if request.method == 'POST':
checkout = Checkout.objects.get(pk=request.POST.get('checkout'))
checkout.shipping_address = ShippingAddress.objects.get(pk=request.POST.get('address'))
checkout.save()
ctx={'success':True}
return HttpResponse(json.dumps(ctx),content_type='application/json')
in pick_address.js
success: function (data) {
if (data.success) {
alert('success!');
}
}
I was using the slim version of jQuery, which does not support AJAX. The code was otherwise (mostly) correct.
Related
I am working in a Django project where one of the functionalities will be that user could search a name (using a form), the view will search that name in database (after some transformation), and the results will be displayed below the form.
At the moment, It is necesary that the entire page loads every time a search is submitted. I am working in apply ajax to make this dynamic. The problem is that when I return the search result as a JsonResponse, I am not able to see the data in the success function of ajax.
Views.py
def indexView (request):
form = FriendForm ()
friends = Friend.objects.all ()
return render (request, "index.html", {"form": form, "friends": friends})
def searchFriend(request):
if request.method =="POST":
form = FriendForm (request.POST)
if form.is_valid():
if request.is_ajax():
name = form.cleaned_data['name']
query = Friend.objects.filer(first_name__contains=name)
print(query)
return JsonResponse(list(query), safe=False)
else:
return JsonResponse(form.errors)
Main.js
$(document).ready(function() {
$("#form1").submit(function() { // catch the form's submit event
var search = $("#searchField").val();
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
method: 'post',
dataType: 'json',
url: "search/ajax/friend/",
success: function(data) { // on success..
console.log(data)
}
});
return false;
});
});
Is your query getting printed in terminal ?
Friend.objects.filer use filter instead of filer
and use type: 'post' instead of method: 'post',
and add data: $(search).serialize(), instead of data: $(this).serialize(),
I am creating a website that allows users to search for a list of papers. Once a list of papers is returned, the user can click "like" or "dislike" to one or more papers. The like count should dynamically update as the user click the like button.
I am using jquery to handle the dynamic update of the like count. However, I am not sure how to tell the success function in the ajax WHICH id to update. The reason is that the id is generated on the fly, and it is determined by which papers are returned as search results to the user.
So far, I have the following in the template:
{% for result in results %}
<li >
{{ result.title}},
<span class="like_span fa fa-thumbs-up"></span>
<strong id="like_count_{{ result.pk }}">{{result.likes}} </strong>
</li>
{% endfor %}
As you can see, i specify the id of the part where I want the dynamic update to happen as "like_count_{{ result.pk }}". I am not sure if this is the best way to go about it.
The jquery part looks like this:
<script>
$(document).ready(function(){
$(".like_button").click(function(){
$.ajax({
type: "GET",
data: {'pk': $(this).data('pid'),
'liked': $("span").hasClass('fa fa-thumbs-up') },
url: "{% url 'search:paperpreference' %}",
success: function(response) {
var pk = $(this).data('pid');
$(?????).html(response.likes )
},
error: function(response, error) {
alert(error);
}
});
});
});
</script>
Simply put, I don't know how can i specify the ????? part such that when success, the new like count is only updated to that specific paper, not the first paper in the loop.
The views.py has the following so far:
def paperpreference(request):
# if request.method == "GET":
pid = request.GET['pk']
paper = Paper.objects.get(pk=pid)
likes = paper.likes + 1
paper.likes = likes
paper.save()
data = {'likes': paper.likes}
return JsonResponse(data)
I am new to Jquery, any help would be much appreciated!
Thanks to suggestions by #dirkgroten, the like count can now be dynamically updated by the following jquery function. The trick is to move the pk declaration to before the ajax.
<script>
$(document).ready(function(){
$(".like_button").click(function(){
var pk = $(this).data('pid')
$.ajax({
type: "GET",
data: {'pk': pk,
'liked': $("span").hasClass('fa fa-thumbs-up') },
url: "{% url 'search:paperpreference' %}",
success: function(response) {
$("#like_count_"+ pk).html(response.likes )
},
error: function(response, error) {
alert(error);
}
});
});
});
</script>
another option is return the id from the server.
def paperpreference(request):
# if request.method == "GET":
pid = request.GET['pk']
paper = Paper.objects.get(pk=pid)
likes = paper.likes + 1
paper.likes = likes
paper.save()
data = {'likes': paper.likes,'pid':pid}
return JsonResponse(data)
<script>
$(document).ready(function(){
$(".like_button").click(function(){
var pk = $(this).data('pid')
$.ajax({
type: "GET",
data: {'pk': pk,
'liked': $("span").hasClass('fa fa-thumbs-up') },
url: "{% url 'search:paperpreference' %}",
success: function(response) {
$("#like_count_"+ response.pid).html(response.likes )
},
error: function(response, error) {
alert(error);
}
});
});
});
</script>
I am trying to render the template called reset_password_page.html using AJAX. I intend to send some data to this template. The problem is that page is not getting loaded. It gets loaded when I use location.href, but this cannot be used as I won't be able to send any data to the template.
function trial() {
if ("{{ verified }}" == "yes") {
document.getElementById('lbl_verify').style.display = "block";
document.getElementById('lbl_verify2').style.display = "none";
window.setTimeout(function() {
$(document).ready(function() {
$.ajax({
url: "{% url 'reset_password_page' %}",
type: "POST",
data: {
csrfmiddlewaretoken: '{{ csrf_token }}'
},
async: false,
});
});
}, 1000);
} else {
}
}
views.py
def reset_password_page(request):
return render(request,"reset_password_page.html")
Its due to the if condition used.You are comparing
if ("{{ verified }}" == "yes")
which is false.
try if ({{ verified }} == "yes") which will fetch verified value.
I'm writing Ajax code to hit the database to edit model instances. But the code is not working well. The first alert statement does work, but not the other alert statements. Code in success or error does not respond. Everything seems good. I have no idea how this happened though.
book/detail.html:
<script>
$(document).ready(function () {
$("#add").click(function() {
alert('clicked');
$.ajax({
url: '{% url "cart:add_to_cart" %}',
// handle a successful response
success: function (response) {
alert("Testing.");
("#cartButton").text("Cart" + "(" + response.quantity + ")");
},
error: function (response) {
alert('Got an error');
}
});
});
});
</script>
cart.view.py:
def add_books(request):
c = Cart.objects.get(user=request.user)
q = request.GET.get('quantity')
book_id = request.GET.get('bookID')
<some code here>
response = {
'quantity': BooksInCart.objects.filter(cart=c).aggregate(item_quantity=Sum('quantity'))['item_quantity']
}
return JsonResponse(response)
cart.urls:
app_name = 'cart'
urlpatterns = [
path('add_books/', views.add_books, name='add_to_cart')
]
If you are changing data in the database, you should be using a post-type request. Include method: 'POST' and the csrf token in your ajax call and then check for for a post-type request in your view:
if request.method == 'POST':
To set the csrf token put {% csrf_token %} in your template in order to render the token, and then user JQuery to load the token value into the data portion of the ajax call:
data = {'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()}
I am trying to incorporate a search field in a django registration form. I would like to use a bootstrap tokenfield that searches a django model for possible matches to the search string. I've been struggling with this for a couple of days now. Here is my code below.
<div class="form-inline" id="keywords_div">
{% csrf_token %}
<input type="text" name="search_text" class="form-control" id="tokenfield" placeholder="Enter keyword" style="width: 50%" />
<button type="button" id="addKeyword-btn" class="btn btn-primary">Add</button>
My JQuery code.
$(function(){
//auto complete ajax code.
$('#tokenfield').tokenfield({
autocomplete: {
//source:['red','blue','green','yellow','violet','brown','purple','black','white'],
delay: 100
},
showAutocompleteOnFocus: true,
}).keyup(function(){
alert('key pressed');
$.ajax({
url: "/user_account/auto_complete_search/",
type: 'POST',
data: {
'search_text': $('#tokenfield').val(),
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
success: function(data){
console.log(data)
},
dataType: 'text'
});
});
});
});
Django View
#This is the function that handle the auto complete search functionality.
def autocomplete_search_view(request):
if request.method == 'POST':
search_text = request.POST['search_text']
else:
search_text = ''
keywords = Keywords.objects.filter(keyword__icontains=search_text)
#data = serializers.serialize('json', keywords, fields=('keyword'))
return HttpResponse('Query completed', content_type='application/text')
user_account/urls.py
url(r'^auto_complete_search/$', autocomplete_search_view, name='autocomplete_search'),
The error from the browser.
What am I doing wrong here?
After a very long time of searching for the answer, I eventually got it right. see the code below. I'm trying to figure out how to make the dropdown menu scrollable but code below does exactly what I wanted.
$('#tokenfield').tokenfield({
autocomplete: {
source: function(request, response){
if(request.term.length >= 5){
$.ajax({
url: "/user_account/auto_complete_search/",
type: 'POST',
data: {
'search_text': request.term,
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
success: function(data){
if(data != ""){
var dataArr = [];
$.each(data, function(i, jsonObj){
dataArr[i] = jsonObj.fields.keyword;
});
response(dataArr);
}
else{
response([]);
}
},
dataType: 'json'
});
}
else{
response([]);
}
},
delay: 300,
},
showAutocompleteOnFocus: true
});
Django view.
#This is the function that handle the auto complete search functionality.
def autocomplete_search_view(request):
if request.method == 'POST':
search_text = request.POST['search_text']
else:
search_text = ''
return HttpResponse([{}], content_type='application/json')
keywords = Keywords.objects.filter(keyword__icontains=search_text)
data = serializers.serialize('json', keywords, fields=('keyword'))
return HttpResponse(data, content_type='application/json')
The HTML is still the same. Hope this helps somebody in the future.