Wednesday, January 28, 2009

Saving Time Through the Command Prompt Explorer Bar

In the last couple of posts, I have been mentioning different command line tools that I've been using (specifically Nant and SchemaSpy).  While some people love command line applications and using the command prompt, there are some that cherish the nice Windows GUI and the mouse.  The issue with the GUI is that applications like Nant and SchemaSpy don't really work well out of the box if you double click on them.  This means that in order to have double click functionality that does something, you will need to script it out using tools like shell or PowerShell scripting that executes the configured command for the desired results.  If you don't create (and subsequently debug) the script wrapper, you will find yourself opening up the command prompt, navigating to the directory, and then typing in the command manually.  Thankfully, there's a tool out there that makes things easier.

 

The Command Prompt Explorer Bar

The Command Prompt Explorer Bar is an open source tool on the Code Project web site developed by Pavel Zolnikov that allows you to place a command prompt window inside of your windows explorer window (see image below).  While this immediately doesn't sound useful, it offers some powerful productivity features that a typical command window doesn't.  First, when you open the Command Prompt Explorer Bar, it immediately takes you to the directory you're in.  So, if you are in the directory that contains the Nant script you want to manually execute, you can open the command prompt and immediately type in your command.  In addition, as you move around windows in the explorer window, your command prompt automatically synchronizes with it.  Last but not least, the Command Prompt Explorer Bar offers the ability to have macros.

 

Command Prompt Explorer Bar Screen Shot on Windows Vista
Figure 1: The Command Prompt Explorer Bar for a user's (named llama in this case) home folder.

 

Where to Download the Command Prompt Explorer Bar

As stated previously, the Command Prompt Explorer Bar is an open source tool on the Code Project web site.  You can download the installation binaries and/or the source code from this location. After you have downloaded the installer for it, you will be able to begin using it.

 

How Do I Open it?

The Command Prompt Explorer Bar is very simple to use since it's just an embedded command prompt at it's core.  It works in both XP and Vista and there's no special window style needed to have it open (folder bar is supported as is Vista's Aero interface). There are two ways to open the Command Prompt Explorer Bar.  First, you can go to the View Menu > Explorer Bar > Command Prompt menu option.  The second way is to just press Ctrl+M in the folder.  NOTE: Ctrl+M does not work if you are literally on your windows desktop, a file system/explorer window must be open for the Command Prompt Explorer Bar to open.

 

What Are Those Icons For?

As you may have noticed from the above image or if you've installed the Command Prompt Explorer Bar already, there are a series of buttons/icons on the left sidebar.  These buttons help provide some quick additional functionality.  Going from top to bottom, the buttons are as follows:

  • Command Menu - Provides the command prompt context menu, similar to right clicking inside of the prompt.  Clicking directly on the button shows an "About" dialog.
  • Synchronize - Turns on and off the ability for the command prompt to synchronize as you move through folders above it.
  • CLS - Sends the CLS command to the command prompt; clearing the screen.
  • Get Selected Folder Items - Enters all items you have selected in the folder view above in a <space> separated list.
  • Enter Key - For those who don't like to press the enter key on the keyboard...I think.
  • Esc Key - Used to clear a partially typed line; same as the Escape Key on the keyboard.
  • Macro - A drop down menu containing a list commands that you can use for quick access. (more on this in the next section)
  • Grow - Grows the constraints of the Command Prompt Explorer Bar.
  • Shrink - Shrinks the constraints of the Command Prompt Explorer Bar.

 

Using Macros

When the Command Prompt Explorer Bar was created, Pavel Zolnikov entered in the ability to create and use macros.  The macros that he supplied with it were very much .Net Command Prompt tools.  Browsing the list, you'll find a number of macros for generating a type library, register a COM compliant assembly, and registering an assembly in the GAC.  There are also some macros for traditional command prompt commands like attrib and cd.  There is also a few macros that contain a {1} in their name.  What this syntax represents is the first selected item in folder list above.  For example, if you highlight a folder and then call the "cd {1}" macro, it executes the change directory command into the selected folder in the command prompt.  It does not sync back to the folder view however.

 

Adding New Macros

While the default macros are useful, Pavel also provided us the ability to create our own macros.  This is where it shines.  To create a new macro, Click on the Macro menu button directly.  This will open the C:\Program Files\Command Prompt Explorer Bar\macro.xml file.  Inside of this file you'll see some very basic XML syntax which is described below.

  • <group> - The document element as well as elements that denote a grouping/submenu list of macros
    • text - Sets the text to be shown as the submenu item.
  • <macro> - Denotes a macro-ed command.
    • text - Sets the menu text to be shown for the macro
    • execute - a boolean value telling the command prompt to execute the macro when selected or not.
    • command - the command the macro will execute upon selected if different than the text.(optional)
  • {0} - types out all currently selected files in the folder view
  • {1} - types out the first selected file in the folder view (subsequent numbers represent that element of selected items; i.e. {2} is the 2nd selected item).
  • {1:n'} - types out the last selected file in the folder view (n' represents the inverse order of the files selected)

Now that we've looked at the syntax, let's add a new macro group with a Nant command.  This will assume that you have Nant installed and configured with the Nant.bat file in your system path as described by the Nant installation and configuration steps.

   1: <group text="Nant">
   2:     <macro text="completeBuild {1}" 
   3:            execute="true" 
   4:            command="Nant -buildfile:{1} completeBuild" />
   5: </group>

 

Adding this snippet to the file (inside of the parent <group> xml document element), the new macro group and command is instantly added to the macro menu (no close and reopen needed).  This command allows us to select our build file in the folder view and then executes the macro to call it's "completeBuild" task that it presumably contains.  Quick and easy for executing command line tools and applications without having to navigate and type in the command in a command prompt nor mess with scripted wrappers.

 

In Summary

While this tool isn't the most amazing one out there, it is very useful if you find yourself working in a command prompt a lot.  Great tools and utilities like Nant and SchemaSpy can be easily reduced to a simple click of a macro while you never have to leave the window you are browsing the file system with.


kick it on DotNetKicks.comShout it

Wednesday, January 21, 2009

Database Documentation using SchemaSpy

One of the largest challenges that developers and software project managers have a difficult time with is how to keep documentation in sync with the code elements.  While there are a large amount of tools that allows for documentation to be created based on code comments (i.e. nDoc, JavaDoc, SandCastle, etc.), there are not a lot of tools that do the same for Databases.  Now, there are tools that will document a database after the fact (or will create the database based on the documentation you're creating), many are very expensive or appear to be no longer support.  One tool that I have started using recently for database documentation was recommended in the book The Productive Programmer by Neal Ford.  The tool is called SchemaSpy.

 

For the sake of brevity, this post will cover how to generate database documentation for only Microsoft SqlServer 2000 and 2005 databases using SchemaSpy.

 

What is SchemaSpy?

SchemaSpy is a Java command-line application that will connect to your database and generate information about the tables and their relationship.  SchemaSpy does does not address any database programming elements (i.e. Functions, Triggers, Stored Procedures, etc.); however, supplies a large amount of information on the tables and views themselves along with their relationships.  It also evaluates your indexes and keys in order to build relational diagrams.  Furthermore, it retrieves information from the database tables in order to give you a view of the number of records, the types of columns, and a large amount of other information for it.  In addition to large amount of information, it also provides notification if there are any anomalies in the schema; such as implied relationships between columns (no foreign key constraints), tables without indexes, columns marked as both "null" and "must be unique", single column tables, and more.

 

What does SchemaSpy Produce?

Below are a few screen shots of the documentation that SchemaSpy creates for the Northwind database.

The Index page for the documentation SchemaSpy produces. 
Figure 1: SchemaSpy's Index page for the Northwind Database.

 

An example of the relational diagrams produced by SchemaSpy
Figure 2: An example of the the diagramed relationships SchemaSpy produces

 

What do I need to start using SchemaSpy?

SchemaSpy requires 4 separate components to be installed in order to work properly:

  • The SchemaSpy application itself (version 4.1.1 as of this post) - Download
  • The Graphviz Diagram Engine - Download
  • Java Runtime Environment (v1.5 or higher)  - Download
  • The Database Driver(s) required for a Java Application to connect to your database.
    • MS SqlServer 2000 / 2005 - JTDS v1.2 - Download

Once the 4 components are downloaded and the JRE and Graphviz are installed, the next thing we have to do is install/configure the JTDS drivers (more on why JTDS instead of traditional JDBC in a moment).  As of this post, SchemaSpy only works with the 1.2 version of the JTDS driver and requires the jtds-1.2.jar file to be in the C:\Program Files\Java\Shared\jtds directory.  The driver jar file can be stored in other directories; however, an additional command parameter has to be passed to SchemaSpy if you do (see below).  At this point, the only thing that's left is to execute SchemaSpy with the proper command line arguments. 

 

Running SchemaSpy

After all of the above components are installed, you are able to execute SchemaSpy from a command prompt using the following (general) syntax:

java -jar SchemaSpy_4.1.1.jar -t databaseType -host serverName -port portNumber -db dbName -u userName -p password -s schemaName -o outputDirectory

Let's dissect these command parameters a bit:

  • -t  : This identifies the type of the database we're using.  Since this post is focusing on MS SqlServer using the JTDS driver, the database type will be either mssql-jtds (for SqlServer 2000) or mssql05-jtds (for SqlServer 2005).
  • -host  :  This is required by our type.  It signifies what database server to connect to.
  • -port  :  This is required by our type.  This signifies what port to connect to the database.  This will not always be 1433 (see below).
  • -db  :  This tells SchemaSpy what database to diagram for us.
  • -u  : This tells SchemaSpy the database user name to login with.
  • -p  : This tells SchemaSpy the database user's password to login with.
  • -s  : This tells SchemaSpy what schema to read and diagram.  The user credentials provided must have access to at least read this schema.
  • -o  : This tells SchemaSpy the output directory to generate the documentation.
  • -dp  : This tells SchemaSpy the path to locate the database driver file (not used in this example)

An example of a fully completed command:

java -jar SchemaSpy_4.1.1.jar -t mssql-jtds -host myDBServer -port 1433 -db Northwind -u myDbUser -p password -s dbo -o NorthwindDocumentation

If your projects use Sql Server's integration authentication option, you can use the -sso option.  The -sso option allows you to remove both the username (-u) and password (-p) parameters and use the identity of the account used to called the Java Runtime Environment.  Modifying the example above to use integrated authentication, we get the following:

java -jar SchemaSpy_4.1.1.jar -t mssql-jtds -host myDBServer -port 1433 -bb Northwind -sso -s dbo -o NorthwindDocumentation

 

Why JTDS instead of the JDBC drivers?

As I mentioned above, I recommend using the JTDS Java Database drivers instead of the traditional JDBC drivers that Microsoft offers off of their web site.  While the fact that JTDS is a single driver as opposed to the 2 separate JDBC drivers is a plus, the main reason is the trouble I had getting the JDBC drivers to work with SqlServer 2005 databases.  If I was working on documenting a database I'm creating for a project on my local system using SQL Server 2005 Express Edition, it would always give me an error stating that the "variant" data type is not supported.  After a lot of research and trial and error, the only result I could only get this working by using the JTDS driver.

 

How to use SchemaSpy to Diagram a Named Instance

When installing Microsoft Sql Server, you have the option of installing it as a stand alone service or a named instance.  In the event of a named instance, you would normally connect to it in your .Net code (or via Management Studio/Query Analyzer) as ServerName\InstanceName.  For example, the default instance of a Sql Server 2005 Express Edition is localhost\SQLExpress.  In order to connect to a named instance database with SchemaSpy, you do not need the Instance Name of the database (just the server name as if it wasn't an instance), and you have to use the database's TCP Dynamic Port instead of the typical 1433.

You can locate a named instance's dynamic port through the following steps:

  1. Open the Sql Server Configuration Manager application (either through the Programs Menu or a MMC Snap In)
  2. Expand the Sql Server 2005 Network Configuration element
  3. Click on the Protocols for "INSTANCE" where "INSTANCE" is the name of your named instance
  4. In the right pane, double click on TCP/IP
  5. In the TCP/IP Properties dialog that appears, click on the IP Addresses tab.
  6. Towards the bottom of the IP Addresses tab, you'll find the TCP Dynamic Ports value to use for SchemaSpy

The above steps were taken based on a local installation of SQL Server 2005 Express Edition.  Your steps may vary depending upon configuration.

 

Conclusion

SchemaSpy is a tool that I have been using to help with some of the documentation pains that I have experienced on some of my personal and professional projects.  Being able to add the command into a build script to automatically keep the documentation up to date is a huge time saver and is invaluable as people migrate onto the project(s).  I hope you find it as useful as I have, and to assist further, I have added a simple step by step guide to setting up and begin using SchemaSpy below. 

 

The Step-By-Step

  1. Install the Java Runtime Environment version 1.5 or higher if it is not already installed.
  2. Install Graphviz Diagramming Engine.
  3. Download the SchemaSpy jar file.
  4. Download the JTDS v1.2 driver and place the jar file in the C:\Program Files\Java\Shared\JTDS directory.
  5. Obtain User Login Credentials with the proper permissions to read the schema for the database you will be documenting if integrated authentication is not available.
  6. Obtain the TCP Dynamic Port if the database you are accessing is a named instance.
  7. Open a command window and navigate to the location of the SchemaSpy jar file.
  8. Execute the SchemaSpy jar file using the proper command line parameters.


kick it on DotNetKicks.com Shout it

Wednesday, January 14, 2009

Filtering Table Results with jQuery

A few weeks ago, I was looking for a way to filter records in a table.  The screen that I was going to use this one was a composite/advanced search screen to where after the results are populated, the user can continue typing in search results into other fields and it would auto-filter.

 

There are a large amount of jQuery plug-ins that offer table filtering features.  I reviewed the TableSorter plug-in; however, I didn't want a filtering system where 1 text box would filter all columns.  That plug-in works extremely well and I am using it in other areas, but I'm looking for a text box-to-column filtering mechanism instead. Bill Beckelmen, who has a lot of great posts and examples on the TableSoter plug-in, suggested trying the jQuery Column Filter or tablefilter plug-ins.  Both were better; however, also auto-created the text boxes in another header row for the table.  After looking a bit more, I came to the conclusion that I would need to write my own functionality.  If I continue working on refining this code, I will probably see about turning it into a plug-in for easier use.

 

Post Downloads:

Table Filtering with jQuery Example - TableFilter.zip

 

The filterColumn Function:

At the heart of the filtering process is a JavaScript function called filterColumn.  This function takes 2 parameters.  The first parameter takes the text name of the table column that is being evaluated.  The second parameter is the text value to filter on.  For the sake of the example, the filterColumn function will be bound to each text box's onKeyUp event; passing it's current value for the filtering text.

Inside of the filterColumn function, 3 things occur to make the filtering mechanism work.  First, the two input parameters are inserted into regular expression patterns that will be used to locate the table column header as well as the records in that column once found.  The second thing it does is loop through the column header (first table row in the thead tag that contains th tags...or "#resultsTable thead tr:first th" in jQuery selector syntax) to locate the column's index.  Lastly, it loop through the table's records using the column's index and sets the row's display style to "none" if it doesn't match the filtering criteria.

   1: function filterColumn(columnHeader, value){
   2:  
   3:     // set regex objects with the appropriate patterns.
   4:     var headerPattern = new RegExp('^' + columnHeader + '$', 'i');
   5:     var filterPattern = new RegExp('^' + value + '', 'i');
   6:  
   7:     // initialize the column identifier
   8:     var colIndex = -1;
   9:     
  10:     // loop through the header's first row of cells
  11:     var headerRow = $("#resultsTable thead tr:first th");
  12:     headerRow.each(function(n){
  13:         if (headerPattern.test($.trim(this.innerHTML))){
  14:             colIndex = n;        
  15:         }    
  16:     });
  17:     
  18:     // check to see if the column was found.
  19:     if (colIndex > -1){
  20:         
  21:         // loop through each table body row and evaulate the proper cell.
  22:         var bodyRows = $("#resultsTable tbody tr");
  23:         bodyRows.each(function(n){
  24:             if(!filterPattern.test($.trim(this.childNodes[colIndex].innerHTML))){
  25:                 this.style.display = 'none';
  26:             }
  27:             else {
  28:                 this.style.display = '';
  29:             }
  30:         });
  31:     }
  32: }

Next Steps:

I have a lot of refinement to go on this function if I am thinking about converting it into a plug-in at some point.  I need to make the table's id not hard coded and bind the onKeyUp events when the search button is pressed instead of having it attached all the time in the HTML.  In addition, I need to look into incorporating a zebra-striping plug-in as well to have it address the row styling after the filtering. 

The code is a great starting point and it's very useful as is.  With a little refinement, it can provide a very robust mechanism for simple table filtering without having to learn and use a very complex plug-in.


kick it on DotNetKicks.com

Wednesday, January 7, 2009

Goals for the New Year

Happy New Year!  Ok, so I'm a week late.  With the start of each year comes a tradition that some view as a farse while others hold as an event of refocusing.  New Year's Resolutions are are great time to reflect and focus what someone wants to achieve.  While I'm not big on making my personal goals known like some other bloggers (it's just not my cup of tea), below are a few goals I've set for myself that relate (directly or indirectly) to this site.

 

Blog More

This is a given.  2008 was a huge year of transition for me in my personal and professional life.  While I was able to churn out more post than I had before, I struggled on many weeks.  I'm hoping to be able to hit my goal of once per week this year.  Hopefully I'll be able to keep it up while also providing interesting topics for everyone to follow.

 

Learn F#

One of the things that I've wanted to do in recent months is expand my professional arsenal.  Coming from a Java background and transitioned into the .Net world almost exclusively now, I've somewhat been stuck trying to stay afloat with just C# and VB.Net (ASP.Net included).  While I am still working on keeping up with the times and changes in those languages, I'm wanting to expand into F# as well for a truly different perspective. 

 

Learn Silverlight 2

I dabbled in Silverlight 1 while I was also learning XAML in general for WPF.  It was fun but I didn't get too deep into it due to the JavaScript model that it used and the obvious changes Silverlight 2 (then 1.1 alpha) had.  Now that Silverlight 2 is out.  It's time for me to get back to work on it and begin getting a subtle level of proficiency in it.

 

Finish the Books I Start Reading

For those that know me, I love reading; however, I tend to read books in parallel and rarely finish technical books.  This works well for some books since they are great for references just as much as reading cover-to-cover (i.e. Wrox's Professional C# 2008, etc.).  The issue comes in when I'm reading a book to clarify a topic or to truly learn, I tend to lose attention on the material.  This goal is to simply push myself to finish the books that I feel need to be finished.  For example, here are all of the books I'm currently reading:

 

Learn DDD

One concept that is being shown a lot of attention recently is Domain Driven Design.  It's got some great concepts for managing complexity and the research I've done on it so far has yielded some interesting ideas on my application designs.  I just recently picked up a copy of Eric Evans' book and will hopefully get to it very soon to clarify a lot of the items I've had some trouble with.

 

Use jQuery More

I love jQuery.  Of all of the JavaScript frameworks that I've used on both personal and professional projects, it is the one I prefer hands down.  With that being said, I haven't had much spare time to work on any personal projects that require new ways of using it so such posts have been reduced a bit.  I have projects queued up so hopefully there'll be more jQuery related posts to come up in the future.

 

In Summary

I'm sure that I'll have more goals as the year progresses; however, for right now I feel like I have a good focus for the next handful of months.  Next week I'll start up the normal posts again.  This year will have a more diverse mix of posts with more tools and different technologies and techniques coming.  Hopefully I'll be able to stick to my goals :-).

Wednesday, November 19, 2008

Book Review: The Productive Programmer by Neal Ford

I'm going to do something a bit different than my normal posts and review a book I just finished reading.  I read a number of books each month and this will provide me an outlet of to point people to on some of my recommendations.

 

 

I don't know how I discovered The Productive Programmer by Neal Ford (O'Reilly Press 2008); however, I know that it was a great purchase.  The book covers various practices on how to become a more productive programmer through tips, tricks, and tools.  The book is split into two parts.  The first part really focuses on mechanics; how things are done and how they can be done better.  This section of the book focuses on a number of great recommendations for tools to use to make yourself faster as well as recommendations on good practices that make you faster or more automated.  The second part of the book is about the practices of programming.  This section focuses on refactoring tips, code analysis, metrics, and general philosophies.

 

The books is great for anyone who is looking to do their job better or make it easier by finding ways to remove the repetitive ceremony that we all encounter.  While the book is very Java and Ruby focused, he does point out a few examples in C# and tools specific to the .Net community as well.  He also draws on the philosophy that to truly know a subject, one should focus beyond their current problem domain to see how others address it.  I found very few items in this book that I couldn't find a counterpart in the .Net world or be able to translate it very easily.

 

Pros:

  • Easy to read
  • Very good tips starting at page 1
  • A large amount of small side notes drive key points home
  • Lots of examples

Cons:

  • Would like a larger variety of examples in different languages

 

If you are interested in finding out more about the book, please refer to the following links:

O'Reilly

Amazon.com

ProductiveProgrammer.com

Google Books

Neal Ford's Website



kick it on DotNetKicks.com

Wednesday, November 12, 2008

Justifying the Use of Build Scripts

Have you read about all of the great benefits of automation and continuous integration?  Have you talked about tools like Nant and a build server to your colleagues, bosses, and your friends?  Have you pitched the idea and desire to see it implemented (in part or completely)  only to have it justified too costly of an initial investment?  If you have, then you're probably like many individuals out there that have tried to find the right resource or answer to implementing automation in some fashion even though the benefits are already justified to yourself.  In this post, I'm going to discuss some of the components of continuous integration and also discuss how to get data to justify the (manual) use of build scripts to "automate" a scenario initially.  The scenario is not ideal (since build servers would enhance automation to a whole new level);however, the tiny victories are sometimes the best ones to start with.

 

Some Traditional Pieces of Continuous Integration

While the grand vision of continuous integration sounds great, getting there isn't as simple as everyone lets on or would like.  While implementing a continuous integration strategy can sound simple compared to other implementations, the road to such is marked with multiple milestones.  In order to get from a completely manual process to a completely automated one, it's best to identify some of the various pieces that many consider under the continuous integration title.  Below is a small list of items that are traditionally part of continuous integration:

  • Build Scripts
    • Traditionally XML files that are used by a build utility like Ant, Nant, Rake, or MSBuild.
    • Have the ability to execute a sequence of (possibly dependent) tasks that goes beyond just building the code.
  • Build Server
    • A server used to read and execute the build scripts
    • Configured to integrate with a version control system
  • Unit Testing
    • Code based tests used for testing the application's code
    • Typically associated with frameworks like MSTest, NUnit, and xUnit
  • UI Testing
    • Similar to Unit Testing; however, scripted usability test of the UI.
    • Frameworks like Selenium provide the ability for this level of automation.
  • Documentation Generation
    • Tools used read comments from code and/or the version control system to generate and update documentation
    • SVN2Wiki (by Neal Ford), yDoc, Sandcastle, and others provide ways to address this item.
  • Automatic Deployment
    • This is ultimately the culmination of all of the items.  The ability to check in code, test it, document it, and deploy it all in an automated fashion.
    • Many times is considered the truly last stage due to hesitancy to automatically placing code into a production environment.

 

What to automate first?

Looking at the list above, it is fairly easy to see identify that the Build Scripts provide the amount automation and flexibility that can extend as the road to continuous integration evolves down the milestones.  Because of their flexibility, they hold the key in solving the pain points that will fuel your justification. 

 

A Scenario That Could Use Automation

Imagine that you are in an environment where the developer builds and configures the code for multiple environments, copies the code to a staging location on a file share, and then waits while other teams (i.e. QA) takes the code to deploy it to their location.  In many instances, a bug comes back from the QA team and the process repeats itself; a rebuild and deployment into the staging area for each environment. 

Let's look at just this process in more details to understand the cost of it.

  • The Developer may have to do separate builds for each environment
  • The Developer has to navigate out to the file share
  • The Developer has to backup or delete the files currently in the staging location
  • The Developer navigates to each separate build destination
  • The Developer has to copy the files out to the staging area from each build destination
  • The Developer sends notification to various parties that the code is ready.

Now, your environment may be a bit different than what is portrayed here (the number of different builds and how they are distributed, such as .Net's Publish feature or using an FTP instead, for example), these events usually happen in some fashion in many companies based on my discussions about this with other developers. 

 

Identifying the Cost Savings of Build Scripts

Looking at these 6 steps, how much time does it take you to do them individually?  How long does it take your computer to do each build, for you to navigate to each folder, and to copy/backup files over the network?  How much time do you spend being distracted between these steps?  How many times do you have to do this because of bugs from QA? These are the question that will allow you to begin quantitatively justifying automating just these 6 steps using build scripts. 

Depending on your project size and complexity, the above 6 steps can take anywhere from 5 minutes to 30minutes (and even longer in some instances).  Multiplying this amount of time by the number of times the process occurs over release or a few months will help paint a better picture on the amount of time just the build scripts can save. 

Now, while this identifies the cost in time we are hoping to automate, we also have to look into the time it takes to create the build script.  If you have never researched build scripts before, this may take some time through research as well as implementation.  Build utilities, like those listed above, offer a wide variety of predefined tasks that will make the above tasks fairly simple once you learn it.  The documentation in most cases is decent to help make this a simple transition; however, when testing the script itself until you are comfortable with it may take an hour or two.  The good news is that once you have a script for a build utility written, they are very easy to turn into templates (thanks to variables/properties being able to be set in the scripts) for reuse on other projects.

Now that we have identified the length of time the process takes and the amount of time it will take to create the script, we only have to identify how many deployments it will take until the savings is seen. 

 

Conclusion:

While continuous integration is the goal on the horizon, we looked at a scenario where we justified the first step in simple automation.  This post describes creating build scripts that would be executed manually by the developer (in our scenario) that would do everything in that script automatically in the background.  This isn't the ideal situation; however, it is a step closer to automating the process even more (through a build server).  The main thing to identify here is that just because a build server is not available or cannot be justified at this time, trying to move forward with the build scripts will save time now and in the future. 


kick it on DotNetKicks.com

Thursday, November 6, 2008

Starting with jQuery - Using jQuery with Web Forms

In this sixth and final entry on a series of post focused on using jQuery with no prior knowledge, I dive into applying jQuery into the traditional ASP.Net web form environment.  The example code covered in this entry focuses on applying the jQuery Validation plug-in against 2 sets of input in the same form.  To make the example more realistic, the form fields are contained inside of content page to ensure the code works with ASP.Net's client id renaming feature/annoyance.

 

If you would like to review the previous posts in this series, please feel free to review the links below:

 

Code Downloads for this Post:

ASP.Net Example project

 

An Overview of the Example:

The example project provides the following files:

  • Default.master 
    • The master page used in the example
    • Contains the jQuery-1.2.6.js reference
  • CustomerExample.aspx
    • The content page referenced in the example
    • Contains the jQuery.validate.js reference
    • Contains the example's JavaScript reference
  • jQueryExample.js
    • Holds the custom JavaScript code to manage the validations

Starting with jQuery - Solution Explorer
Figure 1: The example's Solution Explorer

 

When the CustomerExample.aspx file is viewed in a browser, we see that the form is divided into two field sets (see Figure 2 below).  The left field set is to simulate a customer information form which requires the First Name and Last Name fields filled.  Should the user opt to enter a phone number, the field will validate against the format specified.  The right field set is simple a text box for a user to insert their email address to subscribe to a fictitious newsletter.  In this case, the email address field is required and validated as an email address using the Validation plug-in's email validation.

 Starting with jQuery - Example Screenshot
Figure 2: The example form(s)

 

Looking at the Code Behind:

While searching on the web, I found a number of different ways of linking an ASP.Net control's client id to jQuery, the simplest and cleanest that I came across was suggested which is found in the page's Page_Load() method.  In this block, I am calling the ClientScript.RegisterHiddenField() method to create a hidden form field with the name of the server controls and containing the value of the server control's client id, prefixed with a pound (#) symbol.  While I chose this method for the example, I highly encourage everyone to do additional research into alternative methods (which are out there) to accomplish this task if you do not like the idea of adding this amount of additional code.

 

Diving into the JavaScript:

Opening up the CustomerExample.js file, we see some variable declarations first thing, followed by the code that will be executed when the document is in a ready state and the form button's client side code.  Inside the code the executes once the document is ready, our custom phone number validation rule is added to the form validator.  Afterwards, we wire the page's form to the validation mechanism. NOTE: ASP.Net Web form applications only allow 1 server-based form on the page.  Lastly, the variables declared at the top of the file are provided the string values of the hidden form fields created in the code behind, and the First Name field is given focus.  At the bottom of the file, two functions are provided that dynamically add and remove the validation rules from the appropriate fields using the variables that hold the hidden field values to pass in the appropriate control ids.

 

Conclusion:

When I started using jQuery a few months ago, I was very impressed with how easy it was to implement and learn as well as how small it was.  Since then I have been busy using a number of different UI plug ins for it as well as integrating it into ASP.Net and Classic ASP applications for my company.  As I explore jQuery more, I will be posting more about it as well.  I hope that this series has provided you with the basic understanding on how to get started with jQuery as well as locating and using some of the many plug-ins available.  In addition, I hope that this last post has provided information for you to begin integrating it into your ASP.Net applications.


kick it on DotNetKicks.com