Click here to Skip to main content
15,892,537 members
Articles / Web Development / IIS

OverLibWrapper -- C# wrapper of the overLIB DHTML popup JavaScript library

Rate me:
Please Sign up or sign in to vote.
4.67/5 (12 votes)
15 Feb 2005CPOL12 min read 114.7K   1.1K   53  
An article on the use of the OverlibPageControl and OverlibPopupAnchor for extended manipulation of the overLIB popup JavaScript library.
//� 2005 Thaddaeus Parker thaddparker(at)usa(dot)net
//This code is free to use and modify as long as this statement is left intact.
//All other copyrights are held by their respective owners
using System;
using System.Text.RegularExpressions;
using System.Collections;
namespace OverLibWrapper.Design
{
	/// <summary>
	/// OverlibPopupTextBuilder builds complex text.
	/// </summary>
	public class OverlibPopupTextBuilder
	{
		private System.Web.UI.WebControls.Table _table;
		private System.Text.StringBuilder text = new System.Text.StringBuilder("");
		private string originalText;
		private bool _hasHTML = false;
		private bool _hasInnerPopups = false;
		private	System.IO.StringWriter stringWriter; 
		private	System.Web.UI.HtmlTextWriter textWriter; 
		/// <summary>
		/// Creates a new <see cref="OverlibPopupTextBuilder"/> instance.
		/// </summary>
		public OverlibPopupTextBuilder(){
		}

		/// <summary>
		/// Returns the text that was built for the popup.
		/// </summary>
		/// <returns>A string that represents the text that will be shown in the popup</returns>
		public string PopupText(){
			if (this._table != null) {
			stringWriter = new System.IO.StringWriter();
			textWriter  = new System.Web.UI.HtmlTextWriter(stringWriter);
				this._table.RenderControl(textWriter);
				textWriter.Close();
				_hasHTML = true;
			}
			this.text = new System.Text.StringBuilder("");
			this.text = stringWriter.GetStringBuilder().Insert(0,originalText+"\n");
			stringWriter.Close();
			return this.text.ToString();
		}
		/// <summary>
		/// Gets a value indicating whether this instance has HTML.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance has HTML; otherwise, <c>false</c>.
		/// </value>
		public bool HasHTML{
			get{return _hasHTML;}
		}
		/// <summary>
		/// Adds the inner tool tip. You must create a new popup and set the innerPopup property to true
		/// </summary>
		/// <param name="rowIndex">row number.</param>
		/// <param name="cellIndex">cell number</param>
		/// <param name="tipHyperlink">the hyperlink string</param>
		public void AddInnerToolTip(int rowIndex,int cellIndex,string tipHyperlink){
			if(tipHyperlink.Trim().Length !=0){
				if(this._table != null){
					if( this._table.Rows.Count > rowIndex){
						if(this._table.Rows[rowIndex].Cells.Count > cellIndex ){
							this._table.Rows[rowIndex].Cells[cellIndex].Text = tipHyperlink;
							_hasInnerPopups = true;
						}
					}
				}
			}
		}
		/// <summary>
		/// Adds a html table to the popup content.
		/// </summary>
		public void AddTable() {
			if(this._table == null){
				this._table = new System.Web.UI.WebControls.Table();
				this._table.Attributes.Remove("border");
			}
			
		}
		/// <summary>
		/// Adds the table attribute.
		/// </summary>
		/// <param name="attrib">The attribute to add.</param>
		/// <param name="value">The string value of that attribute.</param>
		public void AddTableAttribute(string attrib, string value){
			this._table.Attributes.Add(attrib,value);
		}
		/// <summary>
		/// Adds a row to the internal table.
		/// </summary>
		/// <remarks>If another table is needed inside the current table create another OverlibPopupTextBuilder
		/// and create the table there. Then add the html to a particular cell or row</remarks>
		/// <returns>An integer index of the row that is added to the table</returns>
		public int AddTableRow(){
			System.Web.UI.WebControls.TableRow tableRow = new System.Web.UI.WebControls.TableRow();
			int rowIndex = this._table.Rows.Add(tableRow);

			return rowIndex;
		}
		/// <summary>
		/// Adds the table row attribute.
		/// </summary>
		/// <param name="rowIndex">Row index.</param>
		/// <param name="attrib">Attrib.</param>
		/// <param name="value">Value.</param>
		public void AddRowAttribute(int rowIndex, string attrib, string value){
			if (this._table.Rows.Count > rowIndex) {
				this._table.Rows[rowIndex].Attributes.Add(attrib, value);
			}
		}
		/// <summary>
		/// Adds the row cell. See remarks in <seealso cref="AddTableRow"/>
		/// </summary>
		/// <param name="rowIndex">Row index.</param>
		/// <param name="contents">Contents.</param>
		/// <returns>An integer index of the cell that is added to the row</returns>
		public int AddRowCell(int rowIndex, string contents){
			int cellIndex = -1;
			if (this._table.Rows.Count > rowIndex) {
				System.Web.UI.WebControls.TableCell cell = new System.Web.UI.WebControls.TableCell();
				_hasInnerPopups = ParseContentsForInnerPopup(contents);
				cell.Text = contents;
				cellIndex = this._table.Rows[rowIndex].Cells.Add(cell);
			}
			return cellIndex;
		}
		/// <summary>
		/// Adds the cell attribute.
		/// </summary>
		/// <param name="rowIndex">Row index.</param>
		/// <param name="cellIndex">Cell index.</param>
		/// <param name="attrib">Attrib.</param>
		/// <param name="val">Val.</param>
		public void AddCellAttribute(int rowIndex, int cellIndex, string attrib, string val){
			if(this._table.Rows.Count > rowIndex){
				if(this._table.Rows[rowIndex].Cells.Count > cellIndex){
					this._table.Rows[rowIndex].Cells[cellIndex].Attributes.Add(attrib,val);
				}
			}
		}
		/// <summary>
		/// Adds the bullet list.
		/// </summary>
		/// <param name="rowIndex">Row index.</param>
		/// <param name="cellIndex">Cell index.</param>
		/// <param name="bullets">Bullets.</param>
		public void AddBulletList(int rowIndex, int cellIndex, params string[] bullets){
			if(bullets.Length == 0){
				return;
			}
			System.Text.StringBuilder str = new System.Text.StringBuilder();
			str.Append("<ul>");
			foreach(string s in bullets){
				str.Append("<li>"+ s + "</li>");
			}
			str.Append("</ul>");
			if(this._table.Rows.Count > rowIndex){
				if(this._table.Rows[rowIndex].Cells.Count > cellIndex){
					this._table.Rows[rowIndex].Cells[cellIndex].Text = str.ToString();
				}
			}
		}
		/// <summary>
		/// Adds the numbered list.
		/// </summary>
		/// <param name="rowIndex">Row index.</param>
		/// <param name="cellIndex">Cell index.</param>
		/// <param name="bullets">Bullets.</param>
		public void AddNumberedList(int rowIndex, int cellIndex, params string[] bullets){
			if(bullets.Length == 0){
				return;
			}
			System.Text.StringBuilder str = new System.Text.StringBuilder("");
			str.Append("<ol>");
			foreach(string s in bullets){
				str.Append("<li>"+ s + "</li>");
			}
			str.Append("</ol>");
			if(this._table.Rows.Count > rowIndex){
				if(this._table.Rows[rowIndex].Cells.Count > cellIndex){
					this._table.Rows[rowIndex].Cells[cellIndex].Text = str.ToString();
				}
			}
		}
		private bool ParseContentsForInnerPopup(string contents){
			bool innerPopup = false;
			int beginTag = -1;
			beginTag = contents.Trim().IndexOf("<a");
			int endTag = contents.Trim().IndexOf("/a>");
			int overlib2Tag = contents.Trim().IndexOf("overlib2(");
			if(overlib2Tag > -1){
				innerPopup = true;
			}
			return innerPopup;
		}
		private string ParseInputString(string input){
			string[] inputs = input.Split(' ');
			System.Text.StringBuilder content = new System.Text.StringBuilder();
			int index = input.IndexOf("<table");
			if(index == -1){
				return input;
			}
			if(index == 0){
				this._table = new System.Web.UI.WebControls.Table();
			}
			return content.ToString();
		}
		/// <summary>
		/// This parses text incoming that either is just text or html style text.  This function
		/// uses major regular expressions
		/// </summary>
		/// <param name="content">The string of content to parse</param>
		/// <returns>A HTML table formatted group of text that represents the inner content of Popup text</returns>
		public string ParseText(string content){
			System.Text.StringBuilder str =new System.Text.StringBuilder("");
			stringWriter = new System.IO.StringWriter(str);
			textWriter = new System.Web.UI.HtmlTextWriter(stringWriter);
		
			//			string htmltable = "dsfalfdsalfds<table border='0' cellpadding=2><tr class='text'><td rowspan=3>hello</td><td>1</td><td class=yahoo>22222</td></tr>"+
			//				"<tr class='blah2'><td>2</td><td class='blah'>3</td><td>blahhhdndn</td></tr></table> endblah";
			const string table = @"(?<content>[\w\W]*)\<table(?<attribs>[^\>]*)\>";
			const string tr = @"\<tr(?<attribs>[^\>]*)\>";
			const string td = @"\<td(?<attribs>[^\>]*)>(?<content>[^</td]*)";
			const string endtable = @"\</table\>(?<content>[\w\W]*)";
			string endText = "";
			int patternCount = 0;
			int rowCount = 0;
				
			//puts the regular expressions in order of usual appearance within an HTML document
			ArrayList regexs = new ArrayList();
			regexs.Add(table);
			regexs.Add(tr);
			regexs.Add(td);
			regexs.Add(endtable);
			//grabs each one of the patterns specified
			//TODO: find a way to extend this function to grab inner html content
			foreach (string pattern in regexs) {
				Regex regEx = new Regex(pattern, RegexOptions.Compiled|RegexOptions.IgnoreCase|RegexOptions.Singleline);
					
				if (regEx.IsMatch(content)) {
					MatchCollection matches = regEx.Matches(content);
					int matchIndex = 0;
					int rowCounter = 0;
					int cellCount = 0;
					foreach (Match match in matches) {
						switch (patternCount) {
							case 0: // table
								//this gets the content before the table tag
								if(match.Groups["content"].ToString().Trim().Length != 0){
									str.Append(match.Groups["content"].ToString().Trim());
								}
								//we want to ensure about a new table here
								_table = new System.Web.UI.WebControls.Table();
								//clear the existing attributes with the premade table
								//this seems to be a problem, because you cannot go in and edit a particular
								//attribute.  So we just clear them out and start fresh
								_table.Attributes.Remove("border");
								_table.Attributes.Clear();
								Hashtable tableAttribHash = GetAttributes(match);
								foreach(string key in tableAttribHash.Keys){
									_table.Attributes.Add(key,tableAttribHash[key].ToString());
								}
								break;
							case 1: //row
								//creates a new row, adds the attributes found and inserts it into the table
								Hashtable rowAttribHash = GetAttributes(match);
								System.Web.UI.WebControls.TableRow row = new System.Web.UI.WebControls.TableRow();
								foreach(string key in rowAttribHash.Keys){
									row.Attributes.Add(key,rowAttribHash[key].ToString());
								}
								_table.Rows.Add(row); 
								rowCount++; //this is used for the "cell" install feature in case 2:
								break;
							case 2: //cell
								//TODO: Figure out a way to deal with odd numbered cells for the rows.
								//this particular case only deals with even numbered cells
								//that is even if there is a rowspan attribute on the the function will fail miserably!!
								int rowCells = matches.Count/rowCount;
								Hashtable cellAttribHash = GetAttributes(match);
								System.Web.UI.WebControls.TableCell cell = new System.Web.UI.WebControls.TableCell();
								foreach(string key in cellAttribHash.Keys){
									cell.Attributes.Add(key,cellAttribHash[key].ToString());
								}
								if(match.Groups["content"].ToString().Trim().Length != 0){
									cell.Text = match.Groups["content"].ToString().Trim();
								}
								_table.Rows[rowCounter].Cells.Add(cell);
								cellCount++;
								if(cellCount == rowCells){
									rowCounter++;
								}
								//								cellsList.Add(cell);
								break;
							case 3: //end content
								//this grabs the content that is immediately after the end table tag
								if(match.Groups["content"].ToString().Trim().Length != 0){
									endText = match.Groups["content"].ToString().Trim();
								}
								break;
							
						}
						matchIndex++;
					} // foreach (Match match in regEx.Matches)
				} else{ // if (regEx.IsMatch(table))
					//if we don't any type of match we know that a table doesn't exist within the string
					//we will just return the content assuming that it is a pure string.
					if(patternCount == 0){
						originalText = content; //maintain an original if there is nothing
						this.text.Append(content); //this is to ensure that whatever text was sent in is retained by the builder
						return content; //this is due to the fact that if the table wasn't found then
						//why should we go any further;
					}
				}
				patternCount++;
			}
			
			_table.RenderControl(textWriter);
			textWriter.Close();
			stringWriter.Close();
			str.Append(endText);
			this.text = str;
			_hasHTML = true;
			return text.ToString();

		}
		
		/// <summary>
		/// Gets the attributes for a particular regular expression match.
		/// </summary>
		/// <param name="match">A found match that contains possible attributes</param>
		/// <returns>A hashtable that contains the keys and their values</returns>
		private Hashtable GetAttributes(Match match) {
			Hashtable attribsHash = new Hashtable();
			const string attrPattern = "(?<Keyword>\\w+)(?<equals>\\s*=\\s*)([\\s'\"]*)(?<Value>[^\\s'\"]*)([\\s'\"]*)(?<whitespace>\\s*)";
		  
			Group attributeGroup = match.Groups["attribs"];
			Regex attribs = new Regex(attrPattern);
			if (attribs.IsMatch(attributeGroup.ToString())) {
				foreach (Match attribMatch in attribs.Matches(attributeGroup.ToString())) {
					attribsHash.Add(attribMatch.Groups["Keyword"].ToString().Trim().ToLower(),attribMatch.Groups["Value"].ToString().Trim().ToLower());
				}
			}
								
			return attribsHash;
		}


	}
}

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Avanade, Inc
United States United States
A software developer for a medium sized company with a Microsoft product core development strategy.

Comments and Discussions