Creating User Feedback With CFWindow

I hate javascript alert(‘boxes’). They’re boring, ugly and a lousy way to do user feedback. I recently put together the following demonstration of a more elegant system to present error message and feedback to user based on the coldfusion CFWindow tag. If you’ve never used CFwindow before, this tag automagically creates a div which can be populated with pretty much anything; dynamic data, images, even flash.

One thing to note about this code is that nowhere in the code will you actually see <cfwindow…> which is the tag built-in to Coldfusion. the CFWindow tag is very simple to use but in order to make your app really stand out, we need to get into the API which is built from the amazing EXT javascript library This allows us to dynamically set the window size, change the header style of the window and much more.

Have a look at the code. I’ve commented a lot (for me anyways) throughout the code so it should be fairly straightforward.

One note of warning. WordPress likes to mess with some of the text in and especially ” quotes even using the code tag so this may require a bit of cleaning up after you cut and paste.

<!---
Error & Messages 2.0

PreReqs: CF8, Basic Knowledge of CFWindow and java_script
Database not required
Files required: index.cfm (This file) and msgWindow.cfm

contents of msgWindow.cfm

<cfoutput>
<!--- displays the content of url.msg which is passed in the ColdFusion.Window.create call --->
<span style="font-size:.8em;font-family:tahoma;">
#url.msg#
</span>
</cfoutput>

Both files must be in the same directory.

Description
java_script alert() messages are so turn of the century. This tutorial uses CFwindow to create custom error and informational messages. The main function is showMsg() which creates the window and takes several parameters to set up how it looks and what messages are displayed. Unlike basic usage of the cfwindow tag, this uses the Coldfusion AJAX API (via cfajaximport) to create windows at runtime (so you don't have to know how they're going to look or  what they'll contain in advance)

We also take advantage of changing styles of the cf window (didn't know you could do that?) to provide appropriate visual cues for the user.

Since we are creating the window at runtime, it gives us the opportunity to automagically resize the window to fit our message text. This is something you can't do with the simple cfwindow tag as you have to hard code the window size in advance and it can look a bit clunky as a one size fits all message box.

The simplest usage of this function is

function sayHello(){
var d = new Date();
var msg = 'Hello World';
var wid = d.getMinutes()+d.getSeconds();
showMsg(wid, 'Message',msg, 75,400);
}

You can use this on any page to call a window. You can put pretty much anything in the message including html
--->
<!--- index.cfm --->
<!--- import the cfwindow tag so we can call via ColdFusion.Window.create at runtime --->
<CFAJAXIMPORT TAGS="cfwindow">
<html>
<head>
<style ="text/css">
/*change the default cfwindow style and make the header text red*/
.errHdr { background: url(/CFIDE/scripts/ajax/resources/ext/images/default/layout/panel-title-greylight-bg.gif) repeat-x ;
color:#ff0000;
font:normal 11px tahoma, verdana, helvetica;
text-align: center;
padding:5px;
font-weight:bold;}
.x-dlg .x-dlg-close {
background-image: url(/CFIDE/scripts/ajax/resources/ext/images/default/basic-dialog/close.gif);
}
/*change the default cfwindow style*/
.msgHdr { background: url(/CFIDE/scripts/ajax/resources/ext/images/default/layout/panel-title-greylight-bg.gif) repeat-x ;
color:#000;
font:normal 11px tahoma, verdana, helvetica;
text-align: center;
padding:5px;
font-weight:bold;}
.x-dlg .x-dlg-close {
background-image: url(/CFIDE/scripts/ajax/resources/ext/images/default/basic-dialog/close.gif);
}
</style>

<script type="text/javascript">
function showMsg(){
//create the window
//param 1 = showMsg.arguments[0] (wid)
//param 2 = showMsg.arguments[1]  (header text)
//param 3 = windowurl and showMsg.arguments[2](msg variable)
//cfwindowparams {height:showMsg.arguments[3],width:showMsg.arguments[4]
// the other params can be hardcoded since we want error messages to be modal and closeable.
//(you could expand this technique to have even more control if you want)
ColdFusion.Window.create("myWindow"+showMsg.arguments[0], showMsg.arguments[1], "msgWindow.cfm?msg=" + showMsg.arguments[2], {height:showMsg.arguments[3],width:showMsg.arguments[4],modal:true,closable:true, draggable:false,resizable:false,center:true,initshow:true,refreshOnShow:true});
//apply styles based on header message
///you could have as many styles as you want and use a switch block instead of if else
if(showMsg.arguments[1]=='Error Message')
{
document.getElementById(ColdFusion.Window.getWindowObject("myWindow"+showMsg.arguments[0]).header.id).className = "errHdr";
}
else{
document.getElementById(ColdFusion.Window.getWindowObject("myWindow"+showMsg.arguments[0]).header.id).className = "msgHdr";
}
// clear window objectCache
ColdFusion.objectCache["myWindow"+showMsg.arguments[0]] = null;
}

function showHelp()
//this is the basic info box. A slighlty more advanced version of hello world
{
var d = new Date()
var msg = 'This displays an informational message. You can populate this statically, from a db on page load or via an ajax call.'
msg = msg + ' Notice how the header style of the CFWindow changes based on param 2 of the showMsgjava_script call'
msg = msg + ' You can even include html, links and images <div> <a href=\"http://fusebox.org\">Get Fusebox</a><br><br><img src=\"http://fusebox.org/css/images/fuseboxlogo.gif\" style=\"width:300px;\"></div>'
msg=msg + ' <br> just rememberjava_script wants you to escape the double quotes with a front slash \\"'
var wid = d.getMinutes()+d.getSeconds()
showMsg(wid, 'Help Window',msg, 275,450);

}

function checkField()
//this function checks for a value in a form field and pops up an error if none exists
//<standard rant> Remember! Client side validation is a convenience and not a security decision.
//Always use sever side validation and cfqueryparam </standard rant>
{
if (document.getElementById('testField').value=='')
{
var d = new Date()
var msg = 'Please Enter A Value.'
msg = msg + ' You can use this for client side error checking, ajax return errors etc. '
msg = msg + 'Notice the change in header based on the style errHdr. You can populate this statically like we are doing here, from a db on page load or via an ajax call.'

var wid = d.getMinutes()+d.getSeconds()
showMsg(wid, 'Error Message',msg, 130,400);
return false;}
else
{
return true;
}
}

function showWindowResize(theVal)
{
//This function show how we can dynamically fit the window to the message
//for simplicity we'll just set up a single long msg string. In real life you'd probably be pulling various length'ed
//strings from a db
var msg = 'This displays an informational message. You can populate this statically, from a db on page load or via an ajax call.'
msg = msg + ' Thejava_script looks at the <span style=\"font-size:1.3em;\">size</span> of the string passed and resizes the cfWindow to -fit- (mostly)'
msg = msg + ' Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim'
msg = msg + ' veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '
msg = msg + ' Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. '
msg = msg + ' Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
msg = msg + ' <strong>Neque porro quisquam est</strong>, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam'
msg = msg + ' eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis '
msg = msg + ' nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur Quis autem '
msg = msg + ' vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum'
msg = msg + ' fugiat quo voluptas nulla pariatur'

//we'll trim the message to various lengths to show how the code resizes the window.
//we're taking the values passed by button onclick event and trimming the string using substr
// you wouldn't usually need this in a standard application.

switch  (theVal){
case 150:
msg = msg.substring(0,120)
break;
case 300:
msg = msg.substring(0,250)
break;
case 500:
msg = msg.substring(0,450)
break;
case 600:
msg = msg.substring(0,550)
break;
case 700:
msg = msg.substring(0,650)
break;
case 800:
msg = msg.substring(0,750)
break;
case 1000:
msg
break;
}
//for the demo we'll get the message length and assign it to a variable to show in the header of the cfwindow
// wouldn't usually be used in an application although it does show how you can add messages to a header
hdr = 'Message Length is ' + msg.length

//determine the length of the msg variable and set the window ehight accordlingly. vHeight will need
//to be adjusted based on your font size, whether you want scroll bars etc.
if(msg.length < 150) {
vHeight = 85;
} else if(msg.length > 149 && msg.length < 300) {
vHeight = 125;
} else if(msg.length > 299 && msg.length < 500) {
vHeight = 175;
} else if(msg.length > 499 && msg.length < 600) {
vHeight = 200;
} else if(msg.length > 599 && msg.length < 700) {
vHeight = 225;
} else if(msg.length > 699 && msg.length < 800) {
vHeight = 285;
} else {
vHeight = 400;
}
//variable wid is a timestamp that will help ensure that each window instance is unique to avoid caching issues
var d = new Date()
var wid = d.getMinutes()+d.getSeconds()
//a non-demo would not use the hdr length variable
//showMsg(wid, 'Help Window', vHeight,400);

//this is the main call
//the attributes passed are
//wid = unique timestamp
//header title
//msg = message body
//vHeight = cfwindow height variable
//cfwindow width = 400 could be a variable here as well but is static for this demo
showMsg(wid, 'Help Window ' + hdr, msg, vHeight, 400);
}
</script>
</head>
<script  type="text/java_script">
function sayHello(){
var d = new Date();
var msg = 'Hello World';
var wid = d.getMinutes()+d.getSeconds();
showMsg(wid, 'Message',msg, 75,400);
}

</script>

<body>

<button onClick="showHelp();">Help with Image and Link</button>    <br>
<button onClick="showWindowResize(150);">Show Window Resize 150 Chars</button>    <br>
<button onClick="showWindowResize(300);">Show Window Resize 300 Chars</button>    <br>
<button onClick="showWindowResize(500);">Show Window Resize 500 Chars</button>    <br>
<button onClick="showWindowResize(600);">Show Window Resize 600 Chars</button>    <br>
<button onClick="showWindowResize(700);">Show Window Resize 700 Chars</button>    <br>
<button onClick="showWindowResize(800);">Show Window Resize 800 Chars</button>    <br>
<button onClick="showWindowResize(1000);">Show Window Resize +800 Chars</button>    <br>
<form method="post" action="index.cfm" onSubmit="return checkField();">
<input type="text" name="testField" id="testField">
<input type="submit" value="TestMe Without a Value">

</form>
</body>

</html>

Advertisements