Recommended hosting
Oct 06 2006

Download grouping repeater solution

Posted by admin under Controls

This is part 6of this tutorial on how to create a expandable/collapsible grouping repeater control with ASP.NET. So, please start by reading part 1. 

Now lets look a little depper at the GroupingHelper class.



public class GroupingHelper
{
	public GroupingHelper()
	{
		//
		// TODO: Add constructor logic here
		//
	}

    public DataTable SetupGroupedTable(DataTable dt, string sGroupCol)
    {

        dt.Columns.Add(new DataColumn("poorman_type", System.Type.GetType("System.String")));
        foreach (DataRow row in dt.Rows)
            row["poorman_type"] = "item";

        if (sGroupCol.Length == 0)
            return dt;

        string sLastGroupColValue = "-";
        DataTable dt2 = dt.Clone();
        dt2.Clear();
        foreach (DataRow row in dt.Rows)
        {
            //Should be create a header?
            if (sGroupCol != "None" && row[sGroupCol].ToString() != sLastGroupColValue)
            {
                //Yes
                DataRow rowNew = dt2.NewRow();
                rowNew["poorman_type"] = "groupheader";
                rowNew[sGroupCol] = row[sGroupCol];
                dt2.Rows.Add(rowNew);
            }
            if (sGroupCol != "None")
                sLastGroupColValue = row[sGroupCol].ToString();
            dt2.ImportRow(row);
        }
        return dt2;
    }

    public string MinusImage = "";
    public string PlusImage = "";
    public void SetImageSwapper(string sMinus, string sPlus)
    {
        MinusImage = sMinus;
        PlusImage = sPlus;
    }
    public void AddGroup(string sClientID, string sImageID)
    {
        GroupRows.Add(new JSGroupItem(this, sClientID, sImageID));
    }
    public JSGroupItem CurrentGroupItem
    {
        get
        {
            return GroupRows[GroupRows.Count - 1];
        }
    }
    public string GetJS()
    {
        string JS = "<script type=\"text/javascript\">" + Environment.NewLine;
        foreach (JSGroupItem oItem in GroupRows)
        {
            JS += oItem.GetJS();
        }
        JS += "</script>";
        return JS;
    }
    public System.Collections.Generic.List<JSGroupItem> GroupRows = new List<JSGroupItem>();
}


The SetupGroupedTable function modifies the datatable by adding a special column  (poorman_type - set to groupheader or item) - and by adding extra rows to it for each groupheader.

The class also holds a collection of JSGroupItem - those will come in handy for creating the Javascripts needed. Cause each JSGroupItem contains a list of ClientRows 

public System.Collections.Generic.List<string> ClientRows = new List<string>();

which are all clientrow id:s for the specific header row.

So, back to ASPX file - rptOrder_ItemDataBound:

Since we can retreive the ClientID (i.e the id the control will have in the resulting HTML page - which is needed to have in order to generated javascripts correctly) for each control we can (in the case of an group header item) add header rows id and its associated image client id to the grouping helpers collection:

Image oImage = e.Item.FindControl("idImage") as Image; m_oGroupingHelper.AddGroup(rowHeader.ClientID, oImage.ClientID);

This will make the helper class being able to generate a correct "poorman_changeimage" call whenever clicked.

Please just download the code and put a breakpoint in default.aspx Button1_Click and rptOrder_ItemDataBound. Now step on and you'll see how it's done. Remember - the kind of HTML/Javascript code we are trying to produce is:



  <script type="text/javascript">

function poorman_toggle(id)
{
	var tr = document.getElementById(id);
	if (tr==null) { return; }
	var bExpand = tr.style.display == '';
	tr.style.display = (bExpand ? 'none' : '');
}
function poorman_changeimage(id, sMinus, sPlus)
{
	var img = document.getElementById(id);
	if (img!=null)
	{
	    var bExpand = img.src.indexOf(sPlus) >= 0;
		if (!bExpand)
			img.src = sPlus;
		else
			img.src = sMinus;
	}
}

function Toggle_rptOrder_ctl01_rowGroupHeader()
{
poorman_changeimage('rptOrder_ctl01_idImage','images/minus.gif','images/plus.gif');
poorman_toggle('rptOrder_ctl02_rowItem');
poorman_toggle('rptOrder_ctl03_rowItem');
poorman_toggle('rptOrder_ctl04_rowItem');
poorman_toggle('rptOrder_ctl05_rowItem');
poorman_toggle('rptOrder_ctl06_rowItem');
poorman_toggle('rptOrder_ctl07_rowItem');
}
function Toggle_rptOrder_ctl08_rowGroupHeader()
{
poorman_changeimage('rptOrder_ctl08_idImage','images/minus.gif','images/plus.gif');
poorman_toggle('rptOrder_ctl09_rowItem');
poorman_toggle('rptOrder_ctl10_rowItem');
poorman_toggle('rptOrder_ctl11_rowItem');
poorman_toggle('rptOrder_ctl12_rowItem');
}

</script>

        <table id="table2" class="treetable">
            <tr>
              <th>Group</th>
              <th>Orderid</th>
              <th>Orderdate</th>
              <th>RequiredDate</th>
            </tr>
            
    
        <tr id="rptOrder_ctl01_rowGroupHeader">
	<td colspan="4"><span id="rptOrder_ctl01_idClickable" onclick="javascript:Toggle_rptOrder_ctl01_rowGroupHeader();"><img id="rptOrder_ctl01_idImage" class="button" src="images/minus.gif" style="height:16px;width:16px;border-width:0px;" /><span id="rptOrder_ctl01_lblGroupName" style="font-weight:bold;">ALFKI</span></span></td>
</tr>

    
    
        
    <tr id="rptOrder_ctl02_rowItem">
	<td>&nbsp;&nbsp;ALFKI</td>
	<td class="number">10643</td>
	<td class="number">1997-08-25 00:00:00</td>
	<td class="number">1997-09-22 00:00:00</td>
</tr>

    
        
    <tr id="rptOrder_ctl03_rowItem">
	<td>&nbsp;&nbsp;ALFKI</td>
	<td class="number">10692</td>
	<td class="number">1997-10-03 00:00:00</td>
	<td class="number">1997-10-31 00:00:00</td>
</tr>

    
        
    <tr id="rptOrder_ctl04_rowItem">
	<td>&nbsp;&nbsp;ALFKI</td>
	<td class="number">10702</td>
	<td class="number">1997-10-13 00:00:00</td>
	<td class="number">1997-11-24 00:00:00</td>
</tr>

    
        
    <tr id="rptOrder_ctl05_rowItem">
	<td>&nbsp;&nbsp;ALFKI</td>
	<td class="number">10835</td>
	<td class="number">1998-01-15 00:00:00</td>
	<td class="number">1998-02-12 00:00:00</td>
</tr>

    
        
    <tr id="rptOrder_ctl06_rowItem">
	<td>&nbsp;&nbsp;ALFKI</td>
	<td class="number">10952</td>
	<td class="number">1998-03-16 00:00:00</td>
	<td class="number">1998-04-27 00:00:00</td>
</tr>

    
        
    <tr id="rptOrder_ctl07_rowItem">
	<td>&nbsp;&nbsp;ALFKI</td>
	<td class="number">11011</td>
	<td class="number">1998-04-09 00:00:00</td>
	<td class="number">1998-05-07 00:00:00</td>
</tr>

    
        <tr id="rptOrder_ctl08_rowGroupHeader">
	<td colspan="4"><span id="rptOrder_ctl08_idClickable" onclick="javascript:Toggle_rptOrder_ctl08_rowGroupHeader();"><img id="rptOrder_ctl08_idImage" class="button" src="images/minus.gif" style="height:16px;width:16px;border-width:0px;" /><span id="rptOrder_ctl08_lblGroupName" style="font-weight:bold;">ANATR</span></span></td>
</tr>

    
    
        
    <tr id="rptOrder_ctl09_rowItem">
	<td>&nbsp;&nbsp;ANATR</td>
	<td class="number">10926</td>
	<td class="number">1998-03-04 00:00:00</td>
	<td class="number">1998-04-01 00:00:00</td>
</tr>
...
...
...

 Good luck - and please contact me if you develop it further!

 

 

Attachments