Shaun Mccran

My digital playground

26
F
E
B
2010

Combining persistent server side (ColdFusion) variables with client side (JQuery) values

I stumbled upon an interested dilemma recently whilst building a search engine. The results of a search are returned, and can be viewed in a list or thumbnail view. The view toggle is a uses a JQuery function, so no persistent data is stored concerning a users current viewing option. The dilemma is how do you maintain the viewing mode across page reloads, such as for pagination, or filtering of the search results?

[ More ]

25
F
E
B
2010

Using the JQuery dataTables plugin to display dynamic data in tables: part 1

Rather than writing out long winded table code to display your data in a tabulated fashion why not use the dataTables JQuery plugin to do it for you?

In this blog entry I'll be generating tables using a JQuery plugin, but I will also be generating the JQuery code from an XML document.

The theory behind the dataTables JQuery plugin is that when the template loads it makes an AJAX request to a remotely specified template. That template returns a JSON object of data which is formatted and used in a tabular display. This means that you can perfom filtering and sort functions inline, and the JQuery simply re submits the AJAX request, receiving new JSON each time. So no refreshing.

I'll be dealing with the auto generation of the JSON back end in the second part of this article. Here is how I setup the tabular display.

Build a standard html template, including the CSS and JQuery plugins.

view plain print about
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/transitional.dtd">
2<html lang="en-GB">
3<head>
4<InvalidTag http-equiv="Content-Type" content="text/html; charset=iso-8859-1" lang="en">
5<InvalidTag name="language" content="en-GB">
6
7<style type="text/css" title="currentStyle">
8    @import "demo_page.css";
9    @import "demo_table.css";
10</style>
11
12<s/cript type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
13<s/cript type="text/javascript" language="javascript" src="jquery.dataTables.js"></script>

Next we build our JQuery function. I wont go into massive detail about all the parameters and values being passed in here, but it is well documented on http://www.datatables.net/.

view plain print about
1<s/cript type="text/javascript" charset="utf-8">
2$(document).ready(function() {
3                $('#example').dataTable( {
4                    "bProcessing": true,
5                    "bServerSide": true,
6                    "sAjaxSource": "content.cfm",
7                    "aoColumns": [
8{ "sName": "Edit", "sTitle": "Edit", "sWidth":"10%"} ,
9{ "sName": "Band", "sTitle": "Band"} ,
10{ "sName": "Genre","sTitle": "Genre"} ,
11{ "sTitle": "Fake Column"}
12],
13                    "sPaginationType": "full_numbers",
14                    "aaSorting": [[1,'asc']],
15                    "oLanguage": {
16                        "sLengthMenu": "Page length: _MENU_",
17                        "sSearch": "Filter:"
18                    }
19                } );
20            } );
21</script>

The really important column here is the "aoColumns" JSON data block. This specifies what fields are returned from your AJAX call, and parameters they must adhere to.

In this example we are anticipating that we will receive four columns of data back (Edit,Band,Genre and Fake Column).

Lastly we create a table with an ID of "example", as this is what the JQuery is looking for. This table must be formatted in a certain way, as the JQuery plugin will re write the specified elements.

view plain print about
1<table cellpadding="0" cellspacing="0" border="0" class="display" id="example">
2<thead>
3<tr>
4 <th>Edit</th>
5 <th>Band</th>
6 <th>Genre</th>
7 <th>Fake Column</th>
8</tr>
9</thead>
10 <tbody>
11 <tr>
12 <td colspan="3" class="dataTables_empty">Loading data from server</td>
13 </tr>
14 </tbody>
15</table>

The code also contains the header elements that will match the returned column values from the AJAX request. The last part of the table is displayed when the data is loading.

This all works well, but to extend it further I have altered the code to read from an XML document. The XML document Is loaded when the template starts, and the data fields and attributes are read, and looped over to create the JQuery code and table headers. In this way it is a generic table display template, driven from an XML document.

The XML doc:

view plain print about
1<?xml version="1.0"?>
2 <form>
3 <field sName="Edit" source="data" sTitle="Edit" sWidth="10%">Edit</field>
4 <field sName="Band" source="data" sTitle="Band">Band</field>
5 <field sName="Genre" source="data" sTitle="Genre">Genre</field>
6 <field sName="fake column" source="" sTitle="Fake Column">Fake column</field>
7 </form>

Read the XML file and parse it out into an Array:

view plain print about
1<!--- parse the xml file --->
2<cfset variables.xml = XMLParse("test.xml") />
3<!--- <cfdump var="#variables.xml#" label="Raw xml document"> --->
4<cfset variables.fields = XMLSearch(variables.xml,"form/field")>
5<cfset variables.totalRecords = ArrayLen(variables.fields)>

Use something like this to dynamically generate the JQuery and table values:

view plain print about
1<cfoutput>
2<cfloop index="variables.index" from="1" to="#ArrayLen(variables.fields)#">
3 { <cfif variables.fields[variables.index].XmlAttributes.source EQ "data">"sName": "#variables.fields[variables.index].XmlAttributes.sName#",</cfif>
4 <cfif structkeyexists(variables.fields[variables.index].XmlAttributes, 'sTitle')>"sTitle": "#variables.fields[variables.index].XmlAttributes.sTitle#"</cfif>
5 <cfif structkeyexists(variables.fields[variables.index].XmlAttributes, 'sWidth')>,"sWidth":"#variables.fields[variables.index].XmlAttributes.sWidth#"</cfif>
6 } <cfif variables.index NEQ variables.totalRecords>,</cfif>
7</cfloop>
8</cfoutput>
9<!--- table values --->
10
11<cfoutput>
12 <cfloop index="variables.index" from="1" to="#ArrayLen(variables.fields)#">
13 <th align="left">#variables.fields[variables.index].XmlText#</th>
14 </cfloop>
15</cfoutput>

The JSON response is hard coded in this example, so the result will not filter or search. I'll handle that in article two.

There is a full example of this here.

23
F
E
B
2010

Creating a pop up floating div with JQuery

This entry will deal with how to create a displayed / collapsible floating div, using JQuery. When I build a web platform I often like to include small sections of text alongside the functionality, just to provide the users with a little guidance on what is going on. Rather than having these inline, where they can often interfere with the content and display, I like to add them to a 'help' div that I float inside the framework. First we include the JQuery library from Google, and our link. It doesn't go anywhere, but we will attach a JQuery event to it.
view plain print about
1<s/cript type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
2
3<a href="javascript:void(0);" id="help">Pop me up</a>
4<div>stuff</div>
Next we create our JQuery function, attached to the 'help' div. This adds a div to the document with whatever content you have set in it. There is also a 'close' link in the floating div that calls the close function.
view plain print about
1<s/cript>
2 $(function() {
3 $("#help").live('click', function(event) {
4 $(this).addClass("selected").parent().append('<div class="messagepop pop">Content<p><a class="close" href="/">Cancel</a></p></div>');
5 $(".pop").slideFadeToggle()
6 return false;
7 });
8
9 $(".close").live('click', function() {
10 $(".pop").slideFadeToggle();
11 $("#contact").removeClass("selected");
12 return false;
13 });
14 });
15
16 $.fn.slideFadeToggle = function(easing, callback) {
17 return this.animate({ opacity: 'toggle', height: 'toggle' }, "fast", easing, callback);
18 };
19</script>
Lastly we add some styling and positioning to tie the whole lot together. This gives the pop up div its shape and style. I've positioned the floating div on top of the calling function text.
view plain print about
1<style>
2a.selected {
3 background-color:#1F75CC;
4 color:white;
5 z-index:100;
6}
7
8.messagepop {
9 background-color:#FFFFFF;
10 border:1px solid #999999;
11 cursor:default;
12 display:none;
13 margin-top: 15px;
14 position:absolute;
15 text-align:left;
16 width:394px;
17 z-index:50;
18 padding: 25px 25px 20px;
19 top: 0px;
20 left: 0px;
21}
22}
23
24label {
25 display: block;
26 margin-bottom: 3px;
27 padding-left: 15px;
28 text-indent: -15px;
29}
30
31.messagepop p, .messagepop.div {
32 border-bottom: 1px solid #EFEFEF;
33 margin: 8px 0;
34 padding-bottom: 8px;
35}
36</style>
You can see an example functionality here.

16
F
E
B
2010

Controlling show() hide() Divs with a JQuery powered Select field

There are many ways of hiding all your page elements then only showing specific areas based on user selection. One old school way of changing the displayed page content was with a select field that had an onchange event that posted to the same page, but with a URL variable.

I have been testing out a variation on this using the JQuery show() / hide() functions.

We attach an event to the select field, and pass the selected option to a JQuery function, as in the example code below.

view plain print about
1<s/cript type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
2
3<select name="field_data_loc[key]" class="form-select required" id="edit-field-data-loc-key" onChange="showHide(this.value)" >
4<option value="didnotchoose" selected="selected">Choose</option>
5<option value="web">Website</option>
6<option value="file">File to upload</option>
7<option value="url">Url</option>
8</select>

We have a series of DIV's that are named the same as the select field options. All these DIV's will be hidden by default, apart from the "start" div.

view plain print about
1<div id="start">Starting div</div>
2
3<div id="url">url</div>
4
5<div id= "file">file</div>
6
7<div id= "web">web</div>

Lastly we have our JQuery script. Here we have our showHide function. This accepts a DIV id, which is then shown. All other DIV's are hidden.

The last piece of script here simply hides all the DIV's on the page load, so that they are all hidden by default.

view plain print about
1<s/cript language="javascript">
2
3    function showHide(obj)
4        {
5            var showDiv = "#"+obj;
6            $("div").hide();
7            $(showDiv).show();
8        }
9
10    // hide all the divs on start up
11    $('#web').hide();
12    $('#file').hide();
13    $('#url').hide();
14
15</script>

Putting it all together, and making it dynamic based on a list, it looks like this:

view plain print about
1<cfset variables.mylist = "scotland,england,wales,ireland">
2
3<s/cript type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
4
5<cfoutput>
6<select name="field_data_loc[key]" class="form-select required" id="edit-field-data-loc-key" onChange="showHide(this.value)" >
7<option value="didnotchoose" selected="selected">Choose</option>
8
9    <cfloop list="#variables.mylist#" index="variables.index">
10        <option value="#variables.index#">#variables.index#</option>
11    </cfloop>
12
13</select>
14
15<div id="start">Starting div</div>
16
17<cfloop list="#variables.mylist#" index="variables.index">
18    <div id="#variables.index#">#variables.index#</div>
19</cfloop>
20
21<s/cript language="javascript">
22
23    function showHide(obj)
24        {
25            var showDiv = "##"+obj;
26
27            <cfloop list="#variables.mylist#" index="variables.index">
28                $('###variables.index#').hide();
29            </cfloop>
30                $('##start').hide();
31
32            //$("div").hide();
33            $(showDiv).show();
34        }
35
36<cfloop list="#variables.mylist#" index="variables.index">
37    $('###variables.index#').hide();
38</cfloop>
39
40</script>
41</cfoutput>

An example is here.

_UNKNOWNTRANSLATION_ /