using
System;
using System.Collections;
namespace olson.code.multisort
{
/// <summary>
/// Summary description for MultiOptions.
/// Adds ability to sort multiple columns,
moving columns to the left in the order
/// in which they are sorted. The
data is sorted first by the left most column, then
/// by the second to the left and so
on. Columns can be sorted in an a ascending or
/// decending order and can be removed from
sort ordering.
/// </summary>
public class MultiOptions
{
private
Hashtable htFields;
private int
col;
private string
direction;
private string
ListStart;
private int[]
iListStart;
private int[]
iDListStart;
private int[]
list;
/// <summary>
/// Sets up the items that need to
be tracked.
/// </summary>
public
MultiOptions(System.Web.HttpRequest
Request)
{
//original column
number
col
= (Request.QueryString["c"]
!= null)
? Convert.ToInt32(Request.QueryString["c"])
: 0;
//sort direction 0 is
ascending, 1 is decending
direction
= (Request.QueryString["d"]
!= null)
? Request.QueryString["d"]
: "0";
//list of which
columns start the grid and the direction in which they are sorted
ListStart
= (Request.QueryString["ls"]
!= null)
? Request.QueryString["ls"]
: string.Empty;
if
(Request.QueryString["c"]
!= null)
//if nothing has been clicked, skip
{
//if
column is not already in ListStart, add it (first click)
if
(ListStart.IndexOf(col.ToString()
+ ":")
< 0)
{
//if
ListStart is empty, just add Column index otherwise add separator and index
if
(ListStart.Length
== 0)
ListStart =
col.ToString()
+ ":"
+ direction;
else
ListStart +=
"|" +
col.ToString()
+ ":"
+ direction;
}
else
{
if
(Request.QueryString["x"]
== null)
{
//modify
sort direction in ListStart
ListStart
= ModifyDirection(ListStart,
col.ToString(),
direction);
}
else
//x link has been clicked
{
//remove
column from ListStart
ListStart
= RemoveColumn(ListStart,
col.ToString());
}
}
string[]
arrListStart =
ListStart.Split('|');
iListStart
= new int[arrListStart.Length];
//column array
iDListStart
= new int[arrListStart.Length];
//sort direction array
//fill
columns and sort direction arrays
for
(int
i=0;
i<arrListStart.Length;
i++)
{
if
(ListStart.Length
> 0)
{
string[]
arrItem =
arrListStart[i].Split(':');
iListStart[i]
= Convert.ToInt32(arrItem[0]);
iDListStart[i]
= Convert.ToInt32(arrItem[1]);
}
}
}
}
/// <summary>
/// Changes the direction of the
column that is clicked on.
/// </summary>
/// <param
name="inStr">ListStart string</param>
/// <param
name="item">column that is clicked on</param>
/// <param
name="d">direction the column will be sorted</param>
/// <returns>modified
ListStart string</returns>
private string
ModifyDirection(string
inStr,
string item, string
d)
{
string[]
arrStr =
inStr.Split('|');
string
str = string.Empty;
for
(int i=0;
i<arrStr.Length;
i++)
{
string[]
arrItem =
arrStr[i].Split(':');
if
(arrItem[0].Equals(item))
{
if
(i
== 0)
str = arrItem[0]
+ ":"
+ d;
else
str +=
"|" +
arrItem[0]
+ ":"
+ d;
}
else
{
if
(i
== 0)
str = arrStr[i];
else
str +=
"|" +
arrStr[i];
}
}
return
str;
}
/// <summary>
/// Takes a column out of the list
of columns that have a particular sort order
/// </summary>
/// <param
name="inStr">ListStart string</param>
/// <param
name="item">column that will be removed from the sort
order</param>
/// <returns>modified
ListStart string</returns>
private string
RemoveColumn(string
inStr,
string item)
{
string[]
arrStr =
inStr.Split('|');
string
str = string.Empty;
int
cnt = 0;
for
(int i=0;
i<arrStr.Length;
i++)
{
string[]
arrItem =
arrStr[i].Split(':');
if
(!arrItem[0].Equals(item))
{
if
(cnt
== 0)
str = arrStr[i];
else
str +=
"|" +
arrStr[i];
cnt++;
}
}
return
str;
}
/// <summary>
/// Enumerates the order and
direction in which the columns will be sorted.
/// </summary>
public string
GetSortExpression()
{
string
sdir = (iListStart
!= null)
? (iDListStart[0]
== 0)
? " ASC"
: " DESC"
: string.Empty;
string
SortExpression = (iListStart
!= null)
? htFields[iListStart[0]].ToString()
+ sdir : string.Empty;
if
(iListStart !=
null)
{
for
(int
i=1;
i<iListStart.Length;
i++)
{
sdir
= (iDListStart[i]
== 0)
? " ASC"
: " DESC";
SortExpression
+= ","
+ htFields[iListStart[i]].ToString()
+ sdir;
}
}
return
SortExpression;
}
/// <summary>
/// Creates a hashtable that
matches the field name with its column number
/// and a list of column numbers
that is ordered by the ListStart order.
/// </summary>
/// <param
name="fields">list of field names</param>
public void
SetFields(string[]
fields)
{
int
FieldsCnt = fields.Length;
list
= new int[FieldsCnt];
htFields
= new Hashtable();
for
(int i=0;
i<FieldsCnt;
i++)
{
htFields.Add(i,
fields[i]);
list[i]
= i;
}
if
(iListStart !=
null)
list = Shuffle();
}
/// <summary>
/// Gets the original column
number.
/// </summary>
/// <param
name="i">current column number</param>
/// <returns>original column
number</returns>
public int
GetIndex(int
i)
{
return
list[i];
}
/// <summary>
/// Gets the link text that
appears in the column headers
/// </summary>
/// <param
name="i">original column number</param>
/// <param
name="field">column field name</param>
/// <returns>Header
Text</returns>
public string
GetHeaderText(int
i, string
field)
{
string
remove = (ListStart.IndexOf(i.ToString()
+ ":")
> -1)
?
" <a href=\""multisort.aspx?c="+i+"&x=r&ls="+ListStart+""\">x</a>"
: string.Empty;
return
"<a href=\""multisort.aspx?c="+i+"&d="+GetDirection(i)+"&ls="+ListStart+""\">"+field+"</a>"
+ remove;
}
/// <summary>
/// Gets the sort direction based
on the column that is clicked and
/// the ListStart values.
/// </summary>
/// <param
name="i">original column number</param>
/// <returns>direction in
which column will be sorted</returns>
private string
GetDirection(int
i)
{
string
dir = direction;
if
(iListStart !=
null)
{
if
(Contains(iListStart,
col))
{
if
(i
== col) //This
is the column clicked on
{
dir
= (direction.Equals("0"))
? "1"
: "0";
}
else
//not clicked on, but a ListStart column
{
for
(int
ils=0;
ils<iListStart.Length;
ils++)
{
if
(iListStart[ils]
== i)
{
dir
= (iDListStart[ils]
== 0)
? "1"
: "0";
break;
}
}
}
}
else
//not a ListStart column
{
dir
= "0";
}
}
return
dir;
}
/// <summary>
/// Get a list that is reordered
putting liststart items first.
/// </summary>
private int[]
Shuffle()
{
int[]
temp =
new int[list.Length];
for
(int i=0;
i<iListStart.Length;
i++)
{
temp[i]
= iListStart[i];
}
int
cnt = iListStart.Length;
for
(int i=0;
i<list.Length;
i++)
{
if
(!Contains(iListStart,
list[i]))
{
temp[cnt]
= list[i];
cnt++;
}
}
return
temp;
}
/// <summary>
/// Checks if items is in the list
/// </summary>
/// <param
name="bag">list of items</param>
/// <param
name="item">item being checked</param>
/// <returns>true if item is
in the list, false if not in list</returns>
private bool
Contains(int[]
bag, int
item)
{
foreach
(int i
in bag)
{
if
(i ==
item) return true;
}
return false;
}
}
}
|