Breakdown of the MyRides homepage
My blog post this evening will talk about the current homepage of my MyRides application that I am working on using CfWheels. The homepage currently shows some statistics about all of my rides as a whole and a data grid that shows all of the individual rides and allows the user to click on any ride to see a detailed view. I needed to create a controller cfc, a view file and a default layout to make this page work. Here is the breakdown and code for each:
In my Wheels controller directory I created a MyRides.cfc file with the following code for the index page:
<cffunction name="index">
<cfset rides = model("ride").findAll(order="date DESC", select="id, name, description, date, totaltime, movingtime, distance, distanceunit, averagespeed, averagemovingspeed, maxspeed, speedunit, minelevation, maxelevation, elevationgain, elevationunit, map, centerlocation, initialzoom")>
<cfset totalRides = model("ride").count()>
<cfset totalMileage = model("ride").sum("distance")>
<cfset totalElevation = model("ride").sum("elevationgain")>
<cfset avgSpeed = model("ride").average(property="averagespeed")>
<cfset avgMovingSpeed = model("ride").average(property="averagemovingspeed")>
<cfset avgDistance = model("ride").average(property="distance")>
</cffunction>
Two things are happening in this function that runs for the index page. First, I'm retrieving all of the ride data that I need for displaying the data in the grid. The following code allowed for data retrieval ordered by date in descending order.
<cfset rides = model("ride").findAll(order="date DESC", select="id, name, description, date, totaltime, movingtime, distance, distanceunit, averagespeed, averagemovingspeed, maxspeed, speedunit, minelevation, maxelevation, elevationgain, elevationunit, map, centerlocation, initialzoom")>
Next, I used some of the built in Wheels column statistics functions to calculate and display my statistics.
<cfset totalRides = model("ride").count()>
<cfset totalMileage = model("ride").sum("distance")>
<cfset totalElevation = model("ride").sum("elevationgain")>
<cfset avgSpeed = model("ride").average(property="averagespeed")>
<cfset avgMovingSpeed = model("ride").average(property="averagemovingspeed")>
<cfset avgDistance = model("ride").average(property="distance")>
For the page view I had to create an index.cfm file in the Wheels views directory.
<cfparam name="title" type="string" default="MyRides - Home">
<cfoutput>
<h1>2010 Cycling Season - #totalRides# total rides</h1>
<div id="rides">
<table id="flex1" style="display:none"></table>
<invalidTag type="text/javascript">
$("##flex1").flexigrid
(
{
url: '/myrides/controllers/MyRides.cfc?method=getGridData',
dataType: 'json',
colModel : [
{display: 'ID', name : 'id', width : 20, sortable : true, align: 'left'},
{display: 'Name', name : 'name', width : 470, sortable : true, align: 'left'},
{display: 'Date', name : 'date', width : 130, sortable : true, align: 'center'},
{display: 'Distance', name : 'distance', width : 40, sortable : true, align: 'left'},
{display: 'Total Time', name : 'totaltime', width : 50, sortable : true, align: 'left'}
],
/*searchitems : [
{display: 'Date', name : 'date'},
{display: 'Name', name : 'name', isdefault: true}
],*/
sortname: "date",
sortorder: "desc",
usepager: true,
title: 'Rides',
useRp: false,
rp: 5000,
showTableToggleBtn: true,
width: 790,
height: 300,
onrowclick:"move"
}
);
</script>
<div id="stats">
<h2>Ride Statistics</h2>
<ul>
<li>Total Mileage: #totalMileage# miles</li>
<li>Total Elevation Gain: #numberformat(totalElevation, ',')# feet</li>
<li>Average Speed: #numberformat(avgSpeed, '__.__')# mph</li>
<li>Average Moving Speed: #numberformat(avgMovingSpeed, '__.__')# mph</li>
<li>Average Distance: #numberformat(avgDistance, '__.__')# miles</li>
</ul>
</div>
</div>
</cfoutput>
I'm using the Flexigrid jquery plugin for my datagrid as I'm running the site on Railo and do not have the ability to use the Adobe ColdFusion datagrid. I used the numberformat function to format the statistical values returned from my controller function.
The final piece to this is the layout file located in the views directory. I used the default layout for the homepage. Here is the code:
<cfsetting enablecfoutputonly="true">
<!--- Title is required --->
<cfparam name="title" type="string">
<!--- Because this is XHTML, we need to output the DOCTYPE as the first
character of the first line, or else we get Quirks Mode! --->
<cfoutput>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<invalidTag http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>#title#</title>
#stylesheetLinkTag("myrides")#
#stylesheetLinkTag("flexigrid")#
#javaScriptIncludeTag("jquery")#
#javaScriptIncludeTag("flexigrid")#
</head>
<body>
<div id="wrap">
<div id="top-bg"></div>
<div id="header">
<h1 id="logo-text">
<p>#linkTo(text="MyRides", action="index")#</p>
</h1>
<p id="slogan">#linkTo(text="CfWheels App for tracking my cycling", action="index")#</p>
</div>
<div id="content-wrap">
<div id="main">
#contentForLayout()#
</div>
</div>
<div id="footer-wrap">
<div id="footer-columns">
<!--- THEME footer-columns ends --->
</div>
<div id="footer-bottom">
</div>
<!--- THEME footer ends --->
</div>
</div>
</body>
</html>
</cfoutput>
<cfsetting enablecfoutputonly="false">
In the head section I used the stylesheetlinktag and the javascriptincludetag helper functions to include my javascript and stylesheets. Stroing the files in the respective javascript and stylesheet directories make the organization straight forward and saves on some typing.
I would love to hear any feedback or suggestions from any CfWheels veterans out there as any questions from people new to the frame work that did not find this post to be clear.