viviwill
viviwill

Reputation: 1573

Use AJAX to update django if-else template

In template I have:

{% for item in items %}
    {% if item.public is True%}
    <a href="{% url 'motifapp:article_public_edit' article.id %}">
      show icon1
    </a>
    {% else %}
    <a href="{% url 'motifapp:article_public_edit' article.id %}">
      show icon2
    </a>
    {% endif %}
{endfor}

I use ajax to handle the request here:

$(anchor).click(function(e){
        e.preventDefault();
        var href = $(this).attr('href')
        $.ajax({
            type: 'POST',
            url: href,
            data: {csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),},
            success: function (response) {
               //refresh a div ? 
            }
        });
    });

Ajax handle the post, and in view it reverse a boolean value 'public'. Question is, how do I update the template? I can pass the opposite icons and value, but it seems very redundant. Is there a way just to refresh that div with anchor and let the if else statement takes care of what's showing ?

Thanks

Upvotes: 0

Views: 2026

Answers (2)

dentemm
dentemm

Reputation: 6379

With ajax calls there is no way the Django template tags will be re-evaluated. They only get evaluated on initial page load.

I think the best way to go is to have the ajax view return the boolean value and then set the image in your front-end code depending on that value.

Upvotes: 1

nik_m
nik_m

Reputation: 12086

You are 99% close to answer your own question.

First, you you must wrap the {% for %} in a div and save it as a separate file, say:

<!-- injection.html -->

<div id="some-id>
    {% for item in items %}
        same code here
    {% endfor %}
</div>

Now in your main template you should include that file like this:

<div id="wrapper">
    {% include 'templates/injection.html' %}
</div>

Now, once you make an AJAX request to your views function then this view should render that div (which is a separate html file) but with a different items value. Like this:

# views.py

def article_public_edit(request, id):
    if request.is_ajax():
        # new calculation of the items QuerySet
        # depending on the data passed through the $.ajax
        return render(request, 'injection.html', locals())

Finally, you can do this inside the $.ajax() success function:

$.ajax({
    type: 'POST',
    url: href,
    data: {csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),},
    success: function (response) {
         // replace the inside of #wrapper div with the injection.html (that has the new items values)
         $("#wrapper").replaceWith(response);
    }
});

Upvotes: 4

Related Questions