How to correctly refresh a div using Jquery/Ajax in a Django template

17,600

The HTML returned from your test_login_url view that you call via ajax includes the h1 element in your template. In your ajax success callback, you're loading that HTML, which includes the h1, into your refresh-this-div div, but you're not deleting the old h1 element that's sitting outside the container. A quick inspection of the DOM with the developer tools on your browser should illustrate what's going on.

The easiest fix is probably to wrap the contents of your current template in a container.

Template code:

<div id="refresh-this-div">
    <h1> This is a Test Ajax Page</h1>
    {% for comment in question.comment_set.all %}
        <p class="">{{ comment.body }}</p>
    {% endfor %}
    <input id="my-text-input-id" type="text" />
    <button type="submit" class="add-comment-button">Add</button>
</div>

Jquery:

$(document).ready(function() {
    $("button.add-comment-button").click(function() {
        var com_body = $('#my-text-input-id').val();
        $.ajax({
                url: '/test_login_url',
                success: function(data) {
                    // grab the inner html of the returned div 
                    // so you don't nest a new div#refresh-this-div on every call
                    var html = $(data).filter('#refresh-this-div').html();
                    $('#refresh-this-div').html(html);
                }
        });
    });
});
Share:
17,600
Dirty Penguin
Author by

Dirty Penguin

Updated on June 25, 2022

Comments

  • Dirty Penguin
    Dirty Penguin almost 2 years

    I have tried implementing the solution here, but I can't seem to get it working correctly.

    I have a div that is populated using a loop inside a Django template. Right below that, I have a input box where I can type some text and click Submit. The Submit action should trigger a Jquery script that gets a model object from the server. This model object should then be given to the div, and the div should subsequently be 'refreshed'. The intention here is that once the div is 'refreshed', the variable accessed by the for loop would have been updated, thus displaying the additional new results.

    My template code:

    <h1> This is a Test Ajax Page</h1>
    <div id="refresh-this-div">
        {% for comment in question.comment_set.all %}
            <p class="">{{ comment.body }}</p>
        {% endfor %}
            <input id="my-text-input-id" type="text" />
            <button type="submit" class="add-comment-button">Add</button>
        </div>
    </div>
    

    My Jquery:

    <script type="text/javascript">
        $(document).ready(function() {
            $("button.add-comment-button").click(function() {
                var com_body = $('#my-text-input-id').val();
                $.ajax({
                        url: '/test_login_url',
                        success: function(data) {
                        $('#refresh-this-div').html(data);
                        }
                      });
            });
        });
    </script>
    

    My view:

    def test_login_url(request):
        question = Question.objects.get(id=1)
        com = Comment(question=question, body='This is a new Comment!')
        question.comment_set.add(com)
        return render_to_response('application/ajax_test_template.html', { 'question': question })
    

    When I click the Submit button, the div is refreshed, however the div section that was refreshed now contains a copy of the h1 tag. As I click Submit multiple times, there are additional h1 tags and comments populated.

    Here is an example of the page before clicking: before_clicking_submit

    And here is an example after clicking Submit: after_clicking_submit

    I've double checked that my implementation is as identical as possible to the solution I referenced earlier, however, I feel like I'm probably missing something simple here. What is the correct way to refresh the div with the new updated variable?