
December 18, 2008
So you’ve put together a CSS template with a body background color. We’ll use #4C4C4C. Your CSS template contains a content area that is a different color. We’ll use #000000. In simple form that looks like this:
body {
background-color: #4C4C4C;
}
#content {
width: 700px;
margin: 0 auto;
background-color:#000000;
color: #FFFFFF;
}
Now if your content area is black, wouldn’t it be nice to edit your content in TinyMCE on a black background? Assuming you have TinyMCE importing your sites stylesheet, here is the trick:
* .mceContentBody {
background: #000000;
}
That’s it! Super easy. If you have a better way of doing this feel free to comment.

November 26, 2008
This is a quick and easy trick/fix for correcting the css min-height problem in IE6. It is pure CSS and does not require any additional div’s. Here’s the code:
selector {
min-height:500px;
height:auto !important;
height:500px;
}
That’s it! This trick should be compatible with: IE6, IE7, Mozilla/Firefox/Gecko, Opera 7.x+, Safari1.2
This is not compatible with IE5.5, but with less than 0.01% of my visitors using it I am not overly concerned about implementing this fix on most sites.
You can view Dustin Diaz’s original article here.

November 18, 2008
This is a PHP script that I wrote a long time ago (possibly around 2002) to count the unique visitors to your website. It does not require a database and stores everything in a text file. It is suitable for small websites that don’t expect large amounts of traffic. It will display web page hits in either text or graphical mode.
Please note that I have not modified this code from its original version so there may be some unknown compatibility issues. Also, if you do look at the code don’t think that I would still write any code like this.
THIS IS NOT AN EXAMPLE OF MY CODING STYLE/SKILL OF TODAY!
With all the new free Web2.0 tools that are available these days you really should be looking into implementing something like Google Analytics to track your visitors. I just thought I would make txtPHPCounter available since sites are still linking to it.
Download txtPHPCounter.zip

November 14, 2008
Looking for a cool new place in Victoria to grab a drink and hang out with friends? Spend one night at Hecklers Bar & Grill located at 123 Gorge Rd, Victoria BC and you will be hooked. Hecklers has all the games/activities that any serious sports bar should have including a dart board, pool table, Foosball table, bubble hockey, Big Buck Hunter and a recently added pinball machine.
But why stop there? Hecklers Bar & Grill also has a Wii set up on one of their many large LCD tv’s free of charge! Can you say Wii Bowling League? That’s right; Every Sunday night you can gather your team, step up to the alley and show everyone what you’re made of. Wii bowling not your style? How about poker? Every Monday night is a just-for-fun poker challenge.
Laugh much? Hit up Hecklers on Friday for comedy night at Victoria’s only stand up comedy club. The posters say “Laugh till you pee” and they aren’t joking. Comedy night features comedians seen on Comedy Central and Just for Laughs. Live music plays every Saturday night with no cover charge!
What about food?! Hecklers has an appetizing with daily specials including 34cent Wednesday wings and $5 appy’s 3pm-6pm. Mmm Yam Fries! The basic order of fries for $5 comes with half regular and half yam fries. Since they make the fries fresh on-site you can order all yams or all regular if you so wish.
Besides the wide array of activities available to keep you occupied, what really makes you want to come back is the atmosphere and the friendly people. You will always be greeted with a smile and can expect a high-level of service from their great staff.
Thanks for the good times Hecklers!

November 7, 2008
The topics listed below were deemed “important to know” for the Comp241 Midterm scheduled for Nov 13, 2008 by Rob Thorndyke.
Session Management
Client-side
- scalable – each client is storing its own state, you can have 1 or 1,000,000 clients and it’s all the same to the server
- distribute load to more servers
- easier to have persistent data
|
Server-side
- secure
- lower bandwidth requirements – state doesnt go back and forth with each request.
- sharing data between clients (careful though, session data is generally locked to one client)
|
Those are the advantages/disadvantages. How do you actually implement these?
Client
- Cookies
- persistent
- can be turned off / modified
- Query String (BAD, try not ever to use these if you want your site to rank in google)
- can’t be turned off
- user sees it, and curious people will change them
- search engines can’t deal with them very well
- browsers can limit the max length
- setting values is not supported in .NET
- GET only! does not work with POST
- View State (implemented using hidden fields)
- nice support in .NET
- supports POST
- with ViewState, watch the bandwidth – everything gets sent back and forth
- Hidden Fields
For all of the above, data must be key/value pairs and must also be serializable.
Server
- Sessions
- unique to each client “connection”
- time out after a while
- may depend on Cookies (the session id is generally stored in a cookie, this can be turned off but then the session id goes in the query string)
- Application
- global – share data between clients
- web servers can reset these at seemingly random moments
Data Management
Connected Objects
- DBCommand – SQL Statement
- DBConnection – interface to the DB
- DBDataReader
- read-only
- forward-only
- safer
- faster (lightweight)
- DBDataAdapter – read/write and bidirectional
Disconnected Objects
- DataSet
- DataTable
- DataTable.Select() – returns DataRow[] (array of DataRow’s)
- DataRow
- Field access (read overwrite)
- Acts as dictionary
int status = (int) ds.Tables["table"].Select("row = 7")[0]["status"];
Data-Bound Controls
- Control.Databind() – Refreshes the view with current DataSource
Input Validation
General Info
- gives you a chance to check user input and make sure it is valid
- generally you need to do the validation on BOTH the server and the client
- server
- needed in case client validation is bypassed
- has access to DB -> more complex validation
- client
- convenient – quick validation without PostBack
Validation Controls
- RequiredFieldValidator
- non-empty / not “default”
- CompareValidator
- compare two values (==, <=, >=, …etc)
- RangeValidator
- MinimumValue
- MaximumValue
- it checks for value between (inclusive)
- RegularExpressionValidator
- CustomValidator
- ClientFunctionName (javascript function)
- ServerValidate event handler
C# Properties
private int age;
public int Age {
get { return age; }
set { age = value; }
}

November 6, 2008
The following notes were taken during a lecture in COMP 241 .NET Web Applications at Camosun College by Rob Thorndyke. These notes are here mainly to help me study, but if you can find some guidance through them then all the better!
Remember Managing State?
Client-side state
- Hidden Fields
- String Queries
- View State
- Cookies
Server-side state
- Sessions
- Application (This is what we will be using for this step)
- Global dictionary for the entire application
- This is where we will attach our DataSet
DataSet ds = new DataSet();
// do stuff with the DataSet
Application["ds"] = ds; // To set it.
ds = (DataSet) Application["ds"]; // To retrieve it.
Lab Hints
Game Database Tables
games
game_id, name, status
board
game_id, row, col0, col1, col2, col3, col4, col5, col6
Creating and Joining Connect4 Games
- After you create a game:
- new game entries added to the tables
- new Guid “game_id”
- set status to JOINABLE
- add “blank.png” rows to the board table
- set my colour to “red”
- “red” always goes first on new game
- wait for someone to join the game
- Once you join an existing game:
- set my colour to blue
- hide new game controls
- set game status to RED_NEXT
“This is where it gets exciting because you can actually
beat your friends into submission!”
~ Rob Thorndyke
private int STATUS_RED_NEXT = 1;
private int STATUS_BLUE_NEXT = 2;
//...
private int getStatus() {
string filter = String.Format("game_id = Convert('{0}, System.Guid)", Session["game_id"]);
DataTable gamesTable = ds.Tables["games"];
return (int) gamesTable.Select(filter)[0]["status"];
}
private string getCellValue(int row, int col) {
string filter = String.Format("game_id = Convert('{0}', System.Guid)", Session["game_id"]);
DataTable board = ds.Tables["board"];
return (string) board.Select(filter + " and row = " + row)[0]["col" + col];
}
To Create a new game:
- use Guid.CreateNew() to make a new unique id
- add row to “games” table -> status = STATUS_JOINABLE;
- add 6 rows to “board” table -> row 0…5; colx = “blank.png”;
- hide the New Game controls
- set all ImageButtons to “blank.png”
- set “game_id” & “my_colour” Session vars
To Join a game:
- verify status is STATUS_JOINABLE
- set status to STATUS_RED_NEXT
- hide New Game controls
- set “game_id” & “my_colour” Session vars
- set all ImageButtons to “blank.png”
To “Refresh”:
- if client is in a game
- check status for my turn and if so
- set info label
- update ImageButtons to see where other guy moved
- check for game end and if so
- show New Game controls
- set info label
- if NOT in game
- repopulate Joinable Games List

October 31, 2008
The following notes were taken during a lecture in COMP 241 .NET Web Applications at Camosun College by Rob Thorndyke. These notes are here mainly to help me study, but if you can find some guidance through them then all the better!
Fundamental Objects
- DbConnection
- DBCommand
- DBDataReader
- DbDataAdapter
Connection Types
- SQL Server
- ODBC
- OLEDB (Old SQL Server)
- Access
- XML
- SqlDbConnection
- OleDbConnection
- OracleDbConnection
- ODBCDbConnection
Example Session
DbConnection connection = new SqlConnection(connectionString);
DbCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM table_name";
connection.Open();
DbDataReader reader = cmd.ExecuteReader();
// Returns a table of data
// Do something with that data
// -------------
connection.Close();
// *NOTE: After closing the connection, the data
// in reader will no longer be available!
Command Examples
cmd.CommandText = "UPDATE table1 SET value = 30 WHERE value = 10";
connection.Open();
int count = cmd.ExecuteNonQuery();
connection.Close();
// -----------------------------
cmd.CommandText = "SELECT count(*) FROM user";
connection.Open();
int num_users = (int) cmd.ExecuteScalar(); // Must be cast
connection.Close();
Data Reader
- Forward-only, read-only, cursor
- Highly efficient; use when you only need read-only data, that’s processed only once, in order
// Iterating through the reader
DbDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
int value = (int) reader["value"];
string name = (string) reader["name"];
}
// Putting the data into a DataTable
DbDataReader reader = cmd.ExecuteReader();
DataTable table = new DataTable();
table.Load(reader, LoadOption.Upsert);
connection.Close();
GridView1.DataSource = table; //Data Bound Control
GridView1.DataBind();
Load Options
(http://msdn.microsoft.com/en-us/library/system.data.loadoption.aspx)
| Member name |
Description |
| OverwriteChanges |
The incoming values for this row will be written to both the current value and the original value versions of the data for each column. |
| PreserveChanges |
The incoming values for this row will be written to the original value version of each column. The current version of the data in each column will not be changed. [This] is the default. |
| Upsert |
The incoming values for this row will be written to the current version of each column. The original version of each column’s data will not be changed. |
Data Adapters
- Allows automatic writeback
- Has 3 “update” properties
- InsertCommand
- DeleteCommand
- UpdateCommand
- These are all or nothing! You must implement all 3
- Formatting these things is not trivial
DbCommand cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM board";
// Create our data adapter
DbDataAdapter adapter = new DataAdapter(cmd);
adapter.Fill(ds, "table"); // ds is a DataSet!
- Formatting:
- Use a GUI wizard – Popped up when the DataAdapter is dropped on the form!
- Use a Builder:
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

October 30, 2008
The following notes were taken during a lecture in COMP 230 Systems Analysis & Design at Camosun College by Marla Weston. These notes are here mainly to help me study, but if you can find some guidance through them then all the better!
Conceptual Data Modeling Process
In the design stage, the conceptual data model is translated into a physical design
Deliverables and Outcome
- Primary deliverable is an entity-relationship diagram (ER Diagram)
- Second deliverable is a set of entries about data obnects to be stored in repository or project dictionary
- repository links data, process, and lopgic models of an information system
- data elements included in the DFD must appear in the ERD
Conceptual Data Model
- The 30,000 foot view.
- Very high level
- Just the system and any external entities that interact with it.
Gathering Information for Conceptual Data Modeling
- Top Down approach for the data model is derived from an intimate understanding of the system
- Bottom Up approach which builds simple low-level objects into more complex higher-level objects.
Entity Relationship Model
- Entity type name should always be a singular noun
- Entity type definition should:
- Include a statement of what the unique characteristics is/are for each instance
- Make clear what entity instances are included and not included in the entity type
- Attributes: a named property characteristic of an entity that is of interest to the organization
- Naming an attribute: eg Vehicle_ID
- Place its name inside the rectangle for the associated entity in the E-R Diagram
- Name is a noun and should be unique
- States what the attribute is and possibly why it is important
- Should indicate if a value is required or optional
- Relationships
- A relationship name is a verb phrase and avoid vague names
- A relationship definition should:
- Explain any optiontion participation
- Explain the extent of history that is kept in the relationship
- Associative Entity
- An entity type that associates the instances of one or more entity types and contains attributes that are peculiar to the relationship between those entity instances
- Used mostly in many-many relationships
- Subtypes: A type together with a constraint which possibly restricts the allowed range of values
- Supertypes: A generic entity type that has a relationship with one or more subtypes
- Business Rules: specifications that preserve the integrity of the logical data model
- Entity Integrity
- Referential
- Trigger/Triggering Operation – An assertion or rule that governs the validity of data manipulations such as insert update and delete

October 24, 2008
The following notes were taken during a lecture in COMP 241 .NET Web Applications at Camosun College by Rob Thorndyke. These notes are here mainly to help me study, but if you can find some guidance through them then all the better!
Web Page
|
GridView (DataBound Control, DataSource Property)
|– DataTable (pure data – no UI)
|– Adapter Object — Database
DataTable & DataColumn
Example Code:
DataTable dataTable = new DataTable();
DataColumn idColumn = new DataColumn( "id" );
idColumn.DataType = typeof( string );
// DataColumn has all the properties you would expect to find if you were creating a database field
idColumn.MaxLength = 10; // Default: -1
idColumn.Unique = true; // Default: false
idColumn.AllowDBNull = false; // Default: true;
// Add the column to the dataTable
dataTable.Columns.Add( idColumn );
// OR
dataTable.Columns.Add( "id", typeof( string ) );
DataColumn column = dataTable.Columns[ "id" ];
// ---------------------------
DataColumn salaray = new DataColumn( "salary" );
salary.DataType = typeof( Decimal );
salary.DefaultValue = 0.00m; // m = decimal literal
dataTable.Columns.Add( salary );
// Decimal - Fixed precision float - good for money
// Hex: int t = 0xc4;
DataRow
Example Code:
DataRow row1 = dataTable.newRow();
row1["id"] = "x123";
row1["salary"] = 11043.00m;
dataTable.Rows.Add(row1);
// Alternatively
dataTable.Rows.Add("Z417", 32147.00m);
// Alternatively adding a row with an object array
dataTable.Rows.Add(new object[] { "P112", 7417.00m } );
DataRow State
DataRow State
- Detached – not in a Table
- Added – just added; never committed
- Unchanged – no changes since last commit
- Modified – some changes since last commit
- Deleted – just deleted
DataRow Version
- Current
- Default
- Original
- Proposed
Code:
row1.AcceptChanges(); // --> "commit"
row1.RejectChanges(); // --> "roll back"
label1.Text = "" + row1.RowState;
DataSet
A collection of DataTables and DataRelations
DataSet ds = new DataSet("db");
DataTable table1 = ds.Tables.Add("table1");
table1.Columns.Add("id", typeof(Guid)); // Guid: Global Unique Identifier
table1.Columns.Add("name", typeof(string));
table1.PrimaryKey = new DataColumn[] { table1.Columns["id"] };
DataTable table2 = ds.Tables.Add("table2");
table2.Columns.Add("id", typeof(Guid));
table2.Columns.Add("style", typeof(string));
table2.Columns.Add("foreign_key", typeof(Guid));
table2.PrimaryKey = new DataColumn[] { table2.Columns["id"] };
ds.Relations.Add("table1_table2_relation", table1.Columns["id"], table2.Columns["foreign_key"]);
Web Page
–|–GridView
——-|–DataSet
————|–DataAdapter
—————–|–database

October 20, 2008
The following notes were taken during a lecture in COMP 230 Systems Analysis & Design at Camosun College by Marla Weston. These notes are here mainly to help me study, but if you can find some guidance through them then all the better!
Data Flow Diagrams (DFD)
- Technology independent
- show data flows, structure, and functional requirements of new system
- Useful for depicting purely logical information flows
- DFDs that detail physical systems differ from system flowcharts which depict details of physical computing equipment
Process: work or actions performed on data (inside the system)
Data store: data at rest (inside the system)
Source/sink: external entitty that is orgingin or destination of dara (ouotside the system)
Data flow: arrow depicting movement of data.
Context Diagram: is an overview of an organizational system that shows:
- the system boundaries
- external entities that interact with the system
- major information flows between the entities
Level-0 Diagram
DFD Rules
There are DFD guidelines that apply:
- the inputs to a process are different form the outputs of that provess
- no process can only have outputs or only inputs. processes must have both inputs and outputs.
- process labels should be verb phrases
- all flows to or from a data store must move through a process
- no data move directly between external entities without going through a process
- bidirectional flwo between process and data store is represented by two separate arrow (no bi-directional arrow)
- forked data flow must refer to exact same data item (not different data items) from a common location
- joined data flow must refer to exact same data item (not different data items) from multiple souces to a common location
- data flow caonn go diretly from a process to itself (no recursive data flows)
- data flow from a process to a data store means update( insert, delete or change)
Functional decomposition is an iterative process of breaking a system description down into finer and finer detail.
- creates a set of charts in which one process on a given chart is explained in great detail on another chart.
- continues until no sub process can logically be broken down any further
Primitive DFD – the lowest level of a DFD.
level 1 diagram results from decomposition of level 0 diagram
BPR: Business Process Re-engineering