0

Short version:

After ajax call, link turns into plain text, but back to link on page refresh.

Details:

I have a notification system in place (like Stack Overflow and whatnot). The notifications are either in a dropdown subtemplate:

notification_menu_list.html

{% load display_tags %} {% load item_tags %}

<div id='notification_header'>{{ request.user|count_unread_notifications }} notification{{ request.user|count_unread_notifications|pluralize}}</div>
        <ul id='notification_box'>
          {% for notification in request.user|get_notifications|slice:"6" %}
            {% if notification.active %}
              <li class='unread notification' id='{{notification.pk}}'>{{notification.headline|safe}}</li>
            {% else %}
              <li class='read notification' id='{{notification.pk}}'>{{notification.headline|safe}}</li>
            {% endif %}
          {% endfor %}
          <li class='notification all_notifications_link'><a href='{% url "notifications" %}'>Show all</a></li>
      </ul>

or in a django-table with more details:

tables.py

class NotificationTable(tables.Table):

    tr_class = tables.BooleanColumn(
        visible=False,
        empty_values=(),
        accessor='active',
    )

    selection = tables.columns.CheckBoxColumn(
        accessor="pk",
        attrs={"th__input": {"onclick": "toggle(this)"}},
        orderable=False)

    message = tables.Column(
        accessor='body',
        verbose_name='Message')

    def render_message(self, value):
      return mark_safe(value)

    created_date = tables.DateTimeColumn()

    def render_tr_class(self, value):
        if value is False:
            return 'read'
        elif value is True:
            return 'unread'

    class Meta:
        model = Notification

They both render correctly. On the table, I can select notifications, and click 'Mark as Read' which processes the form through an ajax call and sets 'active' to False. On the dropdown, clicking a notification (which is often a link) will trigger an ajax call to mark_single_notification_as_read:

views.py:

def mark_notifications_as_read(request):
    if request.method == 'POST':
        selected_pks = request.POST.getlist('selection')
        selected_pks = [int(pk) for pk in selected_pks[0].split(',') if pk != 'on']
        Notification.objects.filter(pk__in=selected_pks).update(active=False)
    table = build_notifications_table(request).as_html()
    return HttpResponse(json.dumps(table), content_type='application/json')


def mark_single_notification_as_read(request):
    if request.method == 'POST':
        notification_id = request.POST.get('notification_id')
        Notification.objects.filter(pk=int(notification_id)).update(active=False)
        return render(request,
                      'notifications/notifications_menu_list.html',
                      {})
    else:
        print 'not post'

Either way, once the ajax completes, the links turn into plain text. If I refresh the page, they are back. I can't figure out why. Any thoughts?

EDITED:

Forgot the ajax. Why in the world would that be important?

$("#notification_container").on('click', 'li.unread', function(){
      notification_id = $(this).attr('id');
      $.ajax({
        type: 'POST',
        url: "{% url 'mark_single_notification_as_read' %}",
        data: {'notification_id' : notification_id}, 
        success: function(data){
          $('#notification_container').html(data);
        }
      });
thumbtackthief
  • 6,093
  • 10
  • 41
  • 87
  • The link changes back on reload because the original source is restored. That means that something you do during the AJAX operation replaces the links with plain text. – Jay Blanchard May 05 '14 at 19:37
  • That's what I figured... but I can't see what. Forgot to add ajax above--adding now. – thumbtackthief May 05 '14 at 20:00
  • You're overwriting everything in the #notification_container when the AJAX call is successful. Is that where these links are? – Jay Blanchard May 05 '14 at 20:04
  • Yes, but the links are the bodies of the Notification objects--stored in the database. I return them with a query – thumbtackthief May 05 '14 at 20:21
  • `mark_notifications_as_read` builds the same table (updated, obviously) as the original template does. – thumbtackthief May 05 '14 at 20:21
  • removing the `as_html` from ` table = build_notifications_table(request).as_html()` in mark_notifications_as_read fixed the problem there... still having trouble with mark_single_notification_as_read (and not sure why that fixed it) – thumbtackthief May 05 '14 at 20:26
  • And I fixed the other one by just changing the class through ajax instead of replacing the div... it's good now, but I'd still like to know why the original didn't work. – thumbtackthief May 05 '14 at 20:35
  • I'd have to see the output from the original. – Jay Blanchard May 05 '14 at 20:36

0 Answers0