Shaun Mccran

My digital playground

22
M
A
R
2010

Creating an image preview using JQuery and a select form field

This article will deal with a user choosing a value from a Select field, and that selection being passed to a JQuery handler. The JQuery handler will perform an AJAX request to a CFC, which will return a JSON value (URL String) that we will use to populate an img html tag.

In this way when you select different options from the select field drop down, the image changes inline, without any page reloads.

[ More ]

15
M
A
R
2010

Using other plug-ins with the JQuery Carousel Plug-in and event issues

This entry examines how the JQuery Carousel object interacts with other Plug-ins, and how to combine those plug-ins with the Carousel functionality. I also cover an issue where the jCarousel plug-in does not apply functionality to non visible elements when the page loads.

[ 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.

20
A
U
G
2009

Connecting Select form fields based on data selections Pt 3

I've been exploring various methods of using JQuery to populate Select form fields. In the previous article I used an intermediary file to act as a handler for the JSON returned object. In this last article I have removed the extra handler template, interfacing directly with the CFC.

Firstly there are some small changes to the JQuery url call.

view plain print about
1<scr/ipt src="jquery-1.2.3.js" type="text/javascript"></script>
2<scr/ipt src="select-chain.js" type="text/javascript" charset="utf-8"></script>
3<scr/ipt type="text/javascript">
4 jQuery.noConflict();
5 jQuery(function () {
6 var type = jQuery('#series');
7 var sp = jQuery('#issueno');
8 var selectedSeries = jQuery('#series').val();
9
10 type.selectChain({
11 target: sp,
12 url: 'jquerySeries.cfc?method=getIssueNos',
13 type: 'post',
14 data: { ajax: true, returnformat: 'plain', series: selectedSeries }
15 }).trigger('change');
16
17 });
18</script>

Now we are directly referencing the CFC. Simply append the function name as a url parameter. In the "DATA" element we place the data we are passing in the form of key value pairs. This will build all the values into the JQuery url, so the final URL would be:

view plain print about
1jquerySeries.cfc?method=getIssueNos&ajax=true&returnformat=plain&series=selectedSeries

At this point I was getting an parse error, until I found the 'returnFormat' value. Coldfusion will return WDDX encoded packets by default, problem was my handler was looking for Json. Adding this value will stop this.

Next we have the same form as before, there are no changes at all: (here for completeness really)

view plain print about
1<cfset variables.series = createObject("component","jquerySeries").getSeries()>
2 <form action="" method="post">
3 <select name="series" id="series">
4 <cfoutput query="variables.series">
5 <option value="#variables.series.intId#">#variables.series.varName#</option>
6 </cfoutput>
7 </select>
8 <select name="issueno" id="issueno">
9 <option></option>
10 </select>
11 <button type="submit">Submit</button>
12 </form>

Lastly there are one or two small changes to our CFC function.

view plain print about
1<cffunction name="getIssueNos" access="remote" output="false" hint="returns related series issue numbers">
2        <cfargument name="series" type="numeric" required="false" hint="Id of the publication">
3        <cfset var result = "">
4
5        <cfquery name="result" datasource="#application.ds#">
6            SELECT [intIssueNo]
7            FROM [dbo].[tbl_cn_series_issueNos]
8            where intSeriesId = <cfqueryparam value="#arguments.series#" cfsqltype="cf_sql_integer">
9        </cfquery>
10        
11        <cfsetting showdebugoutput="false">
12        <cfset ojson = createObject("component","cfjson")>
13        <cfset theresults = ojson.encode(listToArray(valuelist(result.intIssueNo)))>
14        <cfsetting enablecfoutputonly="true">
15    <cfreturn theresults>
16    </cffunction>

The access method has changed, so we add an "access=remote" value to expose the function as a service. Then we serialize the query result into JSON, and return it. This seems like a much more succinct way of doing this.

_UNKNOWNTRANSLATION_ /