Test out Notifications with Boostrap and jQuery

By Samuel Muiruri | Dec. 20, 2018 | Javascript


This is a simple webpage in Bootstrap that will use Javascript Promise to mimick a delayed request from the server and into the notification tab on bootstrap.

So with no backend you should be able to see the notifications come in one at a time and here’s how it’s done. Full code available on github as notification.html.

Starting with the html, here’s the full text

<!DOCTYPE html>
<html>
<head>
 <title>Notifications</title>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
 <link rel="stylesheet" type="text/css" href="css/notification.css">
<script type="text/javascript" src="js/jquery-3.3.1.slim.min.js"></script>
 <script type="text/javascript" src="js/popper.min.js"></script>
 <script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/notification.js"></script>
</head>
<body>
 <!-- Image and text -->
 <nav class="navbar navbar-light">
   <a class="navbar-brand" href="#">
     <img src="img/bootstrap-solid.svg" width="30" height="30" class="d-inline-block align-top" alt="">
     Bootstrap
   </a>
<ul class="navbar-nav lock">
    <li class="nav-item dropdown">
         <a class="nav-link dropdown-toggle" href="#" id="notification-link" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
           Notifications <span class="badge badge-secondary" id="notification-count">0</span>
         </a>
         <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
          <ul class="navbar-nav ul-padding" id="notification-ul">
           <li class="border-bottom padding-bottom"><strong>Message from X:</strong> First Day of the Week, make sure to...</li>
           <li class="border-bottom padding-bottom">Enjoy your Holiday</li>
           <li class="border-bottom padding-bottom">Things looking ok from the report...</li>
          </ul>
         </div>
      </li>
   </ul>
 </nav>
</body>
</html>

This has just the bootstrap’s css & js and the navigation on the body. On view you’ll get a page like this.

The css is mainly for making the nav items behave and stand out more.

.navbar {
 background-color: #0006;
}
.lock {
 position: absolute;
 right: 50px;
 top: 15px;
 width: 190px;
}
.ul-padding {
 padding: 5px;
}
.padding-bottom {
 padding-bottom: 5px;
}
.new-item {
 background-color: #0ff3;
}

And finally the JS

function delayed_response(delay, data) {
 var promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
   resolve(data);
  }, delay);
 });
return promise
}

This creates a promise that has a delay period that is specified on creation plus a message it will return once it’s complete, like a countdown timer.

That message is later on passed to update_notifications which gets the message and updates the page so the notification counter is incremented by 1 and appends the message to the dropdown item.

function update_notification(message) {
 var notifications = parseInt( $('#notification-count').text() ) + 1;
 $('#notification-count').text(notifications);
var has_class = $('#notification-count').hasClass('badge-secondary');
if (has_class) {
  $('#notification-count').removeClass('badge-secondary').addClass('badge-primary');
 }
var new_item = '<li class="border-bottom padding-bottom new-item">' + message + "</li>";
 $('#notification-ul').prepend(new_item);
}

Since the Notification’s number should default back to 0 on preview “Even if the individual messages still are marked as unread” this snippet of code does this.

$('#notification-link').click(event => {
  $('#notification-count').text(0).removeClass('badge-primary').addClass('badge-secondary');
 });

And since the .new-item li are added dynamically to the page with javascript the .click doesn’t work on this and needs to be rewritten to this.

$('#notification-ul').on('click', '.new-item', function() {
  $(this).removeClass('new-item');
 });

And finally there’s the promises created that end up as received messages on the page.

//first item
 delayed_response(2000, 'Welcome Back, long time no see!').then( data => {
  update_notification(data);
 })
 .catch( err => {
  console.log(err);
 });
//second item
 delayed_response(8000, 'Dude, did you see this!').then( data => {
  update_notification(data);
 })
 .catch( err => {
  console.log(err);
 });
//third item
 delayed_response(16000, 'Wow, this video blew my mind!').then( data => {
  update_notification(data);
 })
 .catch( err => {
  console.log(err);
 });

So after: 2, 8 and 16 seconds respectively these messages will be added to the notification counter.