Speaking on ColdFusion @ Screaming Monkeys

I will be speaking next month at the Screaming Monkeys Web Guild in Fort Wayne, IN on ColdFusion and Framework One.

March 15, 2010
Northeast Indiana Innovation Center

3213 Stellhorn Road
Fort Wayne, IN 46815

I will be giving two presentations: 1) An Introduction to ColdFusion and 2) Building Applications with Framework One. An Introduction to ColdFusion will cover all the conveniences in ColdFusion’s toolbox, including PDF manipulation, charting, hibernate (orm), image manipulation, file uploads, MS Office interoperability, Verity Search Collections, and much more. Building Applications with Framework One will walk though building a ColdFusion application easily and quickly by leveraging the built in convetions of the framework.

ColdFusion

Comments (0)

Permalink

The Two Rules of Software Development

When it comes to software development, there are only two rules that apply.

  1. There is no wrong way, as long as it works.
  2. There is ALWAYS a better way.

Software Development

Comments (0)

Permalink

jQuery: Form Field Highlight

A really nice way to enhance user experience, when working with HTML forms, is to “highlight” the background color of the element that contains the form field that has focus. With jQuery, this can be achieved very easily using its event handlers and :input filter. What makes this approach very convenient is that you don’t have to modify any HTML to enable this functionality. Click the image below to see the example:


jQuery Form Field Highlight

Javascript:

$(document).ready(function() {
$(':input:not([type="submit"])').each(function() {
$(this).focus(function() {
$(this).parent().addClass('formFieldFocus');
}).blur(function() {
$(this).parent().removeClass('formFieldFocus');});
});
});

HTML:

<div>
<label for="text_field">Text</label>
<input type="text" id="text_field" name="some_text" />
</div>

jQuery

Comments (0)

Permalink

Flex: Update a DataGrid From a Map’s InfoWindow

Michael Schultz asks:

Can I update a DataGrid based on data captured from within a Map’s InfoWindow?

The answer is yes and it’s surprisingly easy. Click the image to view the example. The source can be viewed by right clicking the flex application.

Update DataGrid from a Marker's InfoWindow

To accomplish this, you’ll have to think about what you need to make this happen:

  • An ArrayCollection that will be the DataGrid’s dataProvider
  • A custom component that will be used as the InfoWindow’s content
  • A value object that will represent each person

When you click on the map to add a marker, the following objects are created:

//marker object
var marker:Marker = new Marker(e.latLng);
//value object that represents the person
var personInfo:PersonVO = new PersonVO();
//custom view component for the marker's info window
var nameInput:NameInput = new NameInput();

You then have to pass the personInfo object to nameInput, which is the custom component for the marker’s info window:

//pass a reference of the person object to the info window's custom component
nameInput.setPersonInfo(personInfo);

Then:

//append data to the array collection
acMarkers.addItem({label: label, marker: marker, personInfo:personInfo});
//add event listenter for when the marker is clicked
marker.addEventListener(MapMouseEvent.CLICK, function(e:Event):void {
//open info widow
marker.openInfoWindow(new InfoWindowOptions({customContent:nameInput, width:300, drawDefaultFrame:true}));
});
//add maker overlay to the map
map.addOverlay(marker);

When you update a name in the marker’s info window, it appears in the data grid. How does this happen?

When you set the data grid’s dataProvider attribute, you’re simply passing a reference to an already existing array collection. When the array collection is updated, the change is reflected in the data grid, but only because our array collection is bindable.

Each time a marker is created, a value object called personInfo is created from a bindable class called PersonVO. This object is then added to: 1) the array collection that populates the data grid and 2) the component (nameInput) that makes up the content of marker’s info window. Neither the array collection nor the component actually hold instances of personInfo; what they do is reference it - they only contain pointers to its location in memory. Since it’s bindable, when changes occur to this object, those changes are reflected everywhere it’s referenced. Thus, when you update a person’s name from the info window, the change occurs in the data grid because it references the same location in memory.

Flex

Comments (5)

Permalink

MooTools: Showing Form Validation Messages

I’ve written a function, with MooTools, that will inject inline messages into a form. View the example.

function showErrorMessage(field, errorMessage) {
var    fieldGroup = $(field).getParent(); //form field's parent element
var errorElement = new Element('div');//error message element

if (!fieldGroup.getFirst().hasClass('errorMessage')) {

//add error message to error message element
errorElement.appendText(errorMessage);

//add class to error message element
errorElement.addClass('errorMessage');
// add class to the form field's parent element
fieldGroup.addClass('error');

//inject error message into form field's parent
errorElement.inject(fieldGroup, 'top');
}

}

This function, showErrorMessage(), can be used with either client-side or server-side validation.

If you’re using showErrorMessage() with client-side validation, there is a companion hideErrorMessage() function you can use for when validation passes.

function hideErrorMessage(field) {
var    fieldGroup = $(field).getParent(); //form field's parent element
var errorElement = '';

if (fieldGroup.getFirst().hasClass('errorMessage')) {
errorElement = fieldGroup.getFirst();//error message element
//destroy error message element
errorElement.destroy();
//remove class from form field's parent
fieldGroup.removeClass('error');
}
}

JavaScript

Comments (0)

Permalink

ColdFusion: Integrated Authentication with SQL Server 2005

Have you ever wanted to stay away from using mixed mode authentication in SQL Server 2005, but were told that you had to enable for SQL Server to work with ColdFusion? Forget what you’ve been told! You actually can use windows/integrated authentication with ColdFusion and SQL Server 2005. Please be reminded that ColdFusion must be running on windows for this to work.

The following shows how to enable this on a CF single server installation. If you are running ColdFusion 8 Enterprise on a mulit-server installation, please be aware that your folder paths *will* be different.

<!–more–>

Step 1- Download the JDBC driver.

Download the SQL Server 2005 JDBC driver and extract it.

Step 2 - Place the files on the server.

There are two files you want to place on the server. The first file is the JDBC driver. It’ll be located at extracted_folder\sqljdbc_1.2\enu\sqljdbc.jar. You’ll want to put this somewhere on the server. I’ve placed mine in the following location - C:\ColdFusion8\lib\thirdpartytools\JDBC\SQLSERVER2005\1.2\.

The second file you’ll want to place on your server is called sqljdbc_auth.dll. This file can be found in extracted_folder\sqljdbc_1.2\enu\auth\x86\sqljdbc_auth.dll (Please note that this folder path is platform specific). Put this file on your server in C:\WINDOWS\system32\. This is the library that the JDBC driver uses to perform integrated authentication.

Step 3 - Add the JDBC class path to ColdFusion

  1. Login to your ColdFusion Administrator
  2. Expand Server Settings
  3. Click on Java and JVM
  4. Add C:\ColdFusion8\lib\thirdpartytools\JDBC\SQLSERVER2005\1.2\sqljdbc.jar in the ColdFusion Class Path field. Please note that this path may be different depending on where you placed the sqljdbc.jar file on the server.
  5. Click on Submit Changes

You will be reminded to restart ColdFusion for the changes to take effect. You’ll want to actually reboot your server since we placed the sqljdbc_aut.dll file in C:\WINDOWS\system32\.

Step 4 - Add a user to SQL Server.

The user you’ll want to use for authentication will be the user that the ColdFusion service runs under. By default, ColdFusion runs under the Local System account (you or your system administrator may have changed this). While whether or not this is the best account for CF to run under is up for debate, you can still use it to authenticate to SQL Server as long as it’s the account that ColdFusion is running under. The use this account, the user you’ll want to specify is in the format of DOMAIN\SERVERNAME$ - make sure you use the $ on the end. Obviously, Windows performs some magic on the backend to map this to the Local System account for the server you’re authenticating from.

  1. Fire up SQL Server Management Studio and connect to the database you wish to use
  2. Expand Security
  3. Right click on Logins and select New Login
  4. For the Login Name, you’ll add the user you want to authenticate with. If ColdFusion is running under the Local System account, try a user in the format of DOMAIN\SERVERNAME$ and see if Windows will do its magic
  5. (optional step) Click on User Mapping and select the databases and permissions for your user
  6. Click on OK

Step 5 - Add a datasource to ColdFusion.

  1. Login to your ColdFusion Administrator
  2. Click on Data & Services
  3. Click on Datasources
  4. Type in a Data Source Name
  5. For Driver, select Other
  6. Click on Add
  7. For the JDBC URL, use the following: jdbc:sqlserver://servername:1433;databaseName=dbname;integratedSecurity=true; (please make sure you substitute the servername and dbname)
  8. For Driver Class, add: com.microsoft.sqlserver.jdbc.SQLServerDriver
  9. Click on Submit

You should now be done and have a successful connection.

ColdFusion

Comments (2)

Permalink

Flex: Create Button Event Listeners

private function createButtonEventListeners():void
{
btnContinue.addEventListener(MouseEvent.CLICK, processForm);
btnCancel.addEventListener(MouseEvent.CLICK, cancelForm);
}

Flex

Comments (0)

Permalink

Using Transactions on Bulk Inserts

Have you ever looped through a large amount of records only to insert them into a dabase table? Something similar to this?

<cfloop query=“routing_numbers”>
<cfquery datasource=“routing_numbers”>
INSERT INTO routing_numbers (routing_number, customer_name)
VALUES (#routing_numbers.routing_number#, ‘#routing_numbers.customer_name#‘)
</cfquery>

</cfloop>

I use the above code as part of a nightly scheduled task. It parses 20,000 records from a text file and inserts them into a database. It is slow. If you’re doing something similar, there’s a good chance you can increase the performance by 500% or more by wrapping your INSERT loop inside a <CFTRANSACTION> block.

<cftransaction isolation=“serializable” action=“begin”>

<cftry>
<cfloop query=“routing_numbers”>

<cfquery datasource=“routing_numbers”>
INSERT INTO routing_numbers (routing_number, customer_name)
VALUES (#routing_numbers.routing_number#, ‘#routing_numbers.customer_name#‘)
</cfquery>
</cfloop>

<cfcatch type=“database”>
<cftransaction action=“rollback”/>
</cfcatch>

</cftry>

<cftransaction action=“commit” />
</cftransaction>

Please note that the <cftransaction action=”commit” /> on the end is optional, depending on your RDBMS. Some require it, some don’t, so please check your documentation.

What’s the difference?

In the first code example, an implicit transaction is performed with each insert. That’s a lot of transactions for a redundant task and takes a lot of time as the DB opens the data file, inserts a record, and then closes it.

In the second example, there is no longer an implicit transaction with each INSERT. All the INSERT statements are grouped together in a single transaction. Thus, the data file only has to be opened and closed once.

ColdFusion

Comments (3)

Permalink

Routing Numbers ColdFusion Component

I recently worked on an application where I needed to display the name of the bank after a user entered their bank’s routing number. After some googling, I found a couple vendors who offered products. One offered a packaged database of routing numbers. This is no good as the list of numbers is dynamic and can change frequently. Another vendor offered an API-ish XML feed of routing numbers for a small fee. I didn’t like either one of these options.

Our financial institution pointed us in the direction of a downloadable text file of routing number provided by Federal Reserve Financial Services at no charge.

I decided to write a ColdFusion component to dowload and parse out bank routing numbers and their data and place them into and return a query object. The CFC is available on RIAForge at http://routingnumberscfc.riaforge.org/.

Since the file is so large and takes a considerable amount of time for the server to download and parse, I utilize the CFC as part of a scheduled task that loops through and stores the data returned from the CFC’s findAll() function into a database. In my application, I then simply just query against the data in the database.

ColdFusion

Comments (0)

Permalink

Flex: Validating a ComboBox with NumberValidator

If you’re using a ComboBox, and want to make sure the user has selected an item in the list, you can peform a quick and dirty validation with Flex’s NumberValidator. This is under the assumption that you do not want to allow the first item in the list to be a legitimate selection.

<mx:Script>
<![CDATA[
import mx.controls.Alert;
]]>
</mx:Script>></code>

<mx:Array id=”colors”>
<mx:String>Select…</mx:String>
<mx:String>Blue</mx:String>
<mx:String>Red</mx:String>
<mx:String>Green</mx:String>
<mx:String>Orange</mx:String>
<mx:String>Black</mx:String>
</mx:Array>

<mx:NumberValidator
id=”vColor”
trigger=”{btnValidate}”
triggerEvent=”click”
minValue=”1";
lowerThanMinError=”Please select a color.”
source=”{color}”
property=”selectedIndex”
invalid=”Alert.show(vColor.lowerThanMinError)”
valid=”Alert.show(’Congratulations! You selected a color.’)”/>

<mx:VBox>
<mx:ComboBox id=”color” dataProvider=”{colors}”/>
<mx:Button id=”btnValidate” label=”Validate”/>
</mx:VBox>

The idea is that you validate against the ComboBox’s selectedIndex property. The default selection will set selectedIndex to 0. If a different value is selected in the ComboxBox, selectedIndex will change to represent the numerical position of the value in the list. By using NumberValidator to validate against selectedIndex and not allowing a value less than 1, we know that the default selection will always be invalid.

Flex

Comments (0)

Permalink