Click here to Skip to main content
15,896,726 members
Articles / Web Development / IIS

Rapid Web Application Development

Rate me:
Please Sign up or sign in to vote.
4.00/5 (5 votes)
27 Sep 200510 min read 204.1K   4.2K   86  
An article about the Multiformity Open Source project.
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using rasp.SQL;
using rasp.SQL.SQLStatement;
using rasp.SQL.DBInfo;
using rasp.HTML.Controls;

namespace rasp.HTML.PageControls
{
	/// <summary>
	/// This class will generate the databound controls needed to edit or add a record out of your database.
	/// Three are two ways to use this class, use it as a collection of the data bound controls (default usage)
	/// or request the RecordEditor property. The reason that this is seperated out is because the redord editor does incur some
	/// sorting and other types of overhead. Additionally, you can add controls to the form to be sorted before you request the
    /// RecordEditor property. Note that the recordeditor will automatically order the controls by the 
	/// tab order, but groups the controls by type and will additionally place controls on the tabs specified in the _Fields table.
    /// It displays the basic text boxes first, the textareas next, puts the dates together
	/// then he checkboxes last. It is a very nice and handy way that usually displays the controls on the webpage in
	/// a way that is both intuitave and logical.
	/// </summary>
	public class Form	: PlaceHolder {
		//TODO: Make public accessors as needed for the various private members.

		private UserInfo _UserInfo;
		private bool _SmallTextAreas = false;
		private RaspButton _SubmitButton;
		private RaspButton _SubmitAndAddAnotherButton;
		private Properties _Properties = new rasp.Properties(Constants.Paths.LocalRoot + "GridProperties.properties");
		private DataAdapter _Adapter;
		private BasePage _Container;
		private string _IDs;
		private bool _NewRecord = false;
		private EventHandler _SubmitHandler;
		private EventHandler _DeleteHandler;
		private EventHandler _CancelHandler;
		private EventHandler _ElipseHandler;
		private EventHandler _CalendarValueHandler;
		private EventHandler _CalendarShowHideHandler;
		private string _SubmitText;
		private string _UsedNames = ",";
		private PlaceHolder _RecordEditor;
		private int _Columns = 4;
		private bool _CanLoop = true;
		private Hashtable controls = new Hashtable();
		private ArrayList captions = new ArrayList();


		/// <summary>
		/// Returns the UserID of the person using the form/
		/// </summary>
		public int UserID { get { return this._UserInfo.ID; } }

		/// <summary>
		/// Note: This cannot be undone as of now, you will have to reinstantiate a new form to get large text areas again..
		/// </summary>
		public bool SmallTextAreas
		{
			set
			{
				_SmallTextAreas = value;
				//Iterate through each control in the field collection and set it's display type to default if it is 
				foreach (FieldInfo fi in TableInformation.FieldCollection)
				{
					if (fi.DisplayType == DisplayTypes.Text && _SmallTextAreas)
					{
						if (controls[fi.TableName + "_" + fi.ActualName] != null)
						{
							RaspTextBox tb = (RaspTextBox)controls[fi.TableName + "_" + fi.ActualName];
							fi.DisplayType = DisplayTypes.Default;
							controls[fi.TableName + "_" + fi.ActualName] = new RaspTextBox(fi, tb.Text, this._Container);
						}

					}
				}
			}
		}

		/// <summary>
		/// Gets the button that is the submit button for the form.
		/// </summary>
		public RaspButton SubmitButton {
			get {
				return _SubmitButton;
			}
		}
		
		/// <summary>
		/// Gets the button that is the submit button for the form.
		/// </summary>
		public RaspButton SubmitAndAddAnotherButton {
			get {
				return _SubmitAndAddAnotherButton;
			}
		}

		/// <summary>
		/// Determines if the form has a "Save and add another" button
		/// </summary>
		public bool CanLoop {
			get { return _CanLoop; }
			set { _CanLoop = value; }
		}

		/// <summary>
		/// Returns the TableInformation object from the Adapter that is passed in when the Form is constructed.
		/// </summary>
		public TableInfo TableInformation { get { return _Adapter.TableInfomation; } }

		private Literal BR { 
			get {
				Literal l = new Literal();
				l.Text = "<br><br>";
				return l;
			}
		}

		/// <summary>
		/// Logs that the field has been displayed on a form.
		/// </summary>
		/// <param name="fieldName">The name of the field that was used</param>
		public void AddField(string fieldName) {
			_UsedNames += fieldName + ",";
		}

		/// <summary>
		/// Allows you to pull the control out of the collection as a Placeholder
		/// </summary>
		public PlaceHolder this[string FieldInterface] {
			get {
				object junk = this.controls[FieldInterface];				
				PlaceHolder c = (PlaceHolder)junk;
				_UsedNames += FieldInterface + ",";
				return c;
			}
		}

		#region Constructors

		// <summary>
		/// Constructs a form using QueryString values found in the containers QueryString property.
		/// </summary>
		/// <remarks>
		/// <b>NOTE:</b> The BasePage that you pass in assumes that it was opened using querystring parameters defined in Constants.Parameters, including
		/// <ul><li>Adapter</li><li>LoopForm</li><li>ID</li></ul>
		/// </remarks>
		/// <param name="TheContainer">The BasePage that will contain the form.</param>
		public Form(BasePage TheContainer, UserInfo userinfo)	{
		
			string a = TheContainer.Request.QueryString[Constants.Parameters.Adapter];
			string strID = TheContainer.Request.QueryString[Constants.Parameters.ID];
			string parentAdapter = TextUtilities.AssignNullString(TheContainer.Request.QueryString[Constants.Parameters.ParentAdapter],"");
			strID = TextUtilities.AssignNullString(strID,"-1");
			if(!parentAdapter.Equals("")) { a += "," + parentAdapter; };						
				try {
					_CanLoop = TextUtilities.CastBoolValues(TheContainer.Request.QueryString[Constants.Parameters.LoopForm], true); 
				} catch {}
			//string editID = TheContainer
			Initialize(a, userinfo , TheContainer, strID);
		
		}

		public Form(BasePage TheContainer, NameValueCollection querystring, UserInfo userinfo)	{
			string a = querystring[Constants.Parameters.Adapter];
			string strID = querystring[Constants.Parameters.ID];
			string parentAdapter = TextUtilities.AssignNullString(querystring[Constants.Parameters.ParentAdapter],"");
			strID = TextUtilities.AssignNullString(strID,"-1");
			if(!parentAdapter.Equals("")) { a += "," + parentAdapter; };						
			try {
				_CanLoop = TextUtilities.CastBoolValues(querystring[Constants.Parameters.LoopForm], true); 
			} catch {}
			//string editID = TheContainer
			Initialize(a,userinfo, TheContainer, strID);
		
		}
		
		
		
		/// <summary>
		/// Constructs a form using the given paramaters.
		/// </summary>
		/// <param name="TheAdapter">The adapter that you wish to create the form for.</param>
		/// <param name="TheContainer">The BasePage that will contain the form.</param>
		public Form(string TheAdapter, UserInfo userinfo,  BasePage TheContainer)	{
			Initialize(TheAdapter, userinfo, TheContainer, "-1");
		}


		/// <summary>
		/// Constructs a form using the given paramaters.
		/// </summary>
		/// <param name="TheAdapter">The adapter that you wish to create the form for.</param>
		/// <param name="TheContainer">The BasePage that will contain the form.</param>
		/// <param name="ID">The ID of the row that you wish to edit.</param>
		public Form(string TheAdapter, UserInfo userinfo,  BasePage TheContainer, string IDs)	{			
			Initialize(TheAdapter, userinfo, TheContainer, IDs);
		}
		#endregion


		#region Events
		/// <summary>
		/// The handler for when the elipse button next to a RaspDropdownList is clicked
		/// </summary>
		public void DisplayTable(object sender, EventArgs e) {
			IButton b = (IButton)sender;
			string strID = b.Attributes["IDValue"];
			int ID = int.Parse(strID);
			string adapter = b.Attributes["Adapter"];
			_Container.Response.Redirect(Constants.URLS.DisplayURL + "?adapter="+adapter+"&ID="+ID);
		}
		/// <summary>
		/// The handler for when the submit button is clicked
		/// </summary>
		public void SubmitForm(object sender, System.EventArgs e) {
			if (SQLDataTransforms.InsertFormData(_Container.Request.Form)) {
				WebControl b = (WebControl)sender;
				bool IsLooping = false;
				try { IsLooping = bool.Parse(b.Attributes["addanother"]); } catch {}
				if (IsLooping) {
					if (b.Attributes["redirecturl"] != null) {
						_Container.Response.Redirect(b.Attributes["redirecturl"]);
					} else {
						_Container.Response.Redirect(LinkGenerator.NewLink(_Container.Request.QueryString[Constants.Parameters.Adapter]));
					}
				} else {
					_Container.Response.Redirect(LinkGenerator.DisplayLink(_Container.Request.QueryString[Constants.Parameters.Adapter]));
				}
			} else {
				Label error = (Label)_Container.FindControl("ErrorMessage");
				error.Text = "Update Failed! Please contact RASP Support.";
			}
		}
		/// <summary>
		/// The handler for when the cancel button is clicked.
		/// </summary>
		public void CancelForm(object sender, System.EventArgs e) {
			_Container.Response.Redirect(LinkGenerator.DisplayLink(_Container.Request.QueryString[Constants.Parameters.Adapter]));
		}
		/// <summary>
		/// The handler for when the delete button is clicked
		/// </summary>
		public void DeleteForm(object sender, EventArgs a) {
			IButton b = (IButton)sender;
			string strID = b.Attributes["IDValue"];
			int ID = int.Parse(strID);
			string strAdapter = b.Attributes["Adapter"];
			DataAdapter adapter = DataAdapterCollection.GetAdapter(strAdapter, this._Container.UserInformation);
			if (SQLUtilities.DeleteRow(adapter, ID)) {
				_Container.Response.Redirect(LinkGenerator.DisplayLink(_Container.Request.QueryString[Constants.Parameters.Adapter]));
			} else {
				Label error = (Label)_Container.FindControl("ErrorMessage");
				error.Text = "Delete Failed! Please contact RASP Support.";
			}
		}
		#endregion
		

		/// <summary>
		/// Initializes the form. All of the constructors eventually call this method
		/// </summary>
		/// <param name="TheAdapter">The Adapter that we will be adding or editing.</param>
		/// <param name="TheContainer">The webpage that will contain the form (this is required for the event handlers)</param>
		/// <param name="IDs">The optional ID for the record that we will be editing (-1 if you wish to add)</param>
		/// <param name="userinfo">The user that will be accessing the form.</param>
		private void Initialize(string TheAdapter, UserInfo userinfo,  BasePage TheContainer, string IDs) {
			if(TheAdapter.IndexOf(",") != -1) {
				foreach(string adapter in TheAdapter.Split(',')) {
					Initialize(adapter, userinfo, TheContainer, IDs);
				}

			} else {
				_Adapter = DataAdapterCollection.GetAdapter(TheAdapter, userinfo, "EditForm");
				_UserInfo = userinfo;
				_Container = TheContainer;
				_IDs = IDs;
				_SubmitHandler = new EventHandler(SubmitForm);
				_DeleteHandler = new EventHandler(DeleteForm);
				_CancelHandler = new EventHandler(CancelForm);
				_ElipseHandler = new EventHandler(DisplayTable);
			
				if (!_IDs.Equals("") && !IDs.Equals("-1")) {
					GenerateWebControls(_IDs);				
				} else {				
					GenerateWebControls();	
				}
				AddLabel();
				EnableViewState = true;
			}

		}

		#region RecordEditor

		/// <summary>
		/// This method groups the controls int appropriate arraylists and generates the 6 main portions of the RecordEditor
		/// </summary>
		/// <returns>A placeholder with the form and edit label</returns>
		private PlaceHolder GenerateRecordEditor() {

			Table TheTabs = new Table();
			TableRow TabRow = new TableRow();
			Table TheForm = new Table();
			TableRow FormRow = new TableRow();
			TableCell FormCell = new TableCell();

			TheForm.Controls.Add(FormRow);
			FormRow.Controls.Add(FormCell);

			TheTabs.Controls.Add(TabRow);

			TheTabs.BorderStyle = System.Web.UI.WebControls.BorderStyle.Double;
			TheForm.BorderStyle = System.Web.UI.WebControls.BorderStyle.Double;
			
			if(this._Adapter.TableInfomation.Tabs.Count > 1) {
				this.Controls.Add(TheTabs);
			}
			this.Controls.Add(TheForm);

			bool IsFirstTab = true;
			int i = 1;
			foreach(TabInfo ti in this._Adapter.TableInfomation.Tabs) {
				//Tab Table Stuff
        TableCell TabCell = new TableCell();
				TabRow.Controls.Add(TabCell);
        TabCell.ID = "Tab" + i.ToString();
				TabCell.BackColor = System.Drawing.Color.White;
				
				Literal TabLink = new Literal();
				TabLink.Text = "<a href=\"javascript:ShowTab('"+ i.ToString() +"')\"><img border=0 src=" + ti.Image +" />" + ti.TabLabel + "</a>";
				TabCell.Controls.Add(TabLink);

				//Form Table stuff
				Literal BeginSpan = new Literal();
				Literal EndSpan = new Literal();
        BeginSpan.Text = "<span ID=TabSpan"+ i.ToString() +" style=\"display:none;\" class=Tab>";
				EndSpan.Text = "</span>";

				if(IsFirstTab) {
					TabCell.BackColor = System.Drawing.Color.Gainsboro;
					 BeginSpan.Text = "<span ID=TabSpan"+ i.ToString() +" class=Tab>";
					IsFirstTab = false;
				}

				FormCell.Controls.Add(BeginSpan);

				#region Initialize

				ArrayList boolControls = new ArrayList();

				ArrayList textControls = new ArrayList();
			
				ArrayList stringControls = new ArrayList();

				ArrayList dateControls = new ArrayList();

				ArrayList dropdownControls = new ArrayList();

				ArrayList defaultControls = new ArrayList();
				_Adapter.TableInfomation.FieldCollection.SortBy(FieldInfoSortParameter.DisplayOrder);
				foreach(FieldInfo fi in _Adapter.TableInfomation.FieldCollection) {			 
					string name = fi.ActualName;
					if(fi.TabID == ti.TabID) {
						if(fi.IsEditable && !fi.IsHidden) {
							switch(fi.DataType) {
								case SqlDbType.Char: case SqlDbType.NChar: case SqlDbType.NText: 
								case SqlDbType.NVarChar: case SqlDbType.VarChar: case SqlDbType.Text: 
									//TODO Eventually initialize the HTML, text and XML display types differently..
									if (fi.DisplayType == DisplayTypes.Text || fi.DisplayType == DisplayTypes.HTML) {								
										textControls.Add(fi);			
									} else {
										if(fi.ActualName.EndsWith("_IDs")) {
											dropdownControls.Add(fi);
										} else {
											stringControls.Add(fi);
										}
									}						
									break;
								case SqlDbType.Bit: 
									boolControls.Add(fi);
									break;
								case SqlDbType.BigInt: case SqlDbType.Decimal: case SqlDbType.Float: case SqlDbType.Int: case SqlDbType.Money:
								case SqlDbType.Real: case SqlDbType.SmallInt:	case SqlDbType.SmallMoney: case SqlDbType.TinyInt:		
									defaultControls.Add(fi);					
									break;
								case SqlDbType.DateTime: case SqlDbType.Timestamp:
									dateControls.Add(fi);
									break;
							}					
						}	else if (!fi.IsHidden) { textControls.Add(fi); }
					}
				}

				#endregion

				FormCell.Controls.Add(GenerateStringTable(stringControls));
				FormCell.Controls.Add(GenerateTextTable(textControls));
				FormCell.Controls.Add(GenerateDateTable(dateControls));
				FormCell.Controls.Add(GenerateDefaultTable(defaultControls));
				FormCell.Controls.Add(GenerateDropDownTable(dropdownControls));
				FormCell.Controls.Add(GenerateBoolTable(boolControls));

				FormCell.Controls.Add(EndSpan);
				++i;
			}

			Controls.Add(GenerateButtonTable());
		
			return (PlaceHolder)this;
		}
		/// <summary>
		/// Returns a Placeholder that contains the Form completely sorted and with a applicable title
		/// </summary>
		public PlaceHolder RecordEditor {
			get {
				if (_Adapter.TableInfomation.IsReadOnly) {					
					_RecordEditor = (PlaceHolder)new RecordViewer(_Adapter.TableInfomation.ActualName, _UserInfo , _Container, ID, "");
				} else {
					_RecordEditor = GenerateRecordEditor();
				}
				return _RecordEditor;
			}
		}

	
		/// <summary>
		/// Generates the Checkbox section of the form.
		/// </summary>
		/// <param name="controls">An arraylist of the Boolean (checkbox) controls</param>
		/// <returns>The table with the controls</returns>
		private Table GenerateBoolTable(ArrayList controls) {
			int count=0;
			TableRow valueRow = new TableRow();
			TableRow captionRow = new TableRow();
			captionRow.Style.Add("background-color", "#E0E0E0");
			Table table = DefaultControls.EmptyTable;
			foreach(FieldInfo fi in controls) {
				TableCell valueCell = new TableCell();
				valueCell.Controls.Add(this[fi.VirtualName]);
				TableCell captionCell = new TableCell();
				captionCell.Text = fi.Caption;
				captionCell.ToolTip = fi.Description;
				if (count % 8 == 0 && count != 0 && count != controls.Count) {
					table.Controls.Add(captionRow);
					table.Controls.Add(valueRow);
					valueRow = new TableRow(); 
					captionRow = new TableRow();
					captionRow.Style.Add("background-color", "#E0E0E0");
				}
				count++;
				if (count == controls.Count) {
					int span = CalculateSpan(count, _Columns);
					valueCell.ColumnSpan = span;
					captionCell.ColumnSpan = span;
				}
				valueRow.Controls.Add(valueCell);
				captionRow.Controls.Add(captionCell);
			}
			if ( count != 0) {
				table.Controls.Add(captionRow);				
				table.Controls.Add(valueRow);	
			}

			return table;
		}


		/// <summary>
		/// Generates the Textarea section of the form.
		/// </summary>
		/// <param name="controls">An arraylist of the Textarea controls</param>
		/// <returns>The table with the controls</returns>
		private Table GenerateTextTable(ArrayList controls) {

			Table table = DefaultControls.EmptyTable;
			TableRow valueRow = new TableRow();
			TableRow captionRow = new TableRow();
			captionRow.Style.Add("background-color", "#E0E0E0");
			foreach(FieldInfo fi in controls) {

				TableCell valueCell = new TableCell();				
				valueCell.ColumnSpan = _Columns;
				valueCell.Controls.Add(this[fi.VirtualName]);

				TableCell captionCell = new TableCell();
				captionCell.Style.Add("background-color", "#E0E0E0");
				captionCell.Text = fi.Caption + "&nbsp;&nbsp;";
				captionCell.ToolTip = fi.Description;
				captionCell.ColumnSpan = _Columns;

				captionRow = new TableRow();
				captionRow.Controls.Add(captionCell);

				valueRow = new TableRow();
				valueRow.Controls.Add(valueCell);

				table.Controls.Add(captionRow);
				table.Controls.Add(valueRow);	
			}

			return table;
		}


		/// <summary>
		/// Generates the regular textbox section of the form
		/// </summary>
		/// <param name="controls">An arraylist of the plain Textbox controls</param>
		/// <returns>The table with the controls</returns>
		private Table GenerateStringTable(ArrayList controls) {
			int count=0;
			TableRow valueRow = new TableRow();
			TableRow captionRow = new TableRow();
			captionRow.Style.Add("background-color", "#E0E0E0");
			Table table = DefaultControls.EmptyTable;
			foreach(FieldInfo fi in controls) {
				TableCell valueCell = new TableCell();
				valueCell.Controls.Add(this[fi.VirtualName]);
				TableCell captionCell = new TableCell();
				captionCell.Text = fi.Caption;
				captionCell.ToolTip = fi.Description;
				if (count % _Columns == 0 && count != 0 && count != controls.Count) {
					table.Controls.Add(captionRow);
					table.Controls.Add(valueRow);
					valueRow = new TableRow(); 
					captionRow = new TableRow();
					captionRow.Style.Add("background-color", "#E0E0E0");
				}
				count++;
				if (count == controls.Count) {
					int span = CalculateSpan(count, _Columns);
					valueCell.ColumnSpan = span;
					captionCell.ColumnSpan = span;
				}
				valueRow.Controls.Add(valueCell);
				captionRow.Controls.Add(captionCell);
			}
			if (count != 0) {
				table.Controls.Add(captionRow);
				table.Controls.Add(valueRow);
			}
			return table;
		}


		/// <summary>
		/// Generates the dates section of the form
		/// </summary>
		/// <param name="controls">An arraylist of the date controls</param>
		/// <returns>The table with the controls</returns>
		private Table GenerateDateTable(ArrayList controls) {
			int count = 0;
			TableRow valueRow = new TableRow(); 
			TableRow captionRow = new TableRow();
			captionRow.Style.Add("background-color", "#E0E0E0");
			Table table = DefaultControls.EmptyTable;
			foreach(FieldInfo fi in controls) {
				TableCell valueCell = new TableCell();
				valueCell.Controls.Add(this[fi.VirtualName]);
				TableCell captionCell = new TableCell();
				captionCell.Text = fi.Caption;
				captionCell.ToolTip = fi.Description;
				if (count % _Columns == 0 && count != 0 && count != controls.Count) {
					table.Controls.Add(captionRow);
					table.Controls.Add(valueRow);
					valueRow = new TableRow(); 
					captionRow = new TableRow();
					captionRow.Style.Add("background-color", "#E0E0E0");
				}
				count++;
				if (count == controls.Count) {
					int span = CalculateSpan(count, _Columns);
					valueCell.ColumnSpan = span;
					captionCell.ColumnSpan = span;
				}
				valueRow.Controls.Add(valueCell);
				captionRow.Controls.Add(captionCell);
			}
			if (count != 0) {
				table.Controls.Add(captionRow);
				table.Controls.Add(valueRow);
			}
			return table;
		}


		/// <summary>
		/// Generates the section of the form that holds all other controls
		/// </summary>
		/// <param name="controls">An arraylist of the "other" controls</param>
		/// <returns>The table with the controls</returns>
		private Table GenerateDefaultTable(ArrayList controls) {
			
			int count = 0;
			TableRow valueRow = new TableRow(); 
			TableRow captionRow = new TableRow();
			captionRow.Style.Add("background-color", "#E0E0E0");

			Table table = DefaultControls.EmptyTable;
			foreach(FieldInfo fi in controls) {
				TableCell valueCell = new TableCell();
				valueCell.Controls.Add(this[fi.VirtualName]);
				TableCell captionCell = new TableCell();
				captionCell.Text = fi.Caption;
				captionCell.ToolTip = fi.Description;
				if (count % _Columns == 0 && count != 0 && count != controls.Count) {
					table.Controls.Add(captionRow);
					table.Controls.Add(valueRow);
					valueRow = new TableRow(); 
					captionRow = new TableRow();
					captionRow.Style.Add("background-color", "#E0E0E0");
				}
				count++;
				if (count == controls.Count) {
					int span = CalculateSpan(count, _Columns);
					valueCell.ColumnSpan = span;
					captionCell.ColumnSpan = span;
				}
				valueRow.Controls.Add(valueCell);
				captionRow.Controls.Add(captionCell);
			}
			if (count != 0) {
				table.Controls.Add(captionRow);
				table.Controls.Add(valueRow);
			}
			return table;
		}


		private Table GenerateDropDownTable(ArrayList controls) {
			
			int count = 0;
			TableRow valueRow = new TableRow(); 
			TableRow captionRow = new TableRow();
			captionRow.Style.Add("background-color", "#E0E0E0");

			Table table = DefaultControls.EmptyTable;
			foreach(FieldInfo fi in controls) {
				TableCell valueCell = new TableCell();
				valueCell.Controls.Add(this[fi.VirtualName]);
				TableCell captionCell = new TableCell();
				captionCell.Text = fi.Caption;
				captionCell.ToolTip = fi.Description;
				if (count % 2 == 0 && count != 0 && count != controls.Count) {
					table.Controls.Add(captionRow);
					table.Controls.Add(valueRow);
					valueRow = new TableRow(); 
					captionRow = new TableRow();
					captionRow.Style.Add("background-color", "#E0E0E0");
				}
				count++;
				if (count == controls.Count) {
					int span = CalculateSpan(count, _Columns);
					valueCell.ColumnSpan = span;
					captionCell.ColumnSpan = span;
				}
				valueRow.Controls.Add(valueCell);
				captionRow.Controls.Add(captionCell);
			}
			if (count != 0) {
				table.Controls.Add(captionRow);
				table.Controls.Add(valueRow);
			}
			return table;
		}

		/// <summary>
		/// Generates the button section of the form. Determines if we are adding or editing, and thus if we need a delete button or not.
		/// </summary>
		/// <returns>The table with the controls</returns>
		private Table GenerateButtonTable() {
			Table table = DefaultControls.EmptyTable;
			TableRow ButtonRow = new TableRow();
			ButtonRow.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Left;
			TableCell ButtonCell = new TableCell();
			Label l = new Label();
			l.Text = "&nbsp;&nbsp;";
			ButtonCell.Controls.Add(this[Constants.Buttons.SubmitName]);
			ButtonCell.Controls.Add(l);
			ButtonCell.Controls.Add(this[Constants.Buttons.CancelName]);
			PlaceHolder db = this[Constants.Buttons.DeleteName];
			if (db != null) {
				l = new Label();
				l.Text = "&nbsp;&nbsp;";
				ButtonCell.Controls.Add(l);
				ButtonCell.Controls.Add(db);
			}
			if (_CanLoop) {
				l = new Label();
				l.Text = "&nbsp;&nbsp;&nbsp;&nbsp;";
				ButtonCell.Controls.Add(l);
				RaspButton rb = new RaspButton(ButtonTypes.Image);
				rb.Attributes.Add("addanother","true");
				rb.Attributes.Add("redirecturl",_Container.Request.RawUrl);
				rb.Text = Constants.Images.SaveAndAdd;
				rb.ToolTip = "Save and add another row";
				rb.SetClick(_SubmitHandler);
				this._SubmitAndAddAnotherButton = rb;
				ButtonCell.Controls.Add(rb);
			}
			//TODO: Fix this as it is a security hole that may allow for passwords to be displayed as clear text in the HTML source
			// We shouldn't have to put the unused controls hidden on the page.
			ButtonCell.Controls.Add(GetUnusedControls());
			ButtonRow.Controls.Add(ButtonCell);
			table.Controls.Add(ButtonRow);
			return table;
		}


		/// <summary>
		/// Adds the label to the form controls
		/// </summary>
		private void AddLabel()
		{
			Literal l = new Literal();
			l.Text = "<h1>";
			if (_NewRecord)
			{
				l.Text += _Adapter.TableInfomation.AddCaption;
			}
			else
			{
				l.Text += _Adapter.TableInfomation.EditCaption;
			}
			l.Text += "</h1>";
			Controls.Add(l);
		}

		/// <summary>
		/// Adds the provided control to the RecordEditor object
		/// </summary>
		/// <param name="c">The webcontrol to add</param>
		public void Add(IWebControl c)
		{
			if (c.ID != null)
			{
				if (controls.Contains(c.ID))
				{
					c.ID += "_" + c.GetHashCode().ToString();
				}
				controls.Add(c.ID.Replace("_PlaceHolder", ""), c);
			}
		}
		#endregion	

		/// <summary>
		/// Calculates the span for the tablecells to be used. Hard to explain this one, just look it over and maybe it will make sense
		/// </summary>
		/// <param name="CurrentCount">The current column count</param>
		/// <param name="ColumnCount">The count of total columns</param>
		/// <returns></returns>
		private static int CalculateSpan(int CurrentCount, int ColumnCount) {
			int ret = 1 + Math.Abs((CurrentCount % ColumnCount) - ColumnCount);
			return ret;
		}

		#region ControlGenerator

		/// <summary>
		/// Generates the IWebControls for the form. Uses the supplied ID to initialize the control values.
		/// </summary>
		/// <param name="id">The ID of the record that you wish to edit.</param>
		public void GenerateWebControls(string id) {
			AddFormControls();
			Add(new RaspHidden("IDValue", id.ToString()));
			Add(new RaspHidden("Command", Constants.Commands.Update));
			if(id.IndexOf(Constants.Delimeter) == -1) {
				DataRow thisRow = SQLUtilities.GetRow(_Adapter, int.Parse(id));
				foreach(FieldInfo fi in TableInformation.FieldCollection) {
					Add(GenerateWebControl(fi, TextUtilities.GetTextValue(thisRow[fi.ActualName])));
				}
			} else {
				foreach(FieldInfo fi in TableInformation.FieldCollection) {
					if(fi.IsEditable || !fi.IsHidden) {
						Add(GenerateWebControl(fi,Constants.Settings.NewValue));
					}
				}
			}
			AddButtons();
		}
		/// <summary>
		/// Generates blank IWebControls for the form, unless default values are specified by SqlDbType, or in the appropriate FieldInfo class. 
		/// </summary>
		public void GenerateWebControls() {
			_NewRecord = true;
			Add(new RaspHidden("Command", Constants.Commands.Insert));
			AddFormControls();
			_NewRecord = true;
			foreach(FieldInfo fi in TableInformation.FieldCollection) {
				if(fi.IsEditable || !fi.IsHidden) {
					Add(GenerateWebControl(fi,Constants.Settings.NewValue));
				}
			}
			AddButtons();
		}
		
		/// <summary>
		/// Actually generates the IWebControls for the form, defaulting the control values as appropriate
		/// </summary>
		/// <param name="fi"></param>
		/// <param name="val"></param>
		/// <returns></returns>
		public IWebControl GenerateWebControl(FieldInfo fi, string val) {			
			string fieldName = fi.ActualName;			
			if (val.Equals(Constants.Settings.NewValue)) {
				if (fi.DefaultValue == null) {
					val = new SQLDataTransforms()[fi.DataType];
				} else {
					val = (string)fi.DefaultValue;
				}
			}
			//This has to be initialized, otherwize we get a "Uninitialized variable" build error
			IWebControl wc = new RaspTextBox(fi, val, this._Container);
			if (!fi.IsHidden) {				
				switch (fi.DataType) {
					case SqlDbType.Char: case SqlDbType.NChar: case SqlDbType.NText: 
					case SqlDbType.NVarChar: case SqlDbType.Text: case SqlDbType.VarChar:					
						if (fi.ActualName.EndsWith("_IDs")) {
							wc = new RaspMultiSelect(fi, val, _ElipseHandler, _Container);
							/*	} else if (fi.DisplayType = DisplayTypes.LocalFile) {
									wc = new MyLocalFileBox(fi, val);
								} else if (fi.DisplayType = DisplayTypes.LocalFile) {
									wc = new MyRemoteFileBox(fi, val);
							*/
						} else if( ! fi.ActualName.EndsWith( "_ID" ) && fi.LookupInformation != null ) {
							wc = new RaspDropDown( fi, val);
						}	else if (_SmallTextAreas && fi.DisplayType == DisplayTypes.Text) { 
							//if we want small text areas and the control is supposed to be a text area					
							//set the field info's object to be a default display type
							fi.DisplayType = DisplayTypes.Default;
							//construct the textbox with the possibly modified field info obj, cool huh, didn't need an overloaded text box constructor :D
							wc = new RaspTextBox(fi,val, this._Container);
						} else if (fi.DisplayType == DisplayTypes.URL) {
							wc = new RaspLinkEditor(fi, val, _Container);
						}
						break;	
					case SqlDbType.Bit: 
						wc = new RaspCheckBox(fi, val, _Container);
						break;
					case SqlDbType.BigInt: case SqlDbType.Decimal: case SqlDbType.Float: case SqlDbType.Int: case SqlDbType.Money:
					case SqlDbType.Real: case SqlDbType.SmallInt:	case SqlDbType.SmallMoney: case SqlDbType.TinyInt:		
						// If we have a foriegn Key
						if (fi.ActualName.EndsWith("_ID") || fi.LookupInformation != null) {
							wc = new RaspDropDown(fi, val);
						} else {
							wc = new RaspTextBox(fi, val, this._Container);
						}						
						break;
					case SqlDbType.DateTime: case SqlDbType.Timestamp:
						wc =  new RaspCalendar(fi, val);
						break;
				}
			}
			return wc;
		}
		/// <summary>
		/// Adds in the hidden info required to update the data later.
		/// </summary>
		public void AddFormControls() {
			Add(new RaspHidden("Adapter", TableInformation.ActualName));
		}
		/// <summary>
		/// Generates the appropriate Submit, Delete and Cancel buttons
		/// </summary>
		public void AddButtons() {
			
			//Update button
			RaspButton ub = new RaspButton(ButtonTypes.Image);
			_SubmitButton = ub;
			ub.SetClick(_SubmitHandler);
			ub.ToolTip = "Save";
			ub.Text = "/images/save.gif";
			ub.ID = rasp.Constants.Buttons.SubmitName;
			Add((IWebControl)ub);

			// Cancel button
			RaspButton cb = new RaspButton(ButtonTypes.Image);
			cb.SetClick(_CancelHandler);
			cb.Text = "/images/cancel.gif";
			cb.ToolTip = rasp.Constants.Buttons.CancelText;
			cb.ID = Constants.Buttons.CancelName;
			cb.CausesValidation = false;
			Add((IWebControl)cb);

			// Delete button, only when editing, not adding
			if(!_NewRecord) {
				Add((IWebControl)CreateDeleteButton(_IDs, TableInformation, _DeleteHandler));
			}
		}
	
		/// <summary>
		/// Creates a basic elipse button
		/// </summary>
		/// <returns>A new button with three dots on it.</returns>
		public static Button CreateElipseButton(){
			Button b = new Button();
			b.Text = "..";
			return b;
		}

		/// <summary>
		/// Creates a Delete button for the form.
		/// </summary>
		/// <param name="id">The record ID</param>
		/// <param name="ti">The TableInfomation object for the adapter that we are editing</param>
		/// <param name="eh">The Eventhandlers object to grab the Delete Handler</param>
		/// <returns>A Button wired up with the correct events and javascript confirmations</returns>
		/// <remarks>
		/// This also adds an onclick attribute to the button to do a Javascript Confirm.
		/// </remarks>
		public static RaspButton CreateDeleteButton(string id, TableInfo ti, EventHandler eh) {
			// Delete button
			RaspButton db = new RaspButton(ButtonTypes.Image);
			db.SetClick(eh);
			db.ToolTip = Constants.Buttons.DeleteText;
			db.Text = "/images/delete.gif";
			db.ID = Constants.Buttons.DeleteName;
			db.CausesValidation = false;
			db.Attributes.Add("IDValue",id);
			db.Attributes.Add("Adapter",ti.ActualName);
			db.Attributes.Add("onClick","return confirm(\"Are you sure you wish to delete this record?\");");
			return db;
		}
		

		#endregion

		//These methods are rarely used, but needed by AddField.aspx.cs, I think that we can eventually rid ourselves of the populatePage methods.
		//We do use the getunused controls methods, and they are required to be there so that things work right.

		#region PlaceHolder Population		


		/// <summary>
		/// Hides the unused controls onto a placeholder and returns it.
		/// </summary>
		/// <returns>A placeholder with the unused controls.</returns>
		public PlaceHolder GetUnusedControls() {
			return GetUnusedControls(new PlaceHolder());
		}
		/// <summary>
		/// Hides the unused controls onto the provided placeholder and returns it.
		/// </summary>
		/// <param name="p">A placeholder to put the controls onto.</param>
		/// <returns>A placeholder with the unused controls.</returns>
		public PlaceHolder GetUnusedControls(PlaceHolder p) {
			foreach(string key in controls.Keys) {
				if (_UsedNames.IndexOf("," + key + ",") == -1) {
					p.Controls.Add(((IWebControl)this[key]).Hide());
				}
			}
			return p;
		}
		/// <summary>
		/// Populates the provided placeholder with the controls from the given adapter. Defaults the column count to 4.
		/// </summary>
		/// <param name="p">A placeholder to put the controls onto.</param>
		/// <param name="adapter">A DataAdapter to get the controls for.</param>
		public void PopulatePage(PlaceHolder p, DataAdapter adapter) {
			PopulatePage(p,4, adapter);
		}
		/// <summary>
		/// Populates the provided placeholder with the controls from the given adapter. Defaults the column count to 4.
		/// </summary>
		/// <param name="p">A placeholder to put the controls onto.</param>
		/// <param name="cols">The number of columns to put in the page.</param>
		/// <param name="adapter">A DataAdapter to get the controls for.</param>
		public void PopulatePage(PlaceHolder p, int cols, DataAdapter adapter) {
			//This is only used in the case when you need to make special forms like the add field, where it is actually 
			//doing two things at once, IE adding a row to _FIELDS and Creating the field in the DB
			Table table = new System.Web.UI.WebControls.Table();
			table.BorderWidth = 1;
			TableRow captionrow = new System.Web.UI.WebControls.TableRow();
			TableRow controlrow = new System.Web.UI.WebControls.TableRow();
			controlrow.BorderStyle = System.Web.UI.WebControls.BorderStyle.Solid;
			controlrow.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Left;
			captionrow.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Left;
			controlrow.VerticalAlign = System.Web.UI.WebControls.VerticalAlign.Top;
			captionrow.VerticalAlign = System.Web.UI.WebControls.VerticalAlign.Top;
			int i = 1;
			adapter.TableInfomation.FieldCollection.SortBy(SQL.DBInfo.FieldInfoSortParameter.DisplayOrder);
			foreach(FieldInfo fi in adapter.TableInfomation.FieldCollection) {
				if (!fi.IsHidden) {
					TableCell captioncell = new System.Web.UI.WebControls.TableCell();
					TableCell controlcell = new System.Web.UI.WebControls.TableCell();
					try {
						captioncell.Text = fi.Caption;
						captioncell.BackColor = System.Drawing.Color.FromName((string)_Properties["HeaderColor"]);
						controlcell.Controls.Add(this[fi.VirtualName]);
					} catch {
						//throw new Exception("Input collection does not contain field: " + fi.ActualName+ ", named: " + fi.Caption);
					}
					captionrow.Controls.Add(captioncell);
					controlrow.Controls.Add(controlcell);
					if (i % cols == 0) {
						table.Controls.Add(captionrow);
						table.Controls.Add(controlrow);				
						captionrow = new System.Web.UI.WebControls.TableRow();
						controlrow = new System.Web.UI.WebControls.TableRow();
						controlrow.BorderStyle = System.Web.UI.WebControls.BorderStyle.Solid;
						controlrow.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Left;
						captionrow.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Left;
						controlrow.VerticalAlign = System.Web.UI.WebControls.VerticalAlign.Top;
						captionrow.VerticalAlign = System.Web.UI.WebControls.VerticalAlign.Top;
					}
					++i;
				} else {
					((IWebControl)this[fi.ActualName]).Hide();
				}				
			}
			table.Controls.Add(captionrow);
			table.Controls.Add(controlrow);

			TableRow tr = new TableRow();
			TableCell tc = new TableCell();
			tc.ColumnSpan = cols;
			Label l = new Label();
			l.Text = "&nbsp;&nbsp;";
			tc.Controls.Add(this[Constants.Buttons.SubmitName]);
			tc.Controls.Add(l);
			tc.Controls.Add(this[Constants.Buttons.CancelName]);
			PlaceHolder db = this[Constants.Buttons.DeleteName];
			if (db != null) {
				l = new Label();
				l.Text = "&nbsp;&nbsp;";
				tc.Controls.Add(l);
				tc.Controls.Add(db);
			}
			tr.Controls.Add(tc);
			table.Controls.Add(tr);
			p.Controls.Add(table);
			GetUnusedControls(p);
		}


		#endregion
		
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions