AJAX News Rotator in Sitefinity Part 3: Handling Disabled Javascript

In part 1 and part 2 of this series, I discussed how to create a simple News Rotator for Sitefinity. Everything is working great until you try to visit the page with Javascript disabled. Since we’re using link buttons that navigate through the various news items, they require the __dopostback javascript command to initiate the postback to the server and update the news content. Obviously, disabling Javascript will break our functionality.

Incidentally, this is also another reason why I decided to build my own rotator in place of the RadRotator control. Remember that this control loads all of the content as hidden, then uses Javascript to toggle the visibility of each. The control binds on the server-side, loading the content, but since Javascript is disabled, none if it is toggled as visible!

I’ve always hated this aspect of ASP.NET. I know that you can replace LinkButtons with regular buttons, ensuring that a regular postback occurs using the ‘submit’ functionality of the input element. However, I’d rather shoot for a more graceful fall-through mechanism.

Normally, the Javascript __dopostback method is embedded in the href attribute of the link, which is where the “button” in LinkButton is simulated. I’ve never understood this either. The anchor html element supports the onclick attribute, why didn’t they use that instead? This is especially annoying if, like me, you use a browser that supports ‘link dragging’ where you drag and drop a link to open it in a new window. I can’t tell you how many times I have been subject to the Your search – javascript:__doPostBack(‘blah$ctl01$blah$ctl01$blah$ctl01’,”) – did not match any documents message from google. It’s REALLY annoying…

Well, my solution was to use the OnDataBind event of my control to override the Javascript and move it from the href attribute into onclick instead. This has the additional benefit of freeing up the href attribute so that we can use that for the actual URL for the news item! This way, when Javascript is disabled, the numbered links at the bottom of the rotator will still correctly point to each individual news story, only instead of causing a postback, they will link directly to the page! Talk about compliance!

The code to do this is pretty straight-forward. All we need to do is modify the ItemDataBound event code to do some additional formatting of the LinkButtons in each bound item.

 

protected void newsNavRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)  
{  
    // get link  
    LinkButton lnk = e.Item.FindControl(“lnkItem”as LinkButton;  
 
    // get dataitem  
    IContent newsItem = e.Item.DataItem as IContent;  
    int itemIndex = e.Item.ItemIndex + 1;  
    lnk.Text = itemIndex.ToString();  
    lnk.OnClientClick = string.Format(“javascript:__doPostBack(‘{0}’,”); return false;”, lnk.ClientID.Replace(“_”“$”));  
    lnk.Attributes.Add(“href”string.Format(“/news/default{0}.aspx”, newsItem.Url));  
    lnk.CommandArgument = (itemIndex – 1).ToString();  
    lnk.ToolTip = newsItem.GetMetaData(“Title”).ToString();  
    lnk.Attributes.Add(“onMouseOver”string.Format(“window.status='{0}’;return true”, lnk.ToolTip));  
    lnk.Attributes.Add(“onMouseOut”“window.status=””);  

The biggest thing to watch out for here is the ClientID. The parameter for the __dopostback method requires an argument that represents the sender. I don’t know enough about this process to explain why, but I noticed by looking at the html source that this parameter is equivalent to the client id, replacing the underscore _ character with the dollar sign $.

Notice also that I also went ahead and included code to show helpful information in the status bar, so that users can know where the links will be taking them. Also be sure to include the return false; snippet so that when Javascript is enabled, the link is not followed (but the postback still occurs, since it now occurs in the onclick attribute!), and is followed when Javascript is disabled. Not too shabby!

So there you have it: a complete Ajax rotator with fall-through support for Javascript-disabled browsers. The only problem I’ve seen is that in IE, the href is APPENDED and not replaced (meaning the __dopostback is still present in the first href attribute, and the link is in the second), which is obviously not XHTML compliant. Strangely enough, it renders correctly in Firefox… and it does function correctly in both browsers… go figure!

I hope this has been helpful to SOMEONE out there! please feel free to send me your comments; I’d love to know how this approach can be improved!

AJAX News Rotator in Sitefinity Part 2: Adding a Timer

In my last entry (AJAX News Rotator Part I), I described how I used the NewsManager in Sitefinity to create an AJAX news rotator that dynamically fetches news content using AJAX. Using the linkbuttons in the repeater, users can jump to different items in the list. However, this isn’t exactly a “rotator”, because to me that implies some sort of automation, which sounds like a good job for the ASP.NET Timer control.