1

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?

Nanor
  • 2,400
  • 6
  • 35
  • 66
  • Could your problem in any way related to anchors ? http://stackoverflow.com/questions/2573979/force-page-reload-with-html-anchors-html-js – Mauro Rocco Feb 01 '16 at 12:12
  • In the AJAX request where `url: "#"`? I don't think so. I changed the URL to be `/messages/` and the problem still persists in the same fashion. – Nanor Feb 01 '16 at 12:14
  • It might help to see the source of your returned ajax block (messages.html) – Mauro Rocco Feb 01 '16 at 12:17

1 Answers1

4

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) ...
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Cool, I never would have found this. I also wanted to say thanks for your help over all the questions I've been asking, Daniel. I really appreciate it. – Nanor Feb 01 '16 at 12:27