Using CF and AJAX to dynamically show and hide divs based on database values
Showing and hiding form and document elements on a page can be pretty useful when you're trying to walk a user through a process and you only want them to interact with controls that are geared towards to the task at hand.
There are a number of ways to do this but a very simple way is to nest your form controls inside of a div and then reference the div in your JavaScript code. Here's a simple example where I'm querying a database to figure out the behavior of how a page should act based on which option a user selects from a cfselect control.
First off, I've got a SQL Server table named PropertyDataType and it has a primary key named PropertyDataTypeCode (a simple varchar). This app will allow users to create custom properties that describe the configuration settings of various sophisticated machines in a factory. The machines can have different properties and the values of a machine setting or property will fall into 1 of 3 categories...
- True or False (As in activate Flux Capacitor? Yes/No)
- Numeric Ranges (Min/Max Values - like temperature setting between 38 and 42 degrees)
- Custom Select Options (User Defined Drop Down List of choices)
Moving on, we also have a 3 other tables in play...
- System (A simple table that uniquely identifies each machine)
- SystemProperty (A table with a compound primary key that uniquely identifies one or more properties of a machine along with the property's custom setting values defined by our user)
- SystemPropertySelector (A table that will hold user defined options created by our user should they elect to create a property that will be configured using a customizable drop down list)
So what we're trying to do is show or hide page elements based on what type of property the user is going to create. We give the user a list of property types that they can create by querying the aforementioned PropertyDataTypeCode table which gives us a list of property types and the behavior of our page. The possible behaviors are to show Min/Max controls, show a subgrid (a cfgrid that will look to our SystemPropertySelector table that holds the values of user defined drop down lists), or finally to show nothing (none - which would be the case if they chose to create a property that had a simple boolean answer).
The system.cfc method getPropertyDataType is shown below...
2 <cfargument name="propertyDataTypeCode" type="string" default="">
3 <cfquery name="qryPropertyDataType" datasource="#REQUEST.ds1#">
4 SELECT PropertyDataTypeCode,
5 Behavior
6 FROM PropertyDataType
7 <cfif ARGUMENTS.propertyDataTypeCode NEQ "">
8 WHERE PropertyDataTypeCode = <cfqueryparam cfsqltype="cf_sql_varchar" value="#ARGUMENTS.propertyDataTypeCode#">
9 </cfif>
10 ORDER BY PropertyDataTypeCode
11 </cfquery>
12 <cfreturn qryPropertyDataType>
13 </cffunction>
This just simply gets our list of property types that a user can select from. Note that the following cfselect control references the query returned by this cfc. It also has an onChange action to call a js function named controlViewState.
2 <option value=""></option>
3 </cfselect>
The controlViewState function will call a remote access method in the system.cfc that will get the behavior of the page for us so that we can decided which document elements to show and hide...
2
3 errorHandler = function(code,msg) {
4 alert('Error ' + code + ': ' + msg);
5 }
6
7 controlViewState = function(){
8 var propDataType = ColdFusion.getElementValue('propertyDataTypeCode', 'editSystemProperty', 'value');
9 var proxyControlView = new proxySystem();
10 proxyControlView.setCallbackHandler(controlViewStateCallback);
11 proxyControlView.setErrorHandler(errorHandler);
12 proxyControlView.getPropertyDataTypeBehavior(propDataType);
13 }
14
15 controlViewStateCallback = function(showHideAction){
16 switch(showHideAction){
17 case 'None':
18 minMaxControls.style.display = 'none';
19 subGridControls.style.display = 'none';
20 break;
21 case 'ShowMinMax':
22 minMaxControls.style.display = 'block';
23 subGridControls.style.display = 'none';
24 break;
25 case 'ShowSubGrid':
26 minMaxControls.style.display = 'none';
27 subGridControls.style.display = 'block';
28 ColdFusion.Grid.refresh('gridSystemPropertySelectors', true);
29 break;
30 default :
31 minMaxControls.style.display = 'none';
32 subGridControls.style.display = 'none';
33 break;
34 }
35 }
36
37</script>
The controlViewState function's callback handler is actually responsible for showing and hiding the named divs that hold our controls. So for instance if the user selects one of the following choices from our option list then we will dynamically show and hide divs based on what the Behavior column of the PropertyDataType table tells our code what to do...

So if we were to select Decimal as our Data Type then we our code would call up the database and figure out that we need to hide everything except for the controls responsible for showing Min/Max values.

If by chance we chose Selector then all controls are hidden and then we show the subGridControls div and refresh the cfgrid (this is done so that we can prepare the grid to be rendered properly - if not then it is distorted and the cfgridcolumns would be initially hidden to the end user).

The page layout is pretty simple but it is worth mentioning that you definitely don't want to forget the id attribute of your divs...
2<body>
3 <cfform name="editSystemProperty" format="html">
4 <table>
5 <tr>
6 <td colspan="2" class="areaHeaderWhite">System Property</td>
7 </tr>
8 <tr>
9 <td class="fieldLabelWhite">System Property Code</td>
10 <td>
11 <cfinput type="text" maxlength="30" size="30" name="propertyCode" value="#propertyCode#">
12 </td>
13 </tr>
14 <tr>
15 <td class="fieldLabelWhite">Data Type</td>
16 <td>
17 <cfselect name="propertyDataTypeCode" query="qryPropertyDataType" value="PropertyDataTypeCode" display="PropertyDataTypeCode" queryPosition="below" onChange="controlViewState()">
18 <option value=""></option>
19 </cfselect>
20 </td>
21 </tr>
22 </table>
23 <div id="minMaxControls" style="display:none;">
24 <table>
25 <tr>
26 <td class="fieldLabelWhite">Minimum Value</td>
27 <td>
28 <cfinput type="text" name="minVal">
29 </td>
30 <td class="fieldLabelWhite">Maximum Value</td>
31 <td>
32 <cfinput type="text" name="maxVal">
33 </td>
34 </tr>
35 </table>
36 </div>
37
38 <div id="subGridControls" style="display:none;">
39 <table>
40 <tr>
41 <td class="fieldLabelWhite">Selector Options</td>
42 </tr>
43 <tr>
44 <td>
45 <cfgrid name="gridSystemPropertySelectors" format="html" selectmode="browse" striperows="yes" height="160" width="440"
46 font="Verdana" fontsize="12" colheaderfontsize="12" selectcolor="##FF6600" colheaderfont="Verdana" pagesize="10"
47 bind="cfc:#REQUEST.cfcDir#.system.getSystemPropertySelectorGrid(
48 warehouseCode='#warehouseCode#',
49 systemCode='#systemCode#',
50 propertyCode={propertyCode},
51 page={cfgridpage},
52 pageSize={cfgridpagesize},
53 gridSortColumn={cfgridsortcolumn},
54 gridSortDir={cfgridsortdirection})">
55 <cfgridcolumn name="WarehouseCode" display="no">
56 <cfgridcolumn name="SystemCode" display="no">
57 <cfgridcolumn name="PropertyCode" display="no">
58 <cfgridcolumn name="SelectorValue" header="Selector Value" width="400">
59 </cfgrid>
60 </td>
61 </tr>
62 </table>
63 </div>
64 </cfform>
65
66</body>
67</cfoutput>

" rel="nofollow"> Ciphone </a>. d^_^bIt is very interesting.I want to introduce <a href="http://www.efox-shop.com/" rel="nofollow"> efox-shop</a> to you.