Search

Tuesday, December 23, 2008

Support rich text with the Yahoo! User Interface Library

During a recent project, my team's task was to redesign a Web page that utilized an ActiveX control as a rich text editor. One goal of the project was to replace the ActiveX control with a more standardized approach. We chose to use the rich text editor available with the Yahoo! User Interface (YUI) Library. This week I examine using the YUI Library's Rich Text Editor.

YUI Library

The YUI Library is a set of utilities and controls in JavaScript, as well as CSS templates for building richly interactive Web applications using standard technologies such as DHTML, DOM scripting, and AJAX.

You can download the YUI Library 2.3.1 for free from SourceForge.net. The download allows you to install the libraries on a Web server. Another option is to use the library files directly from Yahoo! servers. Yahoo! provides an excellent overview of how to use its servers for applications implementing functionality via the YUI Library.

Rich Text Editor

A recent addition to the YUI Library is the Rich Text Editor. It is a user interface control that replaces the standard HTML textarea element. It allows for the rich formatting of text content, including common structural treatments like lists, formatting treatments like bold and italic text, and drag-and-drop inclusion and sizing of images.

A critical feature of the Rich Text Editor is its toolbar, which provides access to various features like text formatting, color choices, and so forth. You may choose which toolbar features to include in an implementation via scripting. In addition, the toolbar is extensible via a plug-in architecture so that advanced implementations can achieve a high degree of customization.

Putting the Rich Text Editor to work

If you want to use the Rich Text Editor, it requires a YUI Library CSS skin to properly render the control. The following YUI Library files (CSS and JavaScript source files) are necessary to use the Rich Text Editor. The following lines reference the files on the previously mentioned Yahoo! servers, but you may use a local installation as well.

<!-- Skin CSS file --> 

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/assets/skins/sam/skin.css">

<!-- Utility Dependencies -->

<script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/yahoo-dom-event/yahoo-dom-event.js"></script>

<script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/element/element-beta-min.js"></script>

<!-- Needed for Menus, Buttons and Overlays used in the Toolbar -->

<script src="http://yui.yahooapis.com/2.3.1/build/container/container_core-min.js"></script>

<script src="http://yui.yahooapis.com/2.3.1/build/menu/menu-min.js"></script>

<script src="http://yui.yahooapis.com/2.3.1/build/button/button-beta-min.js"></script>

<!-- Source file for Rich Text Editor-->

<script src="http://yui.yahooapis.com/2.3.1/build/editor/editor-beta-min.js"></script>

The following base HTML is used to deliver the Rich Text Box, but you'll still need to add scripting to fully implement the control.

<body class="yui-skin-sam"> 

<textarea name="texteditor" id="texteditor" cols="50" rows="10">

This text will be displayed in the text area.

</textarea></body>

Now the cols and rows attributes of the HTML texarea element will be overridden by settings specified in the Rich Text Editor's script. The name assigned to the HTML textarea element is important, since it will be used in the JavaScript code when establishing the relationship between a textarea element and a Rich Text Editor.

Also, the class assigned to the HTML body element (yui-skin-sam) is used to visually format the Rich Text Editor control. This CSS skin is defined in the CSS file imported into the application (see previous list). The skin should be applied to the parent HTML element of the textarea element. In this case, the HTML body element is used, but it could be any element that contains the textarea.

Once the textarea has been defined along with the proper YUI Library files included in the page, the Rich Text Editor control must be rendered. The rendering is accomplished via JavaScript placed within the page. The script can be used to define various Rich Text Editor options such as the toolbar. As an example, I may use the following JavaScript to format our Rich Text Editor:

var rtf = new YAHOO.widget.Editor('texteditor', { 

height: '300px',

width: '522px'});

rtf.render();

This snippet establishes the height and width of the editor while declaring an instance of the Rich Text Editor. Also, it assigns the textarea called texteditor to the Rich Text Editor. The final line in the script actually causes the Rich Text Editor to display when it calls its render method.

When you use the Rich Text Editor control without any specifics about the toolbar, it results in the default behavior of including all toolbar features like text alignment, font face, font size, color, and so forth. You may choose to limit the toolbar options available to users.

The final example uses a Rich Text Editor, but the toolbar options are defined in the JavaScript code to render it. The following options are used:

  • The toolbar options are defined in its own variable. This is later used to instantiate the editor.
  • A title is assigned to the editor via the toolbar's titlebar property.
  • The collapse property signals whether the user may collapse/hide the toolbar.
  • The buttons property allows you to define the buttons displayed in the toolbar. In this example, buttons are displayed for text formatting as well as selecting colors.

Once the toolbar options are defined, a Rich Text Editor object is instantiated with the toolbar variable passed to it along with the HTML textarea element. The final step is to render the control. A complete list of options is available in the YUI Library API documentation.

<html><head> 

<title>Working with YUI Library Rich Text Editor</title>

<!-- Skin CSS file -->

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/assets/skins/sam/skin.css" />

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/fonts/fonts-min.css" />

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/container/assets/skins/sam/container.css" />

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css" />

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/button/assets/skins/sam/button.css" />

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/editor/assets/skins/sam/editor.css" />

<!-- Utility Dependencies -->

<script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/yahoo-dom-event/yahoo-dom-event.js"></script>

<script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/element/element-beta-min.js"></script>

<!-- Needed for Menus, Buttons and Overlays used in the Toolbar -->

<script src="http://yui.yahooapis.com/2.3.1/build/container/container_core-min.js"></script>

<script src="http://yui.yahooapis.com/2.3.1/build/menu/menu-min.js"></script>

<script src="http://yui.yahooapis.com/2.3.1/build/button/button-beta-min.js"></script>

<!-- Source file for Rich Text Editor-->

<script src="http://yui.yahooapis.com/2.3.1/build/editor/editor-beta-min.js"></script>

<style>

body { margin:0; padding:0; font-face: arial; font-size: 10pt;}

.yui-editor-container {z-index: 999;}

.editable {

border: 5px solid black;

argin-top: 100px;

margin: .25em;

float: left;

width: 350px;

height: 100px;

overflow: auto;

}

.textbox {

margin-left: 10px;

width: 100px;

height: 25px;

}

.label {

margin-left: 10px;

width: 50px;

height: 25px;

font-weight: bold;

}

</style></head>

<body class="yui-skin-sam">

<span class="label">First Name:</span><input type="text" name="firstName" id="firstName" class="textbox" /><br />

<span class="label">Last Name:</span><input type="text" name="lastName" id="lastName" class="textbox" /><br />

<textarea name="texteditor" id="texteditor">

Test within TextArea.

</textarea>

<script>

var toolbar = {

height: '200px',

width: '420px',

toolbar: {

titlebar: 'TechRepublic.com Editor',

collapse: true,

buttons: [

{ group: 'textstyle', label: 'Font Style',

buttons: [

{ type: 'push', label: 'Bold', value: 'bold' },

{ type: 'push', label: 'Italic', value: 'italic' },

{ type: 'push', label: 'Underline', value: 'underline' },

{ type: 'separator' },

{ type: 'select', label: 'Arial', value: 'fontname', disabled: true,

menu: [

{ text: 'Arial', checked: true },

{ text: 'Arial Black' },

{ text: 'Comic Sans MS' },

{ text: 'Courier New' },

{ text: 'Lucida Console' },

{ text: 'Tahoma' },

{ text: 'Times New Roman' },

{ text: 'Trebuchet MS' },

{ text: 'Verdana' }

] },

{ type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true },

{ type: 'separator' },

{ type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },

{ type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }

] } ] } };

myEditor = new YAHOO.widget.Editor('texteditor', toolbar);

myEditor.render();



  • Date: November 5th, 2007
  • Author: Tony Patton


</script></body></html>

It is worth noting that the text is formatted using standard HTML to format the text within the Rich Text Editor, so bold text uses the HTML strong element; the font element is used for font styling, and so forth.

An improved interface

I have been a big fan of the YUI Library since I first discovered it more than a year ago. It allows developers to build powerful Web interfaces using code that has been fully tested for proper functionality. The Rich Text Editor is just one example of the power controls available in the YUI Library.

Moving to CSS-based layouts with the YUI Library

While initiating a recent project to make substantial changes to an existing Web application, it was decided to dump the table-based layout used in its original design in favor of CSS. We opted to use the Yahoo! User Interface (YUI) Library after evaluating different approaches. The YUI Library provides core CSS resources that have been developed by a professional team of developers and extensively tested by the Web community.

This tutorial walks you through the steps of how to move from a table-based design to a CSS-based layout with the help of the YUI Library.

The layout

It is worth considering the division of screen real estate in the application to understand how it is coded using both tables and CSS. The overall page is divided into two horizontal sections: a header and a body.

The header portion can be further divided into three horizontal strips. The first strip contains a strip of color at the top. The middle row contains text and a logo on a white background. The final row has its own background color along with a breadcrumb.

The body portion of the page is divided into two columns. The first column is a navigation area featuring a list of navigation links. The second column is divided into two rows with a small footer row at the bottom, and the rest is devoted to page content.

The site design does not change from the original product developed with Dreamweaver and HTML tables. The introduction of CSS will deliver cleaner code with a smaller footprint and simplified maintenance.

Table-based layout

The original design used six HTML tables to divide the page and deliver the solution. It used CSS to style text on the page, but CSS usage stopped at that point. The following listing includes the HTML source. Background colors are assigned to each table (via the bgcolor attribute) to provide a visual cue of the layout.

<html>
<head><title>Table-based page layout</title></head>
<body>
<table bgcolor="yellow" width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr><td colspan="3" width="100%"></td></tr>
<tr><td colspan="3">
<table bgcolor="red" border="0" width="100%" cellspacing="0">
<tr>
<td width="85%" valign="middle">Header Text</td>
<td width="15%"><img src="logo.jpg" mce_src="logo.jpg" /></td>
</tr></table></td></tr>
<tr>
<td width="16%" height="20" nowrap>Breadcrumb</td>
<td width="40%" height="20" align="right" nowrap></td>
</tr>
<tr>
<td width="10%" rowspan="2" valign="top">
<table bgcolor="green" width="101%" height="100%" border="0" cellpadding="0"
cellspacing="0">
<tr>
<td height="167" valign="top">
<table bgcolor="light blue" width="100%" border="0" cellspacing="0">
<tr><td colspan="3">Menu</td></tr>
<tr>
<td width="8"> </td>
<td>Nav Link</td>
<td width="4"> </td>
</tr></table></td></tr></table></td>
<td height="100%" colspan="2" valign="top">
<table bgcolor="brown" width="100%" height="100%" cellpadding="0" cellspacing="0">
<tr><td valign="top">
<table bgcolor="silver" width="96%" height="220" border="0" cellpadding="10">
<tbody><tr>
<td valign=top align=left width="100%">
<p>Content goes here</p>
</td></tr></tbody></table></td></tr><tr>
<td height="40" valign="middle">
Footer
</td></tr>
</table></td></tr></table></body></html>

The table-based layout solution delivers the desired results, but it can be confusing to make layout changes. A quick perusal of the code demonstrates the confusing nature of using tables for layout.

It takes time to make layout changes and to convert a table-based solution to a CSS alternative, so selling such a change to a client can be daunting. In our case, the client was technically savvy and easily convinced when we showed the simplified approach offered by CSS.

YUI Grids CSS

The use of the YUI Grids CSS feature of the YUI Library added another level of acceptance via a tested solution. YUI Grids CSS provides a CSS solution for delivering page layouts that divide the page into areas.

A great aspect of the YUI Grids CSS feature is its A-level browser support, which provides the highest support level in terms of browsers. This means you don't have to worry about the quirks in different browsers when using CSS for layout.

CSS layout

YUI Grids CSS offers preset page widths and templates, along with the ability to nest and stack layouts to generate what you need. Yahoo boasts the capability to deliver more than 1,000 layout combinations with it. YUI Grids CSS is part of the YUI Library download.

We used the following features of the YUI Grids CSS feature:

  • The 100% page width is employed via the doc3 id attribute assigned to the overall <DIV> container.
  • The entire page is divided into three rows using three <DIV> elements. The YUI Grids CSS standard id attributes for header (hd), body (bd), and footer (ft) are used.
  • The header has three rows using two <P> elements and a <DIV> element. The <DIV> includes another <DIV> that uses YUI Grids CSS features. This includes the 100% page width (doc3 attribute), as well as a preset template that has two columns with the narrower column on the left with a width of 180 pixels. The narrower column is assigned the class id of yui-b with the larger column assigned the yui-main attribute. The two columns are used to ensure the breadcrumb appears above the content area of the page.
  • The middle or body row of the whole page layout is divided into two columns with a left column width of 180 pixels. This is accomplished with a predefined template employed by assigning the yui-t2 class to the body's <DIV> container. The smaller left column is designated with the yui-b class assignment, and the main area is designated with the yui-main class assignment.
  • The footer row uses the same approach as the body with two columns — a left column of 180 pixels.
  • The smaller left column of the body row of the page contains a navigation menu. The menu is created with an HTML unordered list and styled via CSS.
  • The YUI Grids CSS is contained in one CSS file available in the YUI Library download. The file is called grids.css and has a small footprint of 4KB.

Here is the source of the reworked page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Reworked with YUI Grids CSS</title>     
<link rel="stylesheet" type="text/css" href="grids.css" mce_href="grids.css">
</head>
<body>
<div id="doc3">
<div id="hd">
<p class="header1"></p>
<p class="header3">
<span>Text</span>
<span class="logo"></span>
</p>
<div>
<div id="doc3" class="yui-t2">
<div class="yui-b"></div>  
<div id="yui-main">
<div class="yui-b">Breadcrumb</div>
</div>
</div>
</div>
</div>
<div id="bd">
<div id="doc3" class="yui-t2">
<div class="yui-b">
<ul class="nav">
<li class="main">Menu</li>
<li class="sub">Nav Link</li>
</ul>
</div>  
<div id="yui-main">
<div class="yui-b">
Content goes here
</div>
</div>
</div>
</div>
<div id="ft">
<div id="doc3" class="yui-t2">
<div class="yui-b">
</div>  
<div id="yui-main">
<div class="yui-b">
Footer
</div>
</div>
</div>
</div>
</div>
</body></html>

You may cringe at the sight of so many <DIV> elements, but this is much easier to follow compared to its table counterpart. Also, the CSS approach allows you to easily modify the layout by editing the CSS or changing what YUI Grids CSS features are used.

For example, we could easily modify the layout to use a layout with a left column of 160 pixels by changing the class assigned to the <DIV> elements from yui-t2 to yui-t1. In order to use this approach, you need to be familiar with using YUI Grids CSS.

There's a caveat to working with the free CSS elements of the YUI Library: It's tricky to alter the source CSS. The code contains many so-called hacks in order to work with all browsers that you may not be fully aware of all of them when you're editing the CSS. For me, I avoid working directly with the source and work within the confines of the YUI Library.

Making the switch

CSS has matured to the point where using it for layout is now acceptable. However, this approach does have pitfalls, which include browser quirks. For this reason, I find the freely available YUI Grids CSS portion of the YUI Library to be an excellent resource for building Web interfaces that use Web standards.

Are you embracing CSS for Web page layout? Do you use any aspect of the YUI Library in your applications? Share your experiences with the Web Developer community.

Additional TechRepublic resources about the YUI Library


  • Date: March 17th, 2008
  • Author: Tony Patton

Build directory structures using SQL Server 2005

If you ever work with directory structures on the filing system, you know how challenging it can be to traverse through folders to find specific file(s). If you store this type of information structure in the database, you are even more aware of what it takes to retrieve the data. Writing queries to pull this information is sometimes difficult to achieve and inefficient. You can use the recursion and XML features in SQL Server 2005 to build a file location on the fly.

Example

This example searches for a document and builds the path to the document based upon a parent-folder to child-folder relationship in the database. One file will belong to one folder, which may be a child folder in a long lineage of parent folders. The ultimate goal is to provide a file to be searched for, and the process will build the location to the file.

I've seen file path locations stored several ways in the database, usually with the purpose of storing the location of a file to be pulled for a Web site. Most of the time, the full path to a file is stored in one database field, but I have also seen the location of a file "normalized" so that the past must be built when needed. My goal for this article is to solve the issue of building the path from the hierarchical structure.

The script below creates a Documents table and a Folders table. The Documents table stores the filenames and the folder that the document resides in. The Folders table stores the directory structure of one or more local or network drives. Most of the work in this example will involve traversing through this folder structure to build the path to the file.

IF OBJECT_ID('Documents','U') IS NOT NULL
DROP TABLE Documents

IF OBJECT_ID('Folders','U') IS NOT NULL
DROP TABLE Folders

IF OBJECT_ID('udf_BuildDocumentPath','FN') IS NOT NULL
DROP FUNCTION udf_BuildDocumentPath

CREATE TABLE Documents
(
        DocumentID SMALLINT,
        FolderID SMALLINT,
        DocumentName VARCHAR(255)
)

CREATE TABLE Folders
(
        FolderID SMALLINT,
        ParentFolderID SMALLINT,
        FolderName VARCHAR(255)
)

The code below adds data to our newly created tables. I am adding data for three documents, all of which are located in the same folder.

INSERT INTO Documents(DocumentID, FolderID, DocumentName)
VALUES(1,5,'SalesForecast2008.xls')
INSERT INTO Documents(DocumentID, FolderID, DocumentName)
VALUES(2,5,'SalesProjection.doc')
INSERT INTO Documents(DocumentID, FolderID, DocumentName)
VALUES(3,5,'SalesForecastPresentation.ppt')

INSERT INTO Folders(FolderID, ParentFolderID, FolderName)
VALUES(1,null, 'D:')
INSERT INTO Folders(FolderID, ParentFolderID, FolderName)
VALUES(2,1, 'Sales')
INSERT INTO Folders(FolderID, ParentFolderID, FolderName)
VALUES(3,2, 'Forecasts')
INSERT INTO Folders(FolderID, ParentFolderID, FolderName)
VALUES(4,3, 'Data')
INSERT INTO Folders(FolderID, ParentFolderID, FolderName)
VALUES(5,4, '2008')
GO

The script below creates the function that will build the full path to the file based upon the DocumentID in the Documents table. This function uses a recursive common table expression (CTE) to traverse through the directory structure, linking the child folder ID to the parent folder ID in the table. Once the set of records are found that comprise the full path to the document, the FOR XML PATH('') construct is used to "pivot" these values from values in different rows to values concatenated in the same row. From there, it is just a matter of returning the build path to the caller.

FOR XML Path() is one of my favorite features in SQL Server 2005 because it makes it so easy to take a list of column values from different rows and concatenate them together so that they are on the same row. It is an ideal tool for dynamically building SQL statements that require list of different values for use in an IN() statement.

CREATE FUNCTION udf_BuildDocumentPath
(
        @DocumentID SMALLINT
)
RETURNS VARCHAR(400)
AS
BEGIN
        DECLARE @ReturnPath VARCHAR(400)

;WITH DirectoryPathCTE(DocumentID, FolderID, ParentFolderID, DocumentName, FolderName, LevelNumber)
        AS
        (
        SELECT
               DocumentID, f.FolderID, ParentFolderID, DocumentName, f.FolderName, 0
        FROM
               Documents d
               INNER JOIN folders f on d.FolderID = f.FolderID
        WHERE
               DocumentID = @DocumentID
        UNION ALL
        SELECT
               DocumentID, f.FolderID, f.ParentFolderID, DocumentName, f.FolderName, p.LevelNumber + 1
        FROM
               Folders f
               INNER JOIN DirectoryPathCTE p on p.ParentFolderID = f.FolderID
        )
        SELECT @ReturnPath =
        (
               SELECT
                  FolderName + '' + CASE WHEN LevelNumber = 0 THEN DocumentName ELSE '' END
               FROM
                       DirectoryPathCTE p
               ORDER BY LevelNumber DESC
               FOR XML PATH('')
        )

        RETURN(@ReturnPath)

END
GO

Now that my function is built, I can call it for every document I have in my Documents table, and the path to the file will be built based upon the DocumentID in the Documents table.

SELECT dbo.udf_BuildDocumentPath(d.DocumentID)
FROM Documents d

Conclusion

Even if you never need to implement the example in this article, I hope you'll take away some ideas from the recursion and the FOR XML PATH clause to solve some tricky problems you may encounter in the future.


  • Date: March 17th, 2008
  • Author: Tim Chapman

Adapt to your audience with CSS media types

In addition to worrying about browsers, Web standards, and more, you also have to consider the multitude of devices or media that may be used to view a site. The CSS media type provides the functionality to build Web applications whose presentation may vary with its target media. Here's an examination of this CSS feature, along with examples.

The media

A CSS media type names a set of CSS properties. A user agent that claims to support a media type by name must implement all of the properties that apply to that media type. Style sheets allow you to specify how a document is presented with different media. For example, viewing a page on the screen should be presented differently than when it is printed or spoken via a speech synthesizer for the visually impaired.

Here's a list of the media types that are currently supported:

  • all: Applies to all media types.
  • aural: Used for speech and sound synthesizers.
  • braille: Provides support for braille tactile feedback devices.
  • embossed: Used for paged braille printers.
  • handheld: Used to target small or handheld devices with limited screen space.
  • print: Applies to printers, so users can easily print a page's content.
  • projection: Used for projected presentations like slides.
  • screen: The most common delivery mechanism for Web content: the computer screen.
  • tty: Used for media using a fixed-pitch character grid, like teletypes and terminals.
  • tv: This applies to television-like devices such as MSN TV.

With these media types in mind, you can develop separate style sheets to use for the different media that may be used by users who visit your site.

Media-specific CSS

You may specify different media types a variety of ways. First, you may use @import at-rules that specify the media type for an external style sheet that is imported, as the following line accomplishes with importing a special style sheet for tv-based devices.

@import url("webtv.css") tv;

You may use the @media rule to provide presentation rules for handling certain media types within a Web page. The following lines show how this could be used to use a white background for tv-like devices:

@media tv {
background: #fff;
}

The Link HTML element allows you to link to external style sheets and use the media attribute to specify the target media type for the link. The following snippet shows how it may be used:

<LINK rel="stylesheet" type="text/css" media="tv" href="tv.css" mce_href="tv.css">

A caveat of each approach is that you may specify more than one media type for a rule by separating the individual media types with commas. For example, the previous HTML snippet can be rewritten to target tv-like media as well as projection media with the following line.

<LINK rel="stylesheet" type="text/css" media="tv, projection"
href="tv.css" mce_href="tv.css">

In action

Different media types are supported so you can format content differently for the various device or media types available. A good example is printing where items like menus and sidebars are omitted (most often using display: none) in the printed output. (Check out Shawn Morton's article about building printer-friendly pages.)

The following CSS is included as a brief example of formatting content for different media types. The background is blue for regular screens and white for printed or handheld output. Also, the font size is set to easier to read 12 point for printed output and smaller for handhelds. The font family is set to apply to all media types.

<style type="text/css">
@nedia all {
font-family: sans-serif;
}
@media handheld {
body {
border: none;
padding-bottom: 5px;
font-size: 8pt;
background: white;
}
h1, h2 {
font-size: 10pt;;
} }
@media screen {
body {
background: blue;
font-size: 10pt;
} }
@media print {
body {
width: auto;
margin: 0 5%;
padding: 0;
font-size: 12pt;
} }
</style>

The size of the style sheet for each media type will be much larger than this simple example in real-world applications, so placing each media type's code in separate files and using the Link element will save bandwidth with less code to download. A key issue with any Web standard is its support within the community.

Support

CSS media types are a part of the CSS2 standard, but browser adoption and compliance has been very slow. The media type values of all, screen, and print are well supported, but the remaining types have only received limited support within the browser market. You should test vigorously to ensure the results match expectations with target platforms.

At this time, the handheld media type is supported by some devices and software, so you should test with target devices to measure support. The Opera browser supports the projection media type, but support outside of Opera is limited. Support for the other media types like braille, tv, tty, embossed, and aural is almost non-existent. The Emacspeak browser utilizes the aural media type.

Know your audience

The CSS2 specification includes the media type feature, which allows developers to tailor content for certain media types via style sheets. The feature has been adopted in a piecemeal fashion by the Web community as the print and screen types are fully supported, while support for others is inconsistent and sometimes non-existent. Meanwhile, the CSS3 standard moves forward with the goal of enhancing the media type feature.

Have you included media type support in your Web applications? Share your thoughts and experiences with CSS and media types with the Web developer community by posting to the discussion.

Additional CSS resources from TechRepublic


  • Date: April 4th, 2008
  • Author: Tony Patton

How do I… Create a scrolling content box in CSS?

In my last TechRepublic Programming and Development blog entry, I showed you how to use Flash to create an animation that mimicked the behavior of the retired (and sometimes reviled) <marquee> tag. I had mentioned that it was possible to use CSS to duplicate the <marquee> tag as well, but only if it were coupled with a few lines of knotty JavaScript.

However, there is an alternative CSS markup that will let you confine large blocks of content to a set width and height and let you scroll through them using a scrollbar control. This gives the effect of viewing content in a frame (remember those?), but the scrolling box stays put on one page and you can place it anywhere in your layout that you wish. This gives both you and your clients much more control over how you view your Web pages. All of my clients like this layout solution, and I bet yours will as well.

This blog post is also available in PDF format as a TechRepublic download, which includes a sample Web page and the example code.

Start

Open your preferred HTML editor and create a new page. Enter the code in Listing A to get started.

Listing A

<html>

<head>

<title>Scrolling Content Box</title>

<body>

</body>

</html>

Let's go ahead and place some formatted text in the Body of the HTML document, so we can see the effects of our CSS code as we build it (Listing B). Place a significant amount of text into the page. This will give us plenty of text to scroll through when the page is complete.

Listing B

<html>

<head>

<title> Scrolling Content Box </title>

</head>

<body>

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</body>

</html>

Our text is in place, but let's go ahead and assign the CSS class to it. Even though the CSS markup has not been coded yet, by assigning the style to the text, you can preview the HTML you are writing at any time to see how the styling is built step by step.

We'll name our style class "scrollBox" in a couple of steps, so assign a <div> tag with that attribute as shown in Listing C.

Listing C

<html>

<head>

<title> Scrolling Content Box </title>

</head>

<body>

<div class="scrollBox">

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</div>

</body>

</html>

Now that our content is in place, it's time to create your CSS code in the head of the document Declare the style and place it immediately after the closing </TITLE> tag. (Listing D)

Listing D

<html>

<head>

<title> Scrolling Content Box </title>

<style type="text/css">

<!--

-->

</style>

</head>

<body>

<div class="scrollBox">

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</div>

</body>

</html>

The next step is to declare a class name for the scrolling box style. Let's keep things simple and name it "scrollBox" by typing in the new code in Listing E.

Listing E

<html>

<head>

<title> Scrolling Content Box </title>

<style type="text/css">

<!-

.scrollBox {

}

-->

</style>

</head>

<body>

<div class="scrollBox">

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</div>

</body>

</html>

Now we have to assign some attributes to the scrollBox class. Let's start by defining how the text itself should look. Helvetica is back in style, and 10 pixels high with a line height of 12 pixels should look fine.

Listing F

<html>

<head>

<title> Scrolling Content Box </title>

<style type="text/css">

<!-

.scrollBox {

font-family: Helvetica, sans-serif;

font-size: 10px;

line-height: 12px;

}

-->

</style>

</head>

<body>

<div class="scrollBox">

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</div>

</body>

</html>

The font is typeset to satisfaction. The next step is to determine how wide and tall the containing box will be. Type in the code in Listing G to give the box a width of 200 pixels and a height of 150 pixels.

Listing G

<html>

<head>

<title> Scrolling Content Box </title>

<style type="text/css">

<!-

.scrollBox {

font-family: Helvetica, sans-serif;

font-size: 10px;

line-height: 12px;

height: 150px;

width: 200px;

}

-->

</style>

</head>

<body>

<div class="scrollBox">

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</div>

</body>

</html>

If we were to just leave the styling alone here, the type would butt up against the scrollbar when it is viewed in the Web browser. Enter the additional code in Listing H to give the type some padding along all edges of the containing box.

Listing H

<html>

<head>

<title> Scrolling Content Box </title>

<style type="text/css">

<!-

.scrollBox {

font-family: Helvetica, sans-serif;

font-size: 10px;

line-height: 12px;

height: 150px;

width: 200px;

padding: 5px;

}

-->

</style>

</head>

<body>

<div class="scrollBox">

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</div>

</body>

</html>

One last bit of graphic design before we move on to the scroll functionality. Give the box a light blue background using the additional markup shown in Listing I.

Listing I

<html>

<head>

<title> Scrolling Content Box </title>

<style type="text/css">

<!-

.scrollBox {

font-family: Helvetica, sans-serif;

font-size: 10px;

line-height: 12px;

height: 150px;

width: 200px;

padding: 5px;

background-color: #CCCCFF;

}

-->

</style>

</head>

<body>

<div class="scrollBox">

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</div>

</body>

</html>

Now, if you previewed your code thus far in a Web browser, you would see that the enormous block of text would be in a blue box, but it would be cut off after several lines. This is due to the height attribute. Therefore, we need a line of markup (shown in Listing J) that tells the browser to allow us to see the text beyond that height limit. This is done with the overflow rule and we'll set its attribute to auto, which will tell the browser to show the scrollbar controls as needed.

Listing J

<html>

<head>

<title> Scrolling Content Box </title>

<style type="text/css">

<!-

.scrollBox {

font-family: Helvetica, sans-serif;

font-size: 10px;

line-height: 12px;

height: 150px;

width: 200px;

padding: 5px;

background-color: #CCCCFF;

overflow: auto;

}

-->

</style>

</head>

<body>

<div class="scrollBox">

"It had a perfectly round door like a porthole, painted green, with a shiny yellow brass knob in the exact middle. The door opened on to a tube-shaped hall like a tunnel: a very comfortable tunnel without smoke, with paneled walls and floors tiled and carpeted, provided with polished chairs, and lots and lots of pegs for hats and coats--the hobbit was fond of visitors. The tunnel wound on and on, going fairly but not quite straight into the side of the hill--The Hill, as all the people for many miles round called it--and many little round doors opened out of it, first on one side and then on another. No going upstairs for the hobbit: bedrooms, bathrooms, cellars, pantries (lots of these), wardrobes (he had whole rooms devoted to clothes), kitchens, dining-rooms, all were on the same floor, and indeed on the same passage. The best rooms were all on the lefthand side (going in), for these were the only ones to have windows, deep-set round windows looking over his garden and meadows beyond, sloping down to the river."

</div>

</body>


  • Date: April 10th, 2008
  • Author: John Lee


</html>

Preview the page in several browsers across operating systems to see how they display the design markup and scrollbar controls.

Since scrollBox is a CSS class, it can be styled even further and it can be applied to any HTML element, not just blocks of text. Try applying it to <img> tags, for example, to create scroll box containers for high-resolution images.

Create custom Visual Studio 2005 code snippets

Visual Studio 2005's built-in code snippets are great, but you can extend the concept by creating custom code snippets to easily reuse common code blocks in your application. This tutorial walks you through the process of creating custom code snippets.

Creating the file

Code snippets are defined in XML files with the .snippet file extension. Microsoft created the Code Snippet XML Schema, which defines the structure of a snippet XML file and specifies the elements (and their attributes) that you may use in a code snippet file.

Since code snippets are defined as XML, you can use your favorite XML or text editor to create and maintain them. Visual Studio 2005 supports XML editing, so it may be used to remain in a common environment.

Code snippet example

Depending on the project or organization, many code snippet candidates may exist. This may be a discrete chunk of code that you may reuse throughout the code (this also lends itself to a code library). In addition, the code may or may not include replaceable parameters that allow you to enforce a coding technique.

To demonstrate, I will create a code snippet that declares a set of objects for working with SQL Server. This allows a developer to insert and use these objects while saving typing time. Here is the C# code snippet:

SqlConnection conn;
SqlCommand comm;
SqlDataAdapter sda;

Listing A contains the appropriate code snippet XML. Listing B contains the equivalent code snippet definition for VB.NET. Here's a closer look at the XML:

  • A code snippet is defined by the CodeSnippet element. The CodeSnippets element is the root node, and it may contain one or more CodeSnippet elements.
  • The Description, Author, and Shortcut elements appear in the Code Snippets Manager window when it is highlighted. For this reason, the text included in the Description element should give a good idea of what the snippet actually does. In addition, the Shortcut element is what is typed within Visual Studio 2005 to actually use the snippet (type the shortcut and hit [Tab]).
  • The Code element contains the actual code associated with the snippet. In this example, there are no replaceable parameters used. The code is placed within the CDATA attribute.
  • The Language attribute of the Code element defines the code used. The options include VB, CSharp, VJSharp, and XML.

You should create a folder to contain your custom code snippets and save this sample in the folder. The next step is to make it available in Visual Studio 2005.

Adding a snippet to Visual Studio 2005

The Code Snippets Manager allows you to easily add your own code snippets to the environment. To do so, you should follow these steps:

  1. Open the Manager window via the Tools | Code Snippets Manager menu selection.
  2. Select the appropriate language in the Language field.
  3. Click the Add button to add your snippet to the environment. This opens the Code Snippets Directory window that allows you to navigate to the folder containing the snippet file(s). You don't select the actual snippet file — the folder is selected and all snippets within it are added.
  4. Once the directory is added, you can select it and browse the files within it.

You can test it by typing the appropriate shortcut in Visual Studio 2005 and hitting [Tab] to insert the code, or you can right-click and select Insert Snippet from the context menu. This allows you to navigate the available code snippet directories to locate one if you don't know its shortcut. If you're using C#, you may also use the Surround With context menu option. This is just one way to tackle this simple example.

More examples

The Code Snippet XML Schema includes the optional Declarations element that you may use to specify the literals and objects for the code specified in the snippet. It might include zero or more Literal elements that you may use to define literals, and zero or more Object elements to define objects used in the code. Literal and Object elements contain ID, ToolTip, and Default elements to assign a name to the item, tooltip text, and its default value. In addition, the Object element contains the Type element to specify the type of object.

The Object and Literal elements are used in the actual code within the Code element. You reference the literals and objects you declared in the Declarations element by placing $ symbols at the beginning and end of the value in the literal or object's ID element. The VB snippet file in Listing C uses these elements to declare literals to be used in our code.

When you use this code snippet, green boxes appear around the literals enclosed in dollar signs ($connString$ and $sqlString$), which allow you to insert the appropriate text. The example code snippets in this column provide a peek at the creation process, but there is much more functionality available via the Code Snippet XML Schema.

Importing code snippets

While creating custom code snippets provides power and flexibility, you may also import snippets (created by you or others) to Visual Studio 2005 via the Import button in the Code Snippets Manager. This allows you to bring snippets into existing directories used by the Code Snippets Manager. You select the destination directories and select the Finish button. The process physically copies the snippet file to the destination directory.

Microsoft provides plenty of Visual Studio 2005 code snippets, which you can download and import into your environment.

Third-party tools

It can be a bit tedious to create and edit XML files. It is especially cumbersome when you must know the syntax and order of a valid element that you may use in the snippet file. While Visual Studio 2005 does not include a snippet editor, there are code snippet editor tools available:

Customize your environment

Creating custom code snippets allows you to customize and streamline your development environment by making it easy to reuse standard coding elements and save typing. Use your favorite XML or text editor to create your own snippets and add them to Visual Studio 2005 to save valuable time.


  • Date: April 18th, 2008
  • Author: Tony Patton

Visual Studio 2008 simplifies JavaScript debugging

One of the more cumbersome development tasks is debugging client-side JavaScript code. Tools such as Firebug are helpful, but in the case of Firebug, you're forced to use Firefox. Thankfully, Visual Studio 2008 provides a robust and developer-friendly environment for debugging JavaScript.

Simplification

Whenever I hear developers discuss the JavaScript debugger features in Visual Studio 2008, I notice that they're quick to point out that this type of functionality has been available in prior versions of the Visual Studio IDE for a long time. This is certainly true, but the improvements in Visual Studio 2008 make it much simpler to use.

The irritating aspect of JavaScript debugging in Visual Studio 2005 is that you have to first execute the application before any breakpoints can be created in your JavaScript. This approach has been modified in Visual Studio 2008 to allow breakpoints to be defined in the source code before the application runs. In fact, you can set them in both your C#/VB.NET code as well as JavaScript. So, when the application is run, you can step through all breakpoints regardless of the code.

Setup

With Visual Studio 2008 installed, there is one additional requirement for enabling JavaScript debugging: Internet Explorer must have script debugging enabled. This setting is available via the Tools | Internet Options menu within Internet Explorer. Once the Internet Options dialog box is open, select the Advanced tab and the Disable Script Debugging option is located in the Browsing section. It should not be checked so that it is enabled. Figure A shows the Disable Script Debugging option deselected.

Figure A

Figure A

Figure A: Enabling script debugging in Internet Explorer

With debugging feature enabled in Internet Explorer, you can start debugging your JavaScript code.

Features

The JavaScript debugger presents many standard debugging features. The following list provides a review of some of these features.

  • Breakpoints: Breakpoints allow you to stop code execution at specific points within the source code. JavaScript breakpoints work just like C#/VB breakpoints.
    Breakpoints are set/cleared by clicking to the left of the code within the IDE; by using the Debug menu or by using the Breakpoint Context menu available by right-clicking on the code. In addition, you may create conditional breakpoints to allow you to define conditions for the breakpoint, as well as set up a macro to run or a message to print when the breakpoint is triggered.
    Breakpoints are viewable in the Watch window located by default in the lower left of Visual Studio 2008.
  • Call Stack: The Call Stack tab in the lower right of Visual Studio 2008 allows you to view what is being called when the ASP.NET page is loaded/running.
  • Locals: The Locals tab in the lower left of Visual Studio 2008 allows you to view the values of variables and objects during script execution. Also, you may change the contents of one of the local variables while the page is running.
  • Execute code: The Immediate Window tab in the lower right of Visual Studio 2008 allows you to execute JavaScript code on-the-fly during page execution.

The Debug drop-down menu within Visual Studio 2008 provides a Windows submenu that allows you to define what windows to display while debugging. The examples in this article use Locals, Watch, Call Stack, and Immediate Window.

The most used feature during debugging is often breakpoints because you can use them to stop code execution and examine the state of variables and objects at that point in the script. Breakpoints provide a number of features (which are available via the Debug drop-down menu during a debugging session) for their use.

Code execution stops at each breakpoint — unless it is a conditional breakpoint whose condition has not been met. Once the code is halted, you may choose to continue one line at a time or until the next breakpoint is encountered.

The debugger is actually enabled via the Debug menu in Visual Studio 2008. You go to Debug | Start to begin a debugging session or press [F5]. A picture is worth a thousand words, so let's take a closer look at actually using the debugger.

In action

For a simple example, I have an ASP.NET page that includes three JavaScript functions. One function populates a DIV tag on the page with text passed to it. The second function displays text passed to it in a pop-up window via the alert function. The last function populates a DIV tag with the text "Loaded"; this function is called when the page first loads.

Figure B shows this page running in debug mode. A breakpoint has been set on the line that populates a local variable with the contents of a DIV tag on the page. The red circle to the left of the line lets you know that it is a breakpoint. The line of code waiting to run is highlighted in yellow.

Figure B

Figure B

Figure B: Sample page opened for debugging in Visual Studio 2008

Also, a watch has been set on the divText variable, so the many properties associated with it are displayed in the Watch window at the bottom of the screen. Watches have been greatly enhanced in Visual Studio 2008 to include much more detail. You can now view runtime object's methods and events, as well as property and property type information.

Dynamic nature

A unique feature of JavaScript is its dynamic nature, whereas the code actually loaded in the browser when an application runs is often different than what is in the IDE. That is, the code is often generated as scripts may be stored as resources, loaded from other locations, or contained within other compiled controls.

The Script Documents feature of Visual Studio 2008 allows you to easily keep an eye on what is loaded and where it originated. While debugging, the Script Documents node will appear within the Solution Explorer pane. It will include the URL of each resource loaded into the page. It is visible in the upper right of Figure B.

Another note on the dynamic nature of JavaScript is the setting of breakpoints in the source code. Visual Studio 2008 automatically maps the breakpoint location to the dynamically generated page loaded in the browser. Likewise, if you set breakpoints in the executing page, the IDE performs the reverse mapping to update the breakpoints in the source code.

Take a peek

Debugging is an essential aspect of every developer's job. Debugging standard code has never been a problem, but working with JavaScript has always presented problems. Visual Studio 2008 eases the burden with an enhanced debugger that simplifies the chore of taking a look at what your JavaScript is actually doing at runtime.

What tools do you use to work with JavaScript? Do you plan on using Visual Studio 2008 to work with JavaScript now or in the future? Share your thoughts with the Web Developer community.


  • Date: May 15th, 2008
  • Author: Tony Patton

Why it’s impossible to become a programming expert

The pace of change in the technology industry has made it nearly impossible to specialize in much or become an expert in anything. I started cluing in on this a few years ago when I was reading a lot about Lisp, but I simply didn't have time to try it out. Learning Lisp, and learning it well, requires a lot of reading, practice, trial and error, and so on. This would have been fine and dandy, but I wasn't doing this during my 9-5 job; this was just a "wouldn't it be neat to learn this?" type of project. A few months ago, my father and I were discussing the topic of expertise, and some of the things he said really clicked in my head.

Compare the amount of knowledge needed to really know C, Pascal, or maybe COBOL to their modern business programming analogues of J2EE and .NET. There are a few commands, a few primitive types, and a few operators. Let's look at the libraries in 1991 as an example (1991 is the year I learned to program). Windows was just starting to penetrate the enterprise. A lot of programming was happening on mainframes. By and large, UIs were completely text based without a mouse. Input validation was a cinch; you simply looped over a "wait for input" statement until the user pressed one of the three valid buttons for that point in the program. Events? Nope. Object-oriented programming? Nope. Declarative UI definitions (HTML, XAML, etc.)? Nope. N-tiered architecture? Accessing resources over a network? Globalization? Nope, nope, and nope. Life was pretty darned simple.

It was a really nice transition from that world to the Perl/CGI world. At the end of the day, writing Perl in a CGI environment is conceptually very similar to writing a COBOL program: You take a batch of input, do your processing, and dump your output as a batch. It took roughly 50 printed pages to have enough Perl documentation, examples, "cookbook recipes," and so on to do the job at a decent level of competency. The experts were the folks who had been around long enough to understand issues such as SQL injection, and the need to properly escape encoded entities. At the time, I specialized in regular expressions. A few months of working with regular expressions (which are arguably a micro-language of their own), and I could read a regex like English. Over the next few years, I worked some real magic with them, from writing my own PHP-like system that fit my needs to working on screen scraping.

In 2001, I transitioned to Java. All of a sudden, I had some monolithic 1,000 page tome on my desk and 200 MB of HTML with minimal formatting on my hard drive — and these were just as reference sources. I ended up reading 500-700 pages of a "teach yourself Java" type of book. (In comparison, I read C in Plain English in three days — it was only a few hundred pages — without access to a C compiler, and I definitely qualified as "knowing" C.) The Java language has grown quite a bit since then; C# and VB.NET are comparable in size and scope. I would guess that it would take at least 500 pages to adequately document (with examples and a thorough explanation of the techniques, usage scenarios for them, etc.) VB.NET, C#, or Java. PHP is much less complex, thanks to its Perlish roots. We still haven't looked at the massive libraries that these systems carry with them; J2EE and the .NET Framework are both quite extensive. If anyone tells me that they are an expert in these systems, I know they are lying.

I have been working with the .NET Framework since 2003, and I am not an expert in the Framework. I am highly experienced with a few namespaces: System.Drawing, System.Threading, System.Net.Web, and System.Text.RegularExpressions. The rest of my time working with .NET has been so insanely spread out that I can't remember much of it. Thank goodness for Visual Studio's IntelliSense; at least with that, I can muddle through namespaces until I find what I need. If anyone were to watch me write code, they would assume that I am an idiot, since it would definitely look like I was grasping at straws 50% of the time. To be honest, that is what it feels like. Unfortunately, my "grasping at straws 50% of the time" still beats the industry average of 70% (I'm just making up numbers).

An expert programmer is no longer someone who is really knowledgeable or experienced. All too often, an expert programmer is the person who is adept at using a variety of reference tools and documentation to find out how to achieve their goals. This is my secret sauce. I am really good at looking at a problem, figuring out approximately what is wrong, and being able to quickly find the solution. To the uninitiated, it looks like sheer magic. To others, they say, "wow, Justin figured that out in only 30 minutes!" when they had been struggling with it all day. My real talent is knowing how to rapidly research and turn my findings into usable information. I suspect that I would be just as good at being a forensic accountant or a question writer for Jeopardy!.

Most of the really good programmers I have met are the same way — they know a little of everything. They have tons of experiences that inform their "guiding light" when they look for answers. They have a natural talent, but overall, if you were to grill them on anything outside a narrow area (say, the System.Threading namespace), there is a really good chance that they will know where to get the answer from but not actually know the answer. Mark Cuban recently called this the "Open Book" World, and I tend to agree. Although for those of us in the IT industry, this happened 10 years ago; programmers (unlike network engineers and system administrators) have been able to touch radically new concepts with a simple download since about 1995. The eruption in new programming models, languages, frameworks, libraries, etc. closely tracks the adoption of the Internet. Between vendors and open source projects, it seems like another new "this will revolutionize how you program!" system is announced once a week or so. They all look worthy, but they take six months to learn really well, and I just can't devote my time to working with more than one at a time. So my choice is to either become barely familiar with a lot of things, or to commit myself to something that may not pan out.

For now, the "sampler platter approach" has been working well for me at the professional level, although I find it quite frustrating at the personal level. I miss learning things in depth. I miss the sense of satisfaction from attaining a level of expertise. I miss getting to explore obtuse and obscure areas of knowledge. But it simply does not match the reality of my work or that of most other programmers.


  • Date: May 27th, 2008
  • Author: Justin James

Manager won’t hire moonlighters

A TechRepublic member has a problem with prospective employers who won't hire him because he has a side business. How should he handle it?

—————————————————————————————————————

In a blog this week I wrote about how to convince a prospective employer that you're not overqualified for a position.

One of our TechRepublic members was frustrated by the fact that a couple of the people who interviewed him for a developer position refused to believe that he would be happy stepping down from the management position he currently held.

This week, another member wrote in with a similar complaint. In this case, prospective employers think some business endeavors he started while on a hiatus will interfere with any new full-time position he gets. Here's the scoop:

"I took a year's hiatus from IT and started up a few small businesses (consulting, web development) to keep me busy and to learn some new skills. Now that I'm back to looking for a job, employers question the 'self-employed' item in my resume. I don't want to leave the last year blank and I don't want to lie about what I've been doing for the past year. I was told flat out at one interview that they were already having problems with two staff who had their own business on the side and weren't interested in taking on any more - end of interview!"

My advice:

How nice that this interviewer was so eager to make an assumption about your work ethic based on his experience with other people! Unfortunately, this is pretty common. Most of the time when an employer makes a bad assumption about a job candidate, it's usually because they've been burned by a similar situation before. It's not fair, but that's why it happens.

The interviewer is assuming that you have money and sweat equity wrapped up in your companies, and that you'll surely want to keep them afloat. And, in his experience, that means you will probably use company time to make that happen. This is also a shame for him because he's missing out on a lot of good employees — a pretty good percentage of IT moonlight.

I wonder how your side businesses are presented in your resume, and if there is any way to refer to the experience gained from the endeavors without referring to them as "side businesses." That is, instead of saying that from 2006-2007, you started a Web development business, maybe you could say that during that time period you consulted on Web developments issues. The latter speaks about your experience and expertise without implying that it is a business that requires attention that would take you away from a job. It may appear that you are withholding information, but you're actually just spinning it so the information will be more agreeable to anyone looking at it.

It's a shame that the initiative that you showed during your time off is being held against you. I hope things work out, or at least you interview with a manager who hasn't been burned by freelancers before.


  • Date: June 27th, 2008
  • Author: Toni Bowers

AJAX should not mandate HTTP

An interesting and unfortunate by-product of AJAX applications is that these applications rely upon the existence of an application server always being available. Many Web users are used to the idea that they can save a Web page to be read at their convenience. Even when there is Flash on the page, the page still works offline. After all, HTML is simply a document storage format, and HTTP is simply a protocol designed to optimally transmit HTML documents. But, in reality, more and more Web developers are assuming that the user will not want to save the Web page or lose network connectivity. I think that this is a mistake.

A lot of frameworks have come out recently that are designed to tackle the offline problem; the frameworks' approach is usually to run a database on the client. The database can cache data from the "home server," and if the user makes changes while offline, that database can write the changes back to the "home server" when it becomes available again. These frameworks don't do anything about all of the back and forth requests to the app server that AJAX applications generate.

Some developers try to tackle this problem by loading a miniature application server on the client via Java (or similar "applet" style technologies). This approach works. However, after a certain point, I wonder how many hoops someone needs to jump through to compensate for an inherent shortcoming of a particular technique before it becomes clear that a technique might not meet their needs.

Even assuming that you can put a miniature application server and database server on the client that can cache and sync with the master servers whenever possible, you still have not solved the problem of "saving a Web page." The user doesn't think they are using an "application"; if it runs in a Web browser, they treat it like a Web page. Users are always clicking the Back button (which messes up AJAX apps) because they expect it to work like the Undo button. And incidentally, it does work like the Undo button in a more traditional step-by-step forms-based application. Ironically, one of the biggest issues that AJAX addresses in traditional Web development is the stateless nature of the HTTP protocol — and yet it suffers from its own lack of state.

Let's take a "product finder" application as an example. In the application, the user selects various options as "must have" and "nice to have" features. Some of these are Boolean selections, while others might be numeric ranges, and one or two might be "one-of-many" or "many-of-many" options. Now, let's imagine that our user has narrowed her choices down to four products from the original 50. She decided to save the Web page to disk so she can e-mail it to her boss or coworkers for review. Whoops! Her boss and coworkers will likely have a problem if they try to bookmark the page or e-mail the link. In a traditional Web application, if the developer is smart, he or she will use GET rather than POST for these scenarios to ensure that the link accurately represents the application's state, and the page is quite easily saved in its current state.

I am not saying that AJAX applications cannot function like this; however, until users get used to the idea that the traditional model no longer applies, developers will want to find smart and creative ways of addressing this issue. One way of doing this would be to periodically "tag" the state with a hash code and redirect the browser to a URL that calls that hash code (for example, http://www.site.com/application/j7qw132j). This way, if the user hits the Back button, she goes back, say, two minutes in time (or 10 operations) rather than back to the beginning. Also, the user can e-mail (or bookmark) that link. Developers often build in E-mail This Page, Bookmark This Page, or even Save This Page buttons on their site, but it takes effort to build in the buttons, and users often miss those buttons or assume that they do the same thing as the similarly labeled browser functions.

I think that developers who work hard can find some creative, workable, and usable solutions for this issue, and their users will appreciate it.


  • Date: May 30th, 2008
  • Author: Justin James

Cyber-bullying- the impact and the consequence

This is a difficult story on many fronts. In reading the facts, it is hard to believe that this kind of thing can happen. There may be a desire to blame the victim- who should have been "smarter." There is also a desire to shake the perpetrator who clearly should have known better. But perhaps it is a cautionary tale that we can all learn something from on many levels- not only personal, but from a corporate standpoint as well.

On May 15, 2008, a federal grand jury indicted Lori Drew, 49, of O'Fallon, Missouri with one count of conspiracy and three counts of unauthorized computer access. If convicted, each count could net Ms Drew five years.

Why does this matter?

Allegedly, Ms. Drew, her 13 year old daughter, and Ms Ashley Grillis, 18, who was employed by the Drew family, created a fictitious MySpace profile for the purpose of harassing Megan Meier, a teenaged girl living on the same block as Drew and her family.

For the next four weeks, a flirtatious relationship blossomed between Ms Meier and the fictitious person that Drew and Grillis created. And then it suddenly ended with the fictitious person telling Megan "The world would be a better place without you." Megan hung herself in her bedroom about an hour later.

State lawmakers gave final approval on May 17th to a bill intended to deal with cyber-harassment. This bill is expected to cover several aspects of technology, identifying as illegal the harassment from computers, text messages, and other electronic devices as well as standard written and telephone communications.

From eFlux Media:

Republican Governor Matt Blunt, who will soon sign the final version of the bill, issued a statement saying that the social networking sites and technology have provided criminals with a whole new set of weapons against their victims and the new protections and penalties are highly needed in order to ensure a safer environment for everyone.

While this case is certainly tragic, it is thankfully not the norm in social networking- a phenomenon that is taking the web, and business, by storm.

What it tells us is that there are definitely boundaries, and states are now recognizing those boundaries and stepping up to set laws in place to enforce those boundaries.

Blogs, wikis, and other social networking tools are beginning to find their way into the business corporate culture. They are useful tools for communication and collaboration between business partners in both the internal and external corporate structure and will continue to grow. According to Forrester Research, the foundation technology, Web 2.0, will cost business US$4.6 billion over the next five years, making Web 2.0 hotter in terms of growth than the area of business intelligence.

I can see that. Seems like everyone I meet wants to add me to one friend list or another.

But as business embraces social networking, one thing is clear. They will have to embrace some policy definitions along with the tools to insure that employees understand where the lines are firmly drawn.

Does your business use any kind of social networking tools? Do you have a community blog on your intranet or use a wiki to explain the workplace jargon? How does business set the standards for your communication?


  • Date: May 19th, 2008
  • Author: Tricia Liebert

Alpha Five: Data-driven application development done right



Alpha Software specializes in creating tools that let developers easily create data-driven applications. Richard Rabins (Co-Chairman) and his brother Selwyn Rabins (CTO) showed me the ropes on the latest version of its Alpha Five development package, and I'm pretty impressed.

What is Alpha Five?

Alpha Five is a package that allows developers to rapidly and easily create data-driven applications. I know… we've all heard this promise a dozen times before, so now we're pretty jaded by it. In this case, I am inclined to believe that someone got the formula right. From the demonstrations that I saw, Alpha Five "connects the dots" that most of the mainstream products just simply leave unconnected.

For example, we're all familiar with the pain of putting together the standard master grid/detail view with a search box Web page. Here is a great example of the benefits of Alpha Five that I saw in action. Let's say that you need to put a grid component on the screen and bind it to a data view and a detail view component. So you bind the detail view to a data view and bind that data view to the selected item in the master data view. Next, you make a search area, add the validation, and add its information to the master data view's filter. It is a formulaic piece of code, yet we repeatedly keep writing it. The code usually takes about 30 minutes to create and tidy up — or even longer if you are not familiar with it.

Alpha Five makes this much easier. Instead, you put a grid component on the form, check a box to indicate that you want a detail view, and then select the fields for the master data view and the detail view. For the search area, check off fields to be "lookup" and add the constraints on the values entered. In less than 60 seconds, I saw Richard put together a form that always takes me 30 minutes.

In a nutshell, the folks at Alpha Software asked, "What are the top X tasks that developers do that involve gluing standard components together in the same way day in and day out?" Then they took that list, wrote their own version of the components, and made those standard "cookbook recipe" combinations into component properties. My first reaction when I watched Richard and Selwyn show this off was, "Wow, this makes it a snap to write that standard CRUD Web application that I keep being asked to write!"

They also showed off the company's Script Genie; it reminds me a lot of Outlook's Rules Wizard, but it generates code. Script Genie looks pretty slick: You select the actions that you want to take in response to various events. Then, you provide the parameters to the actions by selecting the properties of the objects that would be in scope and are appropriate. For example, you can use Script Genie to hook onto a button being clicked, select the Send Email action, and tell it to get the subject line from a configuration file and the body from a field on the screen.

Regular readers know that I'm not a huge fan of AJAX. However, the AJAX libraries that Richard and Selwyn showed me seem to be high quality and worked as promised. Of course, you still need to cope with the usual AJAX problems (like constantly hitting the Web server, but at least Alpha Five uses persistent TCP/IP connections which helps); but if you need to use AJAX, Alpha Five's libraries look pretty good.

The technical details

Alpha Five can make desktop apps (that are interpreted through a runtime system, similar to the JVM or .NET CLR) or Web apps. (Alpha Software's application server can run side-by-side with IIS, and the company is working on a clustering application server, as well as a non-Windows version.) The Web system makes pages similar to PHP, ASP, or JSP, with the A5 tags embedded in between HTML. The language Alpha Software uses is XBASIC, a variant of BASIC.

For database connectivity, the Alpha Five Standard Edition uses its own database engine; the Alpha Five Platinum Edition supports other databases. Like Cognos, Alpha Software's tools produce a "standardized SQL," which then gets translated to the appropriate SQL statements depending upon which SQL driver you use. (Note: You can use ODBC if you want, but Alpha Software has brewed its own drivers for databases that are faster since they don't have ODBC's overhead.)

A while back, I came to realize that most data-driven applications can be done in Microsoft Access or FoxPro; there's a thin veneer of data validation and business logic on top of a 10 - 30 table database — nothing too complex. Tools like Ruby on Rails address this and so does Alpha Five.

Richard admits that Alpha Five is not a "kitchen sink" system like J2EE or .NET. But from what I saw, it can handle about 80% of the applications most developers write with significantly less effort than J2EE, PHP, or .NET require. By focusing on the stuff that most developers spend all day on (instead of what a few developers spend a little bit of time on), the Alpha Software team has created a system that does exactly what most developers need. Watching Richard and Selwyn go through the motions of using it, programmers will still need to write code by hand, but they wouldn't need to write as much code.

Data binding done right

We all know how I usually feel about these systems. I like to throw phrases out there like "shake 'n bake programmers" and knock "drag 'n drop data binding." I'll be the first to admit that years of hearing vendors promise "systems so easy, your secretary will be writing her own applications!" that I just don't believe it. What I saw of Alpha Five wasn't an attempt to get the secretary to be writing Web applications, but it was something that lets a programmer leverage his or her time better.


  • Date: June 5th, 2008
  • Author: Justin James