Textboxes Timers and Updatepanels

In a project I'm working on, I had to create a Facebook style notification system. I wanted the user to be able to enter a status and click the add button and have the list of notifications below it update with their most recent post. That is simple enough to do, all I had to do was to add the notification, clear the textbox then call the updateNotifications function in my button_click code behind method. This all had to be very smooth to the eye so i added the usual updatepanel around the textbox, button and div that listed the notifications.

As well as that, I also wanted the notifications system to automatically update with other users notifications within the same group. So I added a Time control to the mix and set it to refresh the notifications list every 10 seconds.

This seemed to work well until I was half way through typing a new notification when the timer triggered and refreshed the notification list. As the textbox was inside the updatepanel it stopped letting me type any text while it refreshed.

So then I thought that I’d move the textbox outside the updatepanel so it wasn’t impacted when the timer refreshed the list.

The only problem now is that because the submit button to add a new notification was inside the updatepanel and the textbox was outside the updatepanel the textbox could no longer be cleared on the partial postback. My txtNotification.Text = String.Empty; was being ignored.

I can’t quite remember the next thing I tried but it obviously didn’t work because now the whole page was refreshing everytime the timer triggered.

In the end I remembered about the UpdateMode property on the update panel. I set the updatemode to conditional around my textbox/button updatepanel and always on the notification list/timer updatepanel. That way the timer triggers updated the notification list without upsetting the textbox and submitting the add button updated the list and cleared the textbox. Perfect result.

ASPX code:

<asp:UpdatePanel ID="updStatusUpdate" runat="server" UpdateMode="Conditional">
        <asp:TextBox ID="txtStatusUpdate" runat="server" TextMode="MultiLine" Rows="2" Width="570">asp:TextBox> <br />        

        <asp:Button ID="btnAddStatusUpdate" runat="server" Text="Update Status" 
            onclick="btnAddStatusUpdate_Click" class="ui-state-default ui-corner-all"/>


<asp:UpdatePanel ID="updNotifications" runat="server" UpdateMode="Always">
        <div class="NotificationList">
            <asp:Literal ID="litNotifications" runat="server">asp:Literal>
        <asp:Timer ID="Timer1" runat="server" ontick="Timer1_Tick" Interval="10000">asp:Timer>

A function to convert a TimeSpan to an x minutes ago string

An application I’m working on requires a facebook style status system and I thought it would be good to include the “posted x minutes ago” text after the status.

I’m sure my code is not the most elegant solution but it works so I thought I’d share.

public static String LastUpdatedText(DateTime DateNow, DateTime LastUpdated)
            TimeSpan timeDiff = DateNow.Subtract(LastUpdated);

            if (timeDiff.TotalHours < 1)
                return Math.Round(timeDiff.TotalMinutes,0) + " minutes ago";

            if (timeDiff.TotalHours < 24)
                return Math.Round(timeDiff.TotalHours, 0) + " hours ago";

            if (timeDiff.TotalHours < 48)
                return "yesterday";

            if (timeDiff.TotalHours < 168)
                return Math.Round(timeDiff.TotalDays,0) + " days ago";

            if (timeDiff.TotalDays < 42)
                return Math.Round((timeDiff.TotalDays / 7),0) + " weeks ago";

            if (timeDiff.TotalDays < 365)
                return Math.Round((timeDiff.TotalDays / 30),0) + " months ago";

            return Math.Round((timeDiff.TotalDays / 365),0) + " years ago";

Telerik ASP.NET MVC controls and jQuery

For those who are using the Telerik controls for MVC you will most likely have the following somewhere on your page or Master page

This will create issues if you then try to add any jQuery to the page including jQuery plugins.

To get around this, you can append a method to the Telerik ScriptRegistrar to disable the jQuery reference. You need to change it to

And your page should be happy again.

Getting random records from a table using LINQ to SQL

I needed to get a number of random records from a table and a quick google search led me to http://mosesyap.com/BlogWeb/post/2008/07/C-Getting-a-Random-Record-from-a-Table-inside-the-SQL-Server-Database.aspx This is a very quick and easy mechanism to use and will work on any table. To load a specific number of random records change the .First() function
DataContext db = new QuoteDataContext();
var quote = db.Quote.OrderBy(q => db.GetNewId()).First();
to be .Take(x)
DataContext db = new QuoteDataContext();
var quote = db.Quote.OrderBy(q => db.GetNewId()).Take(x);
replacing x with however many records you need.

ASP.NET testing shortcut

I often find when developing an ASP.NET application that I want to set a number of variables when the application loads to make testing easier. I usually have a number of variables set in the Session_Start section of the global.asax.vb or in the Page_Load of the default.aspx page. This is a quick and easy way of setting things like the currently logged in user or other settings. The problem with doing this is that if you forget to comment out or remove these entries prior to uploading the site live you can run into some rather large problems. If found an excellent function in the Request.URL class that can help avoid this issue. The function is called IsLoopback. If you wrap  “If Request.URL.IsLoopback” around your variable setting code, it will only be run when you are running your code from within Visual Studio or from IIS using the http://localhostURL. Example:
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
     ' Fires when the session is started      Session(SessionVariables.UserID) = 1      Session(SessionVariables.CustomerID) = 2 End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
     ' Fires when the session is started
     If Request.URL.IsLoopback Then
          Session(SessionVariables.UserID) = 1
          Session(SessionVariables.CustomerID) = 2
     End If
End Sub
As you can see from the code, if you forget to remove or comment out this code when you upload it to your web server, the code will skip right over setting these variables. I would only recommend this type of variable setting in the initial development/testing phase and it should be removed once your application is put live.