Welcome!

You will be redirected in 30 seconds or close now.

ColdFusion Authors: Yakov Fain, Jeremy Geelan, Maureen O'Gara, Nancy Y. Nee, Tad Anderson

Related Topics: ColdFusion

ColdFusion: Article

Data Entry ReFORMed

Data Entry ReFORMed

HTML-based data entry is a pain, both for developers and for end users. There's no way to sugarcoat it, HTML forms as used today are pathetic. Sure, there are new form specifications on the way, but they are not yet in use, browsers don't support them, and they are still unproven entities. Luckily, there's an option available right now; it's called Macromedia Flash MX.

The Forms Quagmire
Are HTML forms really that bad? Consider the following, first, from a developer's perspective:

  • HTML form controls are limited; you can't extend HTML with your own controls (simple things like date choosers or calendars).
  • HTML form controls provide almost no automatic validation (sure, you can validate text post-input, but you can't prevent the user from typing invalid characters in the first place).
  • There is no simple event model in form controls; basic form control that should be simple (things like graying out controls or making them available based on other selections) is anything but.
  • And one of the most annoying of all, because browsers cannot make round-trips to servers within a page, it is impossible to do things like creating side-by-side list boxes whereby options in one change based on selections in another. (We've all tried this one at some point.)

    To make up for these limitations, developers create multipart forms. These are not a feature of HTML, they are a hack born of necessity. Consider the following, this time from an end user's perspective:

  • Server-side form field validation is time-consuming and extremely annoying. Forcing a user to hit "Back" to make corrections is not user friendly.
  • Some browsers may even lose all entered data, requiring the user to reenter it all.
  • Users will often submit forms multiple times, or hit Back and Refresh repeatedly, creating multiple records or executing multiple requests (which they'll then e-mail you about later).

    And this is just the start of it. As a developer you've probably wasted countless hours having to accommodate for glaring inadequacies in HTML as it exists today.

    Which brings us to Flash MX.

    Why Flash-Based Forms?
    I am not going to sell you on the virtues of Flash - that's another column, and one probably better suited to be written by the Flash experts among us. For now, suffice it to say that Flash is readily available, can be very lightweight, is extremely portable, and (this is the most important part) can be used for more than animation, movies, and annoying popup ads.

    Not that I'm saying Flash should not be used for those things, it should be (well, maybe not for those popup ads that invade your screen, but for everything else). But Flash can also be used for building entire application clients or parts thereof, parts like forms.

    So why don't you see more Flash-based forms out there? There are a couple of reasons for this. First, until recently, Flash was rather inaccessible to developers (those of us who actually create forms); the tool was geared far more toward designers. And second, creating forms meant starting from scratch - actually creating form controls.

    Flash MX addresses both of these problems. It is far more developer friendly than any previous version of Flash, and it also comes with all sorts of form controls that you can literally just drag and drop into place.

    That alone makes Flash MX an ideal solution for building forms, but it gets better. Flash MX and ColdFusion MX can talk to each other with minimal work on your part, which makes creating forms that interact with back-end processing very easy.

    Still not convinced? I'll show you. Let's walk through an example together, in which we'll build a Flash-based form used to select an employee. For this example, we'll create the much-needed side-by-side list boxes. The left list box will display departments, and when a department is selected, the right list box will automatically update with the employees in that department allowing easy selection.

    The Back End
    ColdFusion MX and Flash MX interact in several ways, but one of the simplest is via ColdFusion Components (explained in detail in CFDJ Volume 4, issues 6, 7, and 10). So we'll start with a simple CFC which contains two methods: GetDepartment returns a list of all departments, and GetEmployees returns all employees (either in a specific department or in all departments. Here is employees.cfc:

    <!--- employees.cfc --->
    <CFCOMPONENT>
    <!---
    GetDepartments method
    Get all departments.
    --->
    <CFFUNCTION NAME="GetDepartments"
    ACCESS="remote"
    RETURNTYPE="query"
    OUTPUT="false">

    <!--- Get departments --->
    <CFQUERY NAME="Departments"
    DATASOURCE="exampleapps">
    SELECT *
    FROM tblDepartments
    ORDER BY DepartmentName
    </CFQUERY>

    <!--- Return query --->
    <CFRETURN Departments>

    </CFFUNCTION>

    <!---
    GetEmployees method
    Get all employees if no department
    specified, otherwise gets employees
    in specified department.
    --->
    <CFFUNCTION NAME="GetEmployees"
    ACCESS="remote"
    RETURNTYPE="query"
    OUTPUT="false">
    <!--- Optional department ID --->
    <CFARGUMENT NAME="DeptID"
    TYPE="uuid"
    REQUIRED="no">
    <!--- Get employees --->
    <CFQUERY NAME="Employees"
    DATASOURCE="exampleapps">
    SELECT *
    FROM tblEmployees
    <CFIF IsDefined("DeptID")>
    WHERE DeptIDFK = '#DeptID#'
    </CFIF>
    ORDER BY LastName, FirstName
    </CFQUERY>

    <!--- Return query --->
    <CFRETURN Employees>

    </CFFUNCTION>

    </CFCOMPONENT>
    Create a simple ColdFusion script to test the component. The following code invokes GetDepartments and lists the returned department names:

    <CFINVOKE COMPONENT="employees"
    METHOD="GetDepartments"
    RETURNVARIABLE="depts">

    <UL>
    <CFOUTPUT QUERY="depts">
    <LI>#DepartmentName#</LI>
    </CFOUTPUT>
    </UL>
    The following snippet tests the GetEmployees method, again displaying returned data in a list:

    <CFINVOKE COMPONENT="employees"
    METHOD="GetEmployees"
    RETURNVARIABLE="emps">
    <UL>
    <CFOUTPUT QUERY="emps">
    <LI>#Lastname#, #FirstName#</LI>
    </CFOUTPUT>
    </UL>
    Assuming that the code worked correctly, you now have a CFC capable of accessing and returning data - a component that may be used by ColdFusion (as in this test code) and also by client-side Flash.

    Creating the Flash Movie
    Now fire up Flash MX. We're going to keep the Flash really simple - we'll ignore frames, layers, animation, tweening, etc., so feel free to close the TimeLine window (as I routinely do). The only windows you'll need open are the Actions window, the Properties window, and the Components window (as seen in Figure 1).

    Next, save the new (empty) Flash movie somewhere beneath your Web root (so that you can get to it).

    The form we'll create has two drop-down list boxes (actually called ComboBoxes), so drag two ComboBoxes from the Components window (make sure the drop-down list at the top of the window reads "Flash UI Components") onto the stage. We'll also need a Submit button so drag a PushButton component onto the stage as well. You now have three ready-to-use components on your stage (as seen in Figure 2).

    The next step is to name the instances of the components we just placed on the stage (so as to be able to programmatically script them). Make sure the Properties window is open, then click on each of the three components to access its properties:

  • Click on the left ComboBox and specify dept_cb as the instance name (as seen in Figure 3).
  • Click on the right ComboBox and specify dept_emp as the instance name.
  • Click on the button and specify submit_btn as the instance name and Submit as the label.

    Save the movie and then execute it. Either select Test Movie from the Control menu to run it right within Flash, or select Publish from the File menu to publish the movie so that it may be loaded in a Web browser. You now have a working (albeit rather useless) Flash-based form (as shown in Figure 4).

    ColdFusion-Powered Flash
    Now we need to get Flash to interact with the CFC. Open the Actions window (if it is not already open) and make sure the Actions for Frame 1 of Layer Name Layer 1 option is selected from the drop-down list above it, and enter the following ActionScript code (as seen in Figure 5):

    #include "NetServices.as"
    #include "DataGlue.as"

    // Init stuff
    if (inited == undefined) {
    inited = true;
    // Configure connection to ColdFusion
    var gwURL = "http://localhost:8500/flashservices/gateway";
    NetServices.setDefaultGatewayURL(gwURL);
    gw = NetServices.createGatewayConnection();
    employeeService = gw.getService("cfflash.employees", this);
    // Invoke the GetDepartments method
    employeeService.GetDepartments();
    }

    The first two lines of code are include statements (kind of like <CFINCLUDE> in CFML). The first includes support for Flash Remoting (the ability to interact with back-end systems like ColdFusion) and the second includes DataGlue, a series of functions that dramatically simplifies binding returned data to UI controls (as you will soon see).

    The next block of code is initialization code that needs to be run only once, as it checks to see if it, itself, has been run already (checking for a variable that is defined within the if statement).

    A variable is then declared to store the URL to the Flash Gateway on the ColdFusion MX server. The snippet shown here accesses a local ColdFusion MX using the integrated HTTP server, so the URL is localhost:8500. You'll need to change this to point to your own ColdFusion server as needed.

    The next few lines of code create a gateway connection, and then a local reference to a remote CFC. The path here is specified as cfflash.employees which points to the employees.cfc file in the cfflash directory. You'll need to change that path as needed so that it points to your own employees.cfc file.

    The last line of code actually calls the GetDepartments method. Flash knows that employeeService has been bound to a CFC on the other end of a connection, and so a call to employeeService.GetDepartments() is actually a call to the GetDepartments method in the service bound to employeeService. As soon as this last line of code is executed, Flash will have a query containing the list of departments.

    If you were to run the Flash movie now, it would look no different than it did before. Data is being retrieved but nothing is being done with it (think of it as a <CFQUERY> without a <CFOUTPUT>). The next step is to tell Flash how to populate the appropriate ComboBox with the retrieved data.

    When GetDepartments() is executed, results are returned. Flash automatically looks for a function named GetDepartments_Result(), and will execute it if present. So we'll need to create that function which will loop through the returned data, processing one row at a time and inserting them into the ComboBox. Fortunately you don't have to do that manually; that's where DataGlue comes into play. Here is the GetDepartments_Result() function:

    // Process retrieved departments
    function GetDepartments_Result(result) {
    // Populate dept_cb with results
    DataGlue.bindFormatStrings(dept_cb,result,
    "#DepartmentName#",
    "#DepartmentID#");
    }
    As you can see, GetDepartments_Result() is really simple. It calls DataGlue.bindFormatStrings() to bind the data in result to ComboBox dept_cb using #DepartmentName# as the label (display text) and #DepartmentID# as the value.

    While we're at it, add a similar function to process results returned by GetEmployees(), as we'll be needing that next:

    // Process retrieved employees
    function GetEmployees_Result(result) {
    // Populate emp_cb with results
    DataGlue.bindFormatStrings(emp_cb,
    result,
    "#lastname#, #firstname#",
    "#employeeid#");
    }
    If you save and execute the Flash movie, you'll now see that the left ComboBox is being populated by data returned by ColdFusion. So far, so good. Now for the left ComboBox. What we need is a way to force the left ComboBox to refresh each time a selection is made in the right ComboBox. First create a new function named employeesRefresh(). Each time this function is called, it invokes the GetEmployees method in the employees.cfc (which in turn triggers the GetEmployees_Result() function just created). In order to get employees for the currently selected department, the getSelectedItem() ComboBox method is used to get the current department ID, which is passed as a parameter to GetEmployees(). Here is the employeesRefresh() function:

    // dept_cb change handler
    function employeesRefresh() {
    // Invoke GetEmployees method
    employeeService.GetEmployees(dept_cb.getSelectedItem().data);
    }

    To actually get this employeesRefresh() function to be executed when a department selection is made, all we need to do is add the following code into the initialization code (you can put it right after the inited=true;):

    // Set change handler for first combobox
    dept_cb.setChangeHandler("employeesRefresh");
    This code sets employeesRefresh as the change handler for dept_cb (the left ComboBox), so that any time a change is made in dept_cb, employeesRefresh() will be executed and the employee list will be refreshed which in turn will force emp_cb to be updated.

    Try out your new form. You should see both ComboBoxes populated (as seen in Figure 6) and whenever a department is selected, the employees in that department will be listed automatically. This process makes round-trips to ColdFusion as needed, but it happens so quickly and efficiently (and without needing a page refresh) that you'd never even know.

    There is one last step needed. To actually submit the form, you need form processing code, something that will be executed when the submit button is clicked. Here is the code:

    // Process submit button pressed
    submit_btn.onrelease = function () {
    EmployeeID = emp_cb.getSelectedItem().data;
    getURL("action.cfm", "", "POST");
    }
    To post a form variable, you first need to create it, so the first line of code creates a variable named EmployeeID, and populates it with whatever the id of the selected employee is (again using the getSelectedItem() method). Then getURL is used to actually submit the form fields; here the action page is named action.cfm but you can name yours whatever you'd like. For a simple test you can create an action.cfm that contains the following:

    <CFOUTPUT>
    EmployeeID: #EmployeeID#
    </CFOUTPUT>
    And there you have it. That's all the code you need to create side-by-side ComboBoxes that do exactly what is needed without requiring a single screen refresh. Just to be on the safe side, Listing 1 shows the complete ActionScript code listing.

    Summary
    Creating Flash-based forms is not complicated once you understand the basic steps. Using the form components that are provided removes the need for UI work (where most of us CFers would have gotten stuck) and requires minimal ActionScript. The best part of it is that the form we just created is highly usable and is only 11K in size (yes, believe it or not, Flash need not be big and bloated).

    Give it a try (and be sure to go to the Developers Exchange at www.macromedia.com to download additional form controls, including a complete calendar, a tree control, and even a data grid). You'll find that Web-page form nightmares are a thing of the past.

  • More Stories By Ben Forta

    Ben Forta is Adobe's Senior Technical Evangelist. In that capacity he spends a considerable amount of time talking and writing about Adobe products (with an emphasis on ColdFusion and Flex), and providing feedback to help shape the future direction of the products. By the way, if you are not yet a ColdFusion user, you should be. It is an incredible product, and is truly deserving of all the praise it has been receiving. In a prior life he was a ColdFusion customer (he wrote one of the first large high visibility web sites using the product) and was so impressed he ended up working for the company that created it (Allaire). Ben is also the author of books on ColdFusion, SQL, Windows 2000, JSP, WAP, Regular Expressions, and more. Before joining Adobe (well, Allaire actually, and then Macromedia and Allaire merged, and then Adobe bought Macromedia) he helped found a company called Car.com which provides automotive services (buy a car, sell a car, etc) over the Web. Car.com (including Stoneage) is one of the largest automotive web sites out there, was written entirely in ColdFusion, and is now owned by Auto-By-Tel.

    Comments (4) View Comments

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


    Most Recent Comments
    Joe Kelly 04/17/03 04:04:00 PM EDT

    I noticed a small error in the instructions on naming the check boxes. It may throw you, especially if you are new to ActionScript. The article says to name the employee check box

    Daniel Walker 11/14/02 07:09:00 AM EST

    This book compares and contrasts the various technologies available for getting data off your web visitors and into your web-based application, including Flash-based forms:
    http://www.glasshaus.com/bookInfo.asp?bookId=60

    ... while, FWIW, _this_ book has an entire chapter on Flash-Accessability:
    http://www.glasshaus.com/bookInfo.asp?bookId=44

    Yes, I'll admit that I work for the company that publishes them, but I stil think they're good books. I hope I haven't infringed the rules of this forum.

    Excellent article, BTW, Mr Forta!

    Will Belden 11/13/02 08:53:00 PM EST

    If you scroll down past the original info on the link that Ian provided, you'll see an updated section from the author about improvements in Flash MX.

    Ian Westbrook 11/13/02 07:21:00 PM EST

    whilst what Ben says may be true, the fact is that html forms, if designed right (and that's often a big _IF_), are accessible for visually-impaired users, whilst Flash-based forms are not, generally. And if the RNIB (Royal National Institute for the Blind) is right in saying that up to 10% of the (UK) population has some form of visual impairment (which seems a high figure, until you think about older people whose sight is failing), that's a _lot_ of users with a _lot_ of spending power.

    I know it's two years old now, but I'm sure you've all seen this:

    http://www.useit.com/alertbox/20001029.html

    and anyway, we've all been hitting our head against this particular brick wall for so long that there's a huge resource of hacks and workarounds. I wonder if Ben would be so keen on Flash if Allaire hadn't been bought by Macromedia? (OK, a cheap shot, but not entirely without merit, I feel, and no offence meant. I've got a lot of respect for BF)...

    Ian W

    IoT & Smart Cities Stories
    DXWorldEXPO LLC announced today that ICC-USA, a computer systems integrator and server manufacturing company focused on developing products and product appliances, will exhibit at the 22nd International CloudEXPO | DXWorldEXPO. DXWordEXPO New York 2018, colocated with CloudEXPO New York 2018 will be held November 11-13, 2018, in New York City. ICC is a computer systems integrator and server manufacturing company focused on developing products and product appliances to meet a wide range of ...
    SYS-CON Events announced today that DatacenterDynamics has been named “Media Sponsor” of SYS-CON's 18th International Cloud Expo, which will take place on June 7–9, 2016, at the Javits Center in New York City, NY. DatacenterDynamics is a brand of DCD Group, a global B2B media and publishing company that develops products to help senior professionals in the world's most ICT dependent organizations make risk-based infrastructure and capacity decisions.
    René Bostic is the Technical VP of the IBM Cloud Unit in North America. Enjoying her career with IBM during the modern millennial technological era, she is an expert in cloud computing, DevOps and emerging cloud technologies such as Blockchain. Her strengths and core competencies include a proven record of accomplishments in consensus building at all levels to assess, plan, and implement enterprise and cloud computing solutions. René is a member of the Society of Women Engineers (SWE) and a m...
    Nicolas Fierro is CEO of MIMIR Blockchain Solutions. He is a programmer, technologist, and operations dev who has worked with Ethereum and blockchain since 2014. His knowledge in blockchain dates to when he performed dev ops services to the Ethereum Foundation as one the privileged few developers to work with the original core team in Switzerland.
    @DevOpsSummit at Cloud Expo, taking place November 12-13 in New York City, NY, is co-located with 22nd international CloudEXPO | first international DXWorldEXPO and will feature technical sessions from a rock star conference faculty and the leading industry players in the world. The widespread success of cloud computing is driving the DevOps revolution in enterprise IT. Now as never before, development teams must communicate and collaborate in a dynamic, 24/7/365 environment. There is no time t...
    Headquartered in Plainsboro, NJ, Synametrics Technologies has provided IT professionals and computer systems developers since 1997. Based on the success of their initial product offerings (WinSQL and DeltaCopy), the company continues to create and hone innovative products that help its customers get more from their computer applications, databases and infrastructure. To date, over one million users around the world have chosen Synametrics solutions to help power their accelerated business or per...
    DXWordEXPO New York 2018, colocated with CloudEXPO New York 2018 will be held November 11-13, 2018, in New York City and will bring together Cloud Computing, FinTech and Blockchain, Digital Transformation, Big Data, Internet of Things, DevOps, AI, Machine Learning and WebRTC to one location.
    When talking IoT we often focus on the devices, the sensors, the hardware itself. The new smart appliances, the new smart or self-driving cars (which are amalgamations of many ‘things'). When we are looking at the world of IoT, we should take a step back, look at the big picture. What value are these devices providing. IoT is not about the devices, its about the data consumed and generated. The devices are tools, mechanisms, conduits. This paper discusses the considerations when dealing with the...
    Charles Araujo is an industry analyst, internationally recognized authority on the Digital Enterprise and author of The Quantum Age of IT: Why Everything You Know About IT is About to Change. As Principal Analyst with Intellyx, he writes, speaks and advises organizations on how to navigate through this time of disruption. He is also the founder of The Institute for Digital Transformation and a sought after keynote speaker. He has been a regular contributor to both InformationWeek and CIO Insight...
    IoT is rapidly becoming mainstream as more and more investments are made into the platforms and technology. As this movement continues to expand and gain momentum it creates a massive wall of noise that can be difficult to sift through. Unfortunately, this inevitably makes IoT less approachable for people to get started with and can hamper efforts to integrate this key technology into your own portfolio. There are so many connected products already in place today with many hundreds more on the h...