Nanor
Nanor

Reputation: 2550

Javascript stops working after two HTML injects

I'm creating a chat function for my site. It has the conversation to the left and a list of users on the right. When a user's div is clicked, their ID is sent to the Django back end, full HTML is returned, I call $('html').html('') and then call $('html').html(data') where data is the full, returned HTML as rendered by Django.

When I click a user once, the entire page is refreshed and I'm able to perform all JS related things as expected. When I reload the page once more, the HTML is reloaded with the returned HTML but JS functionality ceases completely. When I inspect the elements in the developer tools, the JS files are all there and loaded in the sources tab.

The JavaScript looks like so:

$(document).ready(function(){

    console.log("******LOAD*********")
    var d = $('div.profile-detail');
    d.scrollTop(d.prop("scrollHeight"));

    $('div.message-text').click(function(e){
        var id = $(this).attr('id');

        $.ajax({
        url: '#',
        method: 'GET',
        data: {'id': id,
                'task': 'get_messages'},
        dataType: 'html',
        success: function(data){
            $('html').html('');
            $('html').html(data);
            $('div.section-img').attr('id', id)
        },
        error: function(){
            console.log("Oh no!");
        }
        })

    })


    $('#message-text').keypress(function(e){
        if(e.which == 13 && !e.shiftKey){
            e.preventDefault();
            $.ajax({
                url: '#',
                method: 'GET',
                data: {'message': $('#message-text').val(),
                        'task': 'post-message',
                        'id': $('div.section-img').attr('id')
                },
                success: function(){
                    $('div.profile-section4').before(
                        '<div class="profile-section2">' +
                        '<p><span class="date-span">'+ new Date().toLocaleString() +'</span><br/><br/>' +
                            $('#message-text').val() +
                        '</p>'
                    ),
                    $('#message-text').val('')
                    d.scrollTop(d.prop("scrollHeight"));
                },
                error: function(){
                    console.log("failure");
                }
            })
        }

    });

})

My view for Django looks like this:

def view_messages(request):
    messages = Message.objects.filter(message_to=request.user, job_id=None).distinct('message_from')
    contact_user_ids = messages.values_list('message_from', flat=True).distinct()

    contacts = User.objects.filter(id__in=contact_user_ids)

    messages = Message.objects.filter(
        Q(message_to=request.user) & Q(message_from_id=contact_user_ids[0]) & Q(job_id=None) | Q(
            message_to=contact_user_ids[0]) & Q(
            message_from_id=request.user) & Q(job_id=None)).order_by('time_date')

    for message in messages:
        if message.message_from == request.user:
            message.sender = True
    try:
        current_chat_user = User.objects.get(id=contact_user_ids[0])
    except:
        current_chat_user = User.objects.get(id=int(request.GET['id']))

    if request.is_ajax():
        if request.method == 'GET':
            if request.GET['task'] == 'get_messages':
                messages = Message.objects.filter(
                    Q(message_to=request.user) & Q(message_from_id=int(request.GET['id'])) & Q(job_id=None) | Q(
                        message_to=int(request.GET['id'])) & Q(
                        message_from_id=request.user) & Q(job_id=None)).order_by('time_date')

                current_chat_user = User.objects.get(id=request.GET['id'])
            else:
                m = Message(message_from=request.user, message_to_id=int(request.GET['id']), message=request.GET['message'])
                m.save()

    return render(request, 'freelancestudent/general/messages.html', {'messages': messages,
                                                                      'messages_from': contacts,
                                                                      'current_chat_user': current_chat_user})

Here is a DiffCheck of the HTML between initial page load and first AJAX request. Then here is a DiffCheck between the first AJAX request and the final one before things stop working. You'll notice nothing changes between the first request and the second request yet things stop working for some reason. Why?

Upvotes: 1

Views: 61

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599600

You're using the old-style jQuery event hooks, which are evaluated at page ready time and which refer to specific DOM elements. But those DOM elements are replaced by your reload, and so the event is no longer bound to anything.

Instead you should use the new-style delegated events:

$('html').on('click', 'div.message-text', function(e) ...

Upvotes: 4

Related Questions