Wednesday, September 28, 2005
Blogs.genesissys.com is a custom blogging engine, built in house to be both easy to use, and more importantly, easy to integrate into the newly redesigned GenesisSys.com website. As such, each required component of a "standard" blog engine had to be recreated, including the ubiquitous blog post calendar.
I'm consistently amazed by Ajax technologies, and by the people who seamlessly and integrate it into everyday use. Naturally, there are the obnoxious examples, but the truly remarkable samples are the ones that are nearly transparent. In setting out to add the calendar to the Genesis Blogs, I wanted the Ajax to be completely un-noticeable.
What WAS noticeable, was the stupid postback that the standard ASP.NET calendar control produces in order to switch months. This obviously has steered us in the past towards other calendar controls, with a Javascript/DHTML implementation.
For this project however, I didn't want to use the Javascript calendars for two major reasons. First, if we start to get TONS of blog entries, I don't want to have to worry about pre-selecting those dates for the entire set of entries. I'd love to only have to worry about the month I'm displaying. And secondly, what FUN is that?! Ha.
Consequently, I set out to develop a more Ajax-esque solution, and as it turns out, with just a little effort one can easily modify Ajaxify the ASP.NET calendar.
In essence, my idea was to have the page make an Ajax request for the Calendar's HTML, and would replace a div's innerHTML with the rendered calendar. Clicking "Next Month" would make another call, requesting the code-behind to render the next month, etc, etc.
We start with a method to get the calendar's html. This is the function that the Javascript will call.
<AjaxMethod()> _
Public Function GetCalendar(ByVal m As Integer, ByVal year As Integer) As String
Inside of this function, we simply need to create a calendar, render it to a string, and return the string.
Dim c As New Calendar
c.TodaysDate = month & "/1/" & year 'display the requested month...
Dim s As New StringBuilder
Dim sw As New StringWriter(s)
Dim tw As New HtmlTextWriter(sw)
c.RenderControl(tw)
tw.Close()
sw.Close()
Return s.ToString
We then call this function from the html with the following call:
function GetCal(month, year)
{
var divCalendar = document.getElementById('divCalendar');
var res = TestPage.GetCalendar(month, year);
if(res.error == null)
{
divCalendar.innerHTML = res.value;
}
else
{
alert('Error: ' + res.error);
}
}
At this point, calling GetCal(1,2005) for example, will cause the server side to generate a new Calendar control, and then render it to a string and return that string. The javascript at that point takes the string and replaces the content of the DIV with the resultant html.
The next major hurdle is to get the month navigation wired up. This can be accomplished by simply making the Next & Prev month buttons be Javascript calls to GetCal(), passing the next and previous months, respectively.
c.NextMonthText = "<a href=""javascript:GetCal(" & IIf(m = 12, 1, m + 1) & _
"," & IIf(m = 12, year + 1, year) & ");"">></a>"
c.PrevMonthText = "<a href=""javascript:GetCal(" & IIf(m = 1, 12, m - 1) & _
"," & IIf(m = 1, year - 1, year) & ");""><</a>"
Viola! A simple Ajax calendar! All that remains to do is to style the calendar appropriately, and to mark any special dates, and both of these things have been outlined elsewhere.
Dusty Davidson
Lead Software Developer