On our web platform, when you get sent a ‘U2U’ message, whether it’s from a colleague, or notification of a phone message, you get a little flashing envelope icon in the toolbar. Clicking on this takes you to your inbox. All of this is pretty much as you’d expect. The count of unread messages is done at page load (well.. taken from memcached anyway) and the button is generated then.
The snag with this is, if you’re expecting a message it can turn you into a bit of a refresh-monkey, reloading the page until you see the unread messages icon.
So we have a page that looks like this:
and we need to make that U2U alert a bit more…………. ‘realtime’. Fortunately it’s pretty easy with a little bit of AJAX magic.
First of all we need to make the button have an identifiable <div> so all we do when rendering the button in the Page_Load is do this: <span class="u2ubutton"></span>
Next, we simply create an ASPX page that returns the inner HTML for the button, which obviously depends on the number of messages. To do that we simply have an ASPX that goes a little like this:
response.clearcontent response.cachecontrol = "no-cache" response.write MessageCount & " U2Us"
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Obviously it’s a bit more complex than that as you only want to display the envelope icon if there’s an unread message, but I’ll spare you the boring part.
Once that’s done it’s a matter of polling that page. In time, I’ll convert it to “Long Polling” for higher efficiency and better response time, but for now, a simple javascript timer will suffice. To poll the button content page, and update the content we can use a single line of JQuery called from a timer:
<script type="text/javascript"> $(document).ready(function() { GetNewU2Us() }); function GetNewU2Us() { $(".u2ubutton").load("<%=request.applicationpath%>/returnu2ubuttoncontent.aspx") window.setTimeout(function() { GetNewU2Us() }, 10000); } </script>
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
The initial page load calls GetNewU2Us which updates the div with the class ‘u2ubutton’ with the HTML that’s spat out by our button page. It then starts a timer off so the event will happen every 10 seconds.
So far so good then, our message alert now works nicely in the background and updates every 10 seconds.
If you’re not currently viewing that page though you might not see it. If you’ve used the Twitter web page recently you may have spotted a nice new addition. If more tweets come in, it updates the page title to ‘(3) Twitter / Home’ signifying there are 3 unread tweets. You can see that number in your browser tab, so even if you’re doing something else you can see at a glance you have new messages.
Replicating this with our solution is a doddle. In our returnu2ubuttoncontent.aspx page we just insert a bit of Javascript after the button text:
If MessageCount > 0 Then ButtonText += "<script language=""JavaScript"">" & vbCrLf ButtonText += "var leftchar = document.title.substring(0, 1)" & vbCrLf ButtonText += "if (leftchar == '(')" & vbCrLf ButtonText += "{" & vbCrLf ButtonText += "var oldtitle = document.title" & vbCrLf ButtonText += "var rhb = oldtitle.indexOf("") "")" & vbCrLf ButtonText += "oldtitle = oldtitle.substring(rhb + 1)" & vbCrLf ButtonText += "document.title = '(" & MessageCount & ") ' + oldtitle" & vbCrLf ButtonText += "}" & vbCrLf ButtonText += "else" & vbCrLf ButtonText += "{" & vbCrLf ButtonText += "document.title = '(" & MessageCount & ") ' + document.title" & vbCrLf ButtonText += "}" & vbCrLf ButtonText += "</script>" & vbCrLf Else ButtonText += "<script language=""JavaScript"">" & vbCrLf ButtonText += "var leftchar = document.title.substring(0, 1)" & vbCrLf ButtonText += "if (leftchar == '(')" & vbCrLf ButtonText += "{" & vbCrLf ButtonText += "var oldtitle = document.title" & vbCrLf ButtonText += "var rhb = oldtitle.indexOf("") "")" & vbCrLf ButtonText += "oldtitle = oldtitle.substring(rhb + 1)" & vbCrLf ButtonText += "document.title = oldtitle" & vbCrLf ButtonText += "}" & vbCrLf ButtonText += "</script>" & vbCrLf End If
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Apologies for not just pasting in the resultant javascript, but you can see what it does. If there’s an unread message, if inserts the top blob which strips a ‘(xx)’ from the title if there’s already one and then adds the new count. If the message count is 0 it just strips the (xx) if it exists. Not pretty but it works!
So after that bit of work, we’re left with:
Obviously the background polling and the nice magic updating aren’t apparent in a screenshot, but the end result is super slick…!!
makes perfect sense to me