29 Oct 2009

Dynamic Linq OrderBy - Sort Field known only at Run-Time

A common issue with my LinqToSql stuff is the need to do an OrderBy on an IQueryable a la:
myQueryable = myQueryable.OrderBy(item => item.mySortField)

However, often you won't know the sort field until runtime, e.g. for a dynamically sortable grid.

One solution is to use the DynamicQueryable library provided by MS. It lets you do string-based dynamic querying like so:
myQueryable = myQueryable.OrderBy(mySortFieldName + " ASC"); // or use DESC if you like it in descending order

However this didn't have an option for using an IComparer to sort the results, and I wanted to use my NaturalSortComparer for natural case sorting. The solution I came up with was this:
myQueryable = myQueryable.OrderBy(item => item.GetReflectedPropertyValue(mySortFieldName ));

Or, actually employing NaturalSortComparer, like this:
myQueryable = myQueryable.OrderBy(item => item.GetReflectedPropertyValue(mySortFieldName ), new NaturalSortComparer<string>());

The solution uses a little helper method called GetReflectedPropertyValue():

public static string GetReflectedPropertyValue(this object subject, string field)
{
object reflectedValue = subject.GetType().GetProperty(field).GetValue(subject, null);
return reflectedValue != null ? reflectedValue.ToString() : "";
}

OK, Reflection is slow (not sure how it compares to building a Lambda Expression tho) but it does the job for my purposes.

28 Oct 2009

AjaxControlToolkit Accessible Tabs

Can't believe it but MS forgot to make Tabs in the Ajax Control Toolkit accessible via the keyboard. Okay, they provide an access key property, but what about just being able to tab to the tab (ho ho) and press enter to open?

My solution is a snippet of JQuery to iterate through all the tabs and update the HeaderText of the TabPanel, turning it into a fake Html Anchor. Works fine in FF3 and IE6+ so I'm happy.

$('.ajax__tab_tab').each(function() { if ($(this).html().indexOf('<a') < 0)
$(this).html('<a href="" onclick="return false;">' + $(this).html() + '</a>'); });

If you want to hide the 'linkiness' of the updated headertext, just add a style directive to your CSS like so:

.ajax__tab_tab a { text-decoration: none; font-weight: normal; }

Probs? Let me know.

15 Oct 2009

JQuery and setting checkbox to checked except disabled ones....

Got a master checkbox that you want to control the toggling of a bunch of other checkboxes in a container (but only non-disabled ones)? Want to use JQuery to make it SUPER EASY?

$('#chkMasterCheckbox').click(function(event) {
$('#divContainer input[type=checkbox]:enabled').attr('checked', $(this).attr('checked'));
});


Oh yeah baby.
If I helped you out today, you can buy me a beer below. Cheers!