Friday, February 29, 2008

GroupingCollection to group mails on Date and Subject

Here is a sample I wrote using GC to group mails according to Date and Subject very similar to Outlook. This sample serves to show the complex ways in which GC can be configures and used.

Subject grouping: The sample uses GroupingField.groupingFunction and GroupingField.compareFunction to achive the Subject grouping even when subject line text is prefixed with RE:, FW: etc. Grouping.groupingObjectFunction is used to supply a custom grouping object MailGroup which has a date field getter function to return the maximum date of the child mail items.

Date grouping: Again groupingFunction is used to form diffrent groups of mails based on the date value.

The "show unread mails" option can be used to remove the read mails from the view. This shows filtering applied to the HierarchicalCollectionView which ADG creates internally when a GroupingCollection (or anything which implements IHierarchicalData) is supplied as the dataProvider.

The "highlight unread mails" option uses the ADG.styleFunction property to hightlight the unread mails by making them bold.

The source is available here

Please note I have a tweak in the sample to keep it ever-green, that is the date values of the mail items are generated at runtime than hard coded.

12 comments:

Vijay Mareddy said...

I found a bug in the above example

Step 1: Select the checkbox 'Show only unread mails'
Step 2: Click on "Group by Subject"

"Show only unread mails" will not work unless you reset the grouping with the check box turned OFF

ImwatIm said...

Hi Sreenivas,

Nice post.I have one doubt regarding the above implementation.How can you sort at the grouped level also,along with the normal sorting when you expand all the nodes? To make my point clear how can you sort the grouped entities like Yesterday,Today,Three days back etc. in the first column when these grouped entities are in the collapsed state.

I hope i made myself clear.

Regards,
Shishir.

Sreenivas said...

Sorting them is controled by the compareFunction supplied to the GroupingField.

ImwatIm said...

Hi Sreenivas,

Hey thanks for the reply.Actually i realised after understanding your solution that i had put a wrong question.The actual question is : When you group in AdvancedDataGrid,i am not able to sort the column at the grouped level by simply clicking the tree column header .But if i collapse the nodes then the sorting works.How can the header-click kind of sorting be achieved for the grouped objects in the tree column?

Thanks,
Shishir.

Vijay Mareddy said...

Shishir,

http://bugs.adobe.com/jira/browse/FLEXDMV-1467

By default, treeColumn.dataField = 'GroupLabel' therfore the dataGrid.sortHandler doesnt know which column u clicked on!
The following will fix ur sort issue

if(_grouping.fields && _grouping.fields.length > 0) {
_grouping.label = (_grouping.fields[0] as GroupingField).name;
} else {
/** treeColumn wont sort and treeColumn.Tooltip will be [object,object] in this case*/
_grouping.label = 'GroupLabel';
}

Niko said...

HI thanks for sharing , I was wondering if you could helpme.

I've tried this:

public static function formDateGroup(value:Object, field:GroupingField):String
{
var today:Date=new Date();
var itemDate:Date=new Date(value.valueDate.toString());
var diff:Number=today.time - itemDate.time;
if (diff < weekDuration)
{

if (itemDate.date - 1 == today.date)
return "Tomorrow";

if (itemDate.date == today.date)
return "Today";
if (itemDate.date + 1 == today.date)
return "Yesterday";
//we do not go before Monday.
if (itemDate.getDay())
return weekDayLabels[itemDate.getDay()];
return "Last week";
}
else if (diff < twoWeekDuration)
{
return "Last week";
}
else if (diff < threeWeekDuration)
{
return "Two weeks ago";
}
else if (diff < fourWeekDuration)
{
return "Three weeks ago";
}
return "Older";
}

but the groups are in the wrong order.
Todays date is the 18/09/09

I'm getting:

Wednesday 16/09/09,
Tomorrow 19/09/09,
Tuesday 15/09/09

where I would like

Tomorrow 19/09/09,
Wednesday 16/09/09,
Tuesday 15/09/09


Thanks for any advice

Sreenivas said...

Have you fixed your compare function to address your changes.

Niko said...

Opps thanks very much, I updated the compare function.

This function would be even better if it knew that dates before Sunday were last week and could distinguish between months like 2 or 3 months ago. keep up the good work dude friend :)

Sreenivas said...

I think that logic can be added by using the Date.day API.

Niko said...

Ok I'll do it and post here my result

Niko said...

here is the function

public static function formValueDateGroup(value:Object, field:GroupingField):String
{
var today:Date=new Date();
var itemDate:Date=new Date(value.valueDate.toString());
var diff:Number=today.time - itemDate.time;

var yearDiff:int = today.getFullYear() - itemDate.getFullYear();
if ( yearDiff != 0)//cater for year(s) difference
return yearDiff == 1?'Last year':yearDiff + ' years ago' ;

var monthDiff:int = today.month - itemDate.month;
if ( monthDiff != 0)//cater for month(s) difference
return monthDiff == 1?'Last month ago':monthDiff + ' months ago' ;

else if (diff < twoWeekDuration)
{
return "Last week";
}
else if (diff < threeWeekDuration)
{
return "Two weeks ago";
}
else if (diff < fourWeekDuration)
{
return "Three weeks ago";
}
if (diff < weekDuration)
{
if (itemDate.date == today.date)
return "Today";
if (itemDate.date + 1 == today.date)
return "Yesterday";
//we do not go before Monday.
if (itemDate.getDay() < today.getDay())
return 'Last ' + weekDayLabels[itemDate.getDay()];
return "Last week";
}



return "Something is wrong";//shouldn't ever get there since we take into account years
}

criticpapa said...

whoa!!!, you had a passion in blogging, thumbs up for your work of love.. Hehe very inspiring ideas,


anyway I'm william
mind if I put a link back to you?


(clickable) ------> Suit