ASP Alliance   .Net Code   Useful Methods
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;
    }

  }

}
csharpindex.com/colorCode
Comments