"PuttingIt All Together," Vol. 1, Issue 4, p. 18

Listing 1: A very simple custom tag
<CFPARAM NAME="attributes.message" DEFAULT="I have nothing to report">

<CFOUTPUT>
<SCRIPT LANGUAGE="JavaScript">
 alert("#attributes.message#");
</SCRIPT>
</CFOUTPUT>

Listing 2: Invoking the QBE of Death
<HTML>
<BODY>
<CF_QBE fieldlistframe="parent.dataframe.fieldframe"
  criteriaframe="parent.dataframe.scriteria"
  fieldcriteriaurl="framesetup.htm"
  fieldcriteriaframe="parent.dataframe"
  buttonframe="buttonframe"
  actionframe="dataframe"
  ACTION="runquery.cfm">
 
  <CF_QUERYCRITERIA  DISPLAY="lastname"
     FIELDNAME="EmpEmployees.lastname"
     DATATYPE="string"
     MAXLENGTH="10"
     EXAMPLE="Jones,Smith"
     DESCRIPTION="Search by Last Name">
 
 
  <CF_QUERYCRITERIA DISPLAY="firstname"
     FIELDNAME="EmpEmployees.firstname"
     DATATYPE="string"
     MAXLENGTH="10"
     EXAMPLE="Steve,Dave"
     DESCRIPTION="Search by First Name">
 
 </CF_QBE>
 
</BODY>
</HTML>
 

Listing 3:
<!---index.htm – starts everything -‡

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
 <title>QBE of Death, By Steve Drucker</title>
</head>

<FRAMESET rows="*,50" frameborder="No" framespacing="0" BORDER=0>
 <FRAME NAME="dataframe" SRC="framesetup.htm">
 <FRAME NAME="buttonframe" SRC="querystart.cfm">
</FRAMESET>

</html>

Listing 4:
<!---
 framesetup.htm – our field selection and search criteria frames
-‡

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
 <title>Untitled</title>
</head>

<FRAMESET COLS="*,*">
 <FRAME NAME="fieldframe" SRC="empty.htm">
 <FRAME NAME="scriteria" SRC="empty.htm">
</FRAMESET>

</html>

Listing 5: Using JavaScript to programatically send html to a frame
function drawCriteria() {
 
<CFOUTPUT>
var mysc=#attributes.criteriaframe#.document;
var criteriafound=0;
</CFOUTPUT>

/* add a row to the search criteria */
 mysc.open();
 mysc.write('<HTML><BODY BGCOLOR="White"><FORM><TABLE WIDTH="100%">');
 mysc.write('<TR BGCOLOR="Navy"><TD><FONT FACE="Arial" SIZE="-1" COLOR="White"><B>Field</b></font></td><TD><FONT FACE="Arial" SIZE="-1" COLOR="White"><B>Logic</B></FONT></td><TD><FONT FACE="Arial" SIZE="-1" COLOR="White"><B>Value</B></FONT></td></tr>');
 for (var i=0; i<searchcriteria.getRowCount(); i++) {

 .
 .
 .
 }
 mysc.write('</table></form></body></html>');
 mysc.close();
 setLogic();
}

Listing 6: Using a nested subtag to aggregate parameters for the parent tag
<!--- querycriteria.cfm – a simple passthrough for CF_QBE -‡
<CFPARAM NAME="attributes.optionvalues"   default="null">
<CFPARAM NAME="attributes.optiontext"   default="null">
<CFPARAM NAME="attributes.maxlength"   default="255">
<CFPARAM NAME="attributes.example"   default="">
<CFPARAM NAME="attributes.description"  default="">
 

<cfassociate basetag="cf_qbe">

Listing 7: Translating tag attributes into a client-side structure
<SCRIPT LANGUAGE="JavaScript">
<!--
function queryobject(datatype,maxlength,optionvalues,optiontext,display) {
  this.datatype=datatype;
  this.maxlength=maxlength;
  this.optionvalues=optionvalues;
  this.optiontext=optiontext;
  this.display=display;
 }
 
 queryobjects = new Array;
 
 <CFOUTPUT>

 function initialize() {
  <CFLOOP index="i" from="1" to="#arrayLen(thisTag.assocAttribs)#">
queryobjects["#thisTag.assocAttribs[i].fieldname#"] = new queryobject('#thisTag.assocAttribs[i].datatype#',
#thisTag.assocAttribs[i].maxlength#,'#thistag.assocattribs[i].optionvalues#',
'#thistag.assocattribs[i].optiontext#','#thistag.assocattribs[i].display#');
  </CFLOOP>
 }
 </CFOUTPUT>
 initialize();
 
//-->
</SCRIPT>

Listing 8: Creating an "empty" wddx JavaScript recordset to serve as a container
           for selected fields
<CFSET mycriteria = querynew("fieldname,logic,value,datatype,display,deletedyn")>
 
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

<CFWDDX  ACTION="CFML2JS"
  INPUT="#mycriteria#"
  TOPLEVELVARIABLE="searchcriteria">
...
...
...
</SCRIPT>

Listing 9:Adding a row to our wddx container
function addfield(fieldname,datatype,display) {
 
 searchcriteria.addRows(1);
 currentrow = searchcriteria.getRowCount() - 1;
 
 searchcriteria.deletedyn[currentrow]='N';
 searchcriteria.fieldname[currentrow]=fieldname;
 searchcriteria.logic[currentrow]='';
 searchcriteria.value[currentrow]='';
 searchcriteria.datatype[currentrow]=datatype;
 searchcriteria.display[currentrow]=display;

 drawCriteria();
}

Listing 10: JavaScript was responsible for outputting the following HTML
1. <tr>
2.  <td>
3.   <b>Department</b>
4.  </td>
5.  <TD>
6.   <SELECT NAME="logic0"
7. onChange="parent.parent.buttonframe.searchcriteria.logic[0]=
this.options[this.selectedIndex].value;
if (this.selectedIndex == 0)
{parent.parent.buttonframe.searchcriteria.deletedyn[0]='Y';
9. parent.parent.buttonframe.drawCriteria()}">
10.    <OPTION VALUE="DEL">(Remove)
11.    <OPTION VALUE="=" SELECTED>Equals
12.   </SELECT>
13.  </TD>
14.  <TD>
15.  <SELECT NAME="data0"
16. onBlur="parent.parent.buttonframe.searchcriteria.value[0]=
this.options[this.selectedIndex].value">
17.   <OPTION VALUE="1"SELECTED>Development</OPTION>
18.   <OPTION VALUE="4">Finance</OPTION>
19.   <OPTION VALUE="5">Human Resources</OPTION>
20.   <OPTION VALUE="3">Marketing</OPTION>
21.   <OPTION VALUE="2">Web Development</OPTION>
22.   </select>
23.  </TD>
</tr>