Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

if notification count is zero I want what I have right now(box) but if it's not zero I want box to be changed to badge with notification count

I have a notification system that works. Right now, when there's no notification or not, the notification appears in a <span class='glyphicon glyphicon-inbox' aria-hidden="true"></span> just like stackoverflow. but my desire is when there's a notification, I want the box to be turned into a

<span class="badge badge-notify" style="red">notification count</span> 

again just like a stack overflow.

So I tried removing a particular class that changes the form of the box when if count == 0 and adding the class when count is not zero. I tried setting set interval as well but it just won't work.

Can you please help me?

below is what I have in navbar, I have the notification box and the badge set up.

   <li class="dropdown">
 <a href="#" class="dropdown-toggle notification-toggle" data-toggle="dropdown" role="button" aria-expanded="false" id="button">
<span class='glyphicon glyphicon-inbox' aria-hidden="true"></span>
<span class="caret"></span> 
<span class="badge badge-notify">notification count</span></a>
    <ul class="dropdown-menu" role="menu" id='notification_dropdown'>

              </ul>
            </li>

below is my ajax function to disply notification

 <script>
    $(document).ready(function(){
      $(".notification-toggle").click(function(e){
        e.preventDefault();
        $.ajax({
          type: "POST",
          url: "{% url 'get_notifications_ajax' %}",
          data: {
            csrfmiddlewaretoken: "{{ csrf_token }}",
          },
         success: function(data){
            $("#notification_dropdown").html(' <li role="presentation" class="dropdown-header">alarm</li>');
            var count = data.count
            console.log(count)
            if (count == 0) {
                  $("#notification_dropdown").removeClass('notification');
              var url = '{% url "notifications_all" %}'
              $("#notification_dropdown").append("<li><a href='" + url+ "'>view all</a></li>")
            } else {
                  $("#notification_dropdown").addClass('notification');
              $(data.notifications).each(function(){
                var link = this;
                $("#notification_dropdown").append("<li>" + link + "</li>")
              })
            }
            console.log(data.notifications);
          },
          error: function(rs, e) {
            console.log(rs);
            console.log(e);
          }
        })
      })
    })
    </script>

so what I kinda tried was this,

        <style>
          {% block style %}
    #notification_dropdown{
    }

    #notification_dropdown.notification{
      color: red;
    }


        {% endblock %}
          </style>

and 

    <script>
setTimeout(function(){
   $("#notification_dropdown:visible").addClass('notification');
}, 2000);
    </script>

maybe I set the id wrong...those did nothing unfortunately.

not sure if this is needed, I'll also add function for notification(ajax)

def get_notifications_ajax(request):
    if request.is_ajax() and request.method == "POST":
        notifications = Notification.objects.all_for_user(MyProfile.objects.get(user=request.user)).recent()
        count = notifications.count()
        notes = []
        for note in notifications:
            notes.append(note.get_link.encode('utf-8'))
        data = {
            "notifications": notes,
            "count": count,
        }
        print data
        json_data = json.dumps(data)
        print json_data
        return HttpResponse(json_data, content_type='application/json')
    else:
        raise Http404

So my question)

1) what did I do wrong that the form/color of notification box didn't change when notification is not zero, and how do I achieve what I want which is box to be turned into a

<span class="badge badge-notify" style="red">notification count</span> 

2) I'm able to display count of notification in console with console.log(count), how do I display this count in the navbar?

like image 464
mike braa Avatar asked Apr 17 '16 06:04

mike braa


1 Answers

It looks like all the changes you are doing in AJAX success are on #notification_dropdown but in your navbar HTML the <span> elements you want to toggle are never touched. It's the same in your CSS:

    <style>
      {% block style %}
#notification_dropdown{
}

#notification_dropdown.notification{
  color: red;
}


    {% endblock %}
      </style>

The CSS selectors used (#notification_dropdown) do not apply the CSS properties to the <span> elements which matter.

One of the ways to fix this -

Change your navbar HTML to:

 <li class="dropdown">
 <a href="#" class="dropdown-toggle notification-toggle" data-toggle="dropdown" role="button" aria-expanded="false" id="button">
<span id="no_notify" class='glyphicon glyphicon-inbox' aria-hidden="true"></span>
<span class="caret"></span> 
<span id="notify_count" class="badge badge-notify">notification count</span></a>
    <ul class="dropdown-menu" role="menu" id='notification_dropdown'>

              </ul>
            </li>

Change: added id attribute to both no notify and notify count badge span elements.

And

Change your Ajax script to:

 <script>
    $(document).ready(function(){
      $(".notification-toggle").click(function(e){
        e.preventDefault();
        $.ajax({
          type: "POST",
          url: "{% url 'get_notifications_ajax' %}",
          data: {
            csrfmiddlewaretoken: "{{ csrf_token }}",
          },
         success: function(data){
            $("#notification_dropdown").html(' <li role="presentation" class="dropdown-header">alarm</li>');
            var count = data.count
            console.log(count)

            if (count == 0) {
                  $("#notify_count").html(count).hide();
                  $("#no_notify").show();

                  $("#notification_dropdown").removeClass('notification');
              var url = '{% url "notifications_all" %}'
              $("#notification_dropdown").append("<li><a href='" + url+ "'>view all</a></li>")
            } else {
              $("#no_notify").hide();
              $("#notify_count").html(count).show();

                  $("#notification_dropdown").addClass('notification');
              $(data.notifications).each(function(){
                var link = this;
                $("#notification_dropdown").append("<li>" + link + "</li>")
              })
            }
            console.log(data.notifications);
          },
          error: function(rs, e) {
            console.log(rs);
            console.log(e);
          }
        })
      })
    })
    </script>

Change: added $("#no_notify") and $("#notify_count") related lines to show()/hide() those spans based on count

And change your setTimeout to:

 <script>
   setTimeout(function(){
        $(".notification-toggle").click();
   }, 2000);
 </script>

$(".notification-toggle").click(); triggers a click on <a> in navbar, which does the Ajax call. If the count from Ajax response is zero we hide notify_count span and show no_notify else do the reverse.

Triggering a click on the <a> tag seems like a good idea. If in future you want the count update to happen only on user action (a click on anchor tag) and do not want the call to happen periodically all you have to do is get rid of setTimeout logic.

It is a best practice to add an error callback too for your AJAX call, just in case if the POST call to get_notifications_ajax fails.

like image 175
LearnerEarner Avatar answered Sep 28 '22 09:09

LearnerEarner