hbp
hbp

Reputation: 15

Why is my Django jQuery button not working?

I am very new to jQuery and trying to make a simple app which allows people to like photos using Ajax call. Here are the relevant parts:

photo.html:

{% if pic %}

<img class="pic" src="/static/assets/{{pic}}" />
<br />

{% csrf_token %}
<input type="button" id="like" name="like" value="Like" />

<p id="likes"> </p> people liked this
{% endif %}

views.py

def like_photo(request, pic_id):
    if request.method == 'POST':
        if pic_id:
            uid = request.user.id
            p=UserPic.objects.get(id=pic_id)

            if Liker.objects.filter(user=uid, pic=pic_id):

                p.likes -=1
                p.save()
                Liker.objects.filter(user= uid, pic=pic_id).delete()
            else:

                p.likes +=1
                p.save()
                newliker = Liker(user= uid, pic=pic_id)
                newliker.save()
            args = {}
            args.update(csrf(request))
            args['likes']= p.likes
        return render_to_response('photo.html', args)

like.js

$(function(){

    $('#like').click(function() {
        var $this = $(this);
        var post_id = this.id;
        $.ajax({
            type: "POST",
            url: "'/photo/like/'+ post_id",
            data: { 
                'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
            },
            success: likeSuccess,
            dataType: 'html'
        });

    });

});

function likeSuccess(data, textStatus, jqXHR)
{
    $('#likes').html(data);
}

I can see in Firebug that jQuery and like.js are loaded on the page but clicking the like button does not have any effect according to Firebug's XHR.

The app works perfectly fine without AJAX call, that is, when I use a simple anchor in the template:

<p><a href="/photo/like/{{pic.id}}">Like</a></p>

Upvotes: 0

Views: 366

Answers (2)

hbp
hbp

Reputation: 15

Ok I manged to get in work like this:

photo.html:

{% if pic %}


<script>
$(document).ready(function(){

    $('#like').click(function() {

        var $this = $(this);
        var post_id = {{pic.id}};

        $.ajax({
            type: "POST",
            url: "/photo/like/" + post_id ,
            data: { 
        'pic_id': post_id,
                'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
            },
            success: likeSuccess,
            dataType: 'html'    
        });            
    });    
});

function likeSuccess(data, textStatus, jqXHR)
{     
    $('#likes').html(data);
}

</script>

<img class="pic" src="/static/assets/{{pic}}" />
<br />

{% csrf_token %}
<input type="button" id="like" name="like" value="Like" />

<p id="likes"> {{pic.likes}} &nbsp;liked this </p>

{% endif %}

views.py

def like_photo(request, pic_id):
    if request.method == 'POST':
        if pic_id:
            uid = request.user.id
            p=UserPic.objects.get(id=pic_id)

            #if UserPic.objects.filter(liked_by__user__contains=uid):
            if Liker.objects.filter(user=uid, pic=pic_id):
                #return HttpResponse('You have already liked!')

                p.likes -=1
                p.save()
                Liker.objects.filter(user= uid, pic=pic_id).delete()
            else:

                p.likes +=1
                p.save()
                newliker = Liker(user= uid, pic=pic_id)
                newliker.save()

            args = {}
            args.update(csrf(request))
            args['likes'] = p.likes

        return render_to_response('userpics/likes.html', args)

also needed to create a specific html for ajax call:

likes.html

{% if likes > 0 %}
{{likes}} liked this
{% else %}
crap
{% endif %}  

Not sure if it is the best way but it works. I wish I could use a more elegant json to return the likes digit and get rid of the likes.html but could not figure out how to do so.

Also, for some strange reason the script does not work when I import it externally at base.html:

<script src="{% static "assets/js/likes.js" %}"></script>

though firebug says that it is loaded on the page.

Your suggestions to improve the answer are welcomed.

Upvotes: 0

roo2
roo2

Reputation: 6071

there was a small (but significant!) bug in your code

"'/photo/like/'+ post_id" is incorrect, you want "/photo/like/" + post_id. notice it isn't all surrounded by quotes

Upvotes: 1

Related Questions