Tracking users and search engines spiders in coldfusion
If you want to find out what CGI variables you have available, just create a <cfdump var = "#cgi#">
Example output from local host:
struct
AUTH_PASSWORD
[empty string]
AUTH_TYPE
[empty string]
AUTH_USER
[empty string]
CERT_COOKIE
[empty string]
CERT_FLAGS
[empty string]
CERT_ISSUER
[empty string]
CERT_KEYSIZE
[empty string]
CERT_SECRETKEYSIZE
[empty string]
CERT_SERIALNUMBER
[empty string]
CERT_SERVER_ISSUER
[empty string]
CERT_SERVER_SUBJECT
[empty string]
CERT_SUBJECT
[empty string]
CF_TEMPLATE_PATH
C:\Inetpub\wwwroot\ApplayIT\cgi_test.cfm
CONTENT_LENGTH
0
CONTENT_TYPE
[empty string]
GATEWAY_INTERFACE
CGI/1.1
HTTPS
off
HTTPS_KEYSIZE
[empty string]
HTTPS_SECRETKEYSIZE
[empty string]
HTTPS_SERVER_ISSUER
[empty string]
HTTPS_SERVER_SUBJECT
[empty string]
HTTP_ACCEPT
*/*
HTTP_ACCEPT_ENCODING
gzip, deflate
HTTP_ACCEPT_LANGUAGE
en-us
HTTP_CONNECTION
Keep-Alive
HTTP_COOKIE
CFID=11202; CFTOKEN=60629250
HTTP_HOST
localhost
HTTP_REFERER
[empty string]
HTTP_USER_AGENT
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Q312461; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Dreamweaver MX 2004 7.0.2052)
PATH_INFO
/applayit/cgi_test.cfm
PATH_TRANSLATED
c:\inetpub\wwwroot\applayit\cgi_test.cfm
QUERY_STRING
[empty string]
REMOTE_ADDR
127.0.0.1
REMOTE_HOST
127.0.0.1
REMOTE_USER
[empty string]
REQUEST_METHOD
GET
SCRIPT_NAME
/applayit/cgi_test.cfm
SERVER_NAME
localhost
SERVER_PORT
80
SERVER_PORT_SECURE
0
SERVER_PROTOCOL
HTTP/1.1
SERVER_SOFTWARE
Microsoft-IIS/5.1
WEB_SERVER_API
[empty string]
Example code:
<cfoutput>#CGI.SERVER_NAME#</cfoutput>
Output:
localhost
This tutorial will show who is visiting your pages, both users and search engine spiders. You can also see how a visitor goes from page to page on your site. It will also give you information about which page or URL the visitors came from. You will also get the name of the search engines spider and you can see which pages the spider has indexed.
What information we need to capture:
The date and time:
The Now() function returns the current date and time from the server.
If you are using a SQL database, use getDate() instead of Now().
The referring page information:
The CGI variable CGI.HTTP_REFERER will capture referring page information. Using the Cold Fusion LEFT string function strips the extra characters providing the number of characters you choose.
Example: LEFT(CGI.HTTP_REFERER, 128)
Notice:
Some versions of IE 5.5, Opera, and AOL don't even recognize the http_referer command. Netscape 7 doesn't like it at all. Microsoft and Netscape have both realized this problem and aren't offering any resolutions.
The IP address of the client computer:
The CGI variable CGI.REMOTE_ADDR will capture the IP address of the client computer. Example: 216.119.65.128.
The client hostname:
The CGI variable CGI.HTTP_HOST will capture the client hostname server.
The browser type of the visitor:
The CGI variable CGI.HTTP_USER_AGENT will capture the browser type of the visitor.
The page name on your site:
The name of the page is typed in on the pages you want to track.
Example:
For the home page:
<cfmodule template = "admin/act_tracker.cfm" page_track = "Home">
For the product page:
<cfmodule template = "admin/act_tracker.cfm" page_track = "Product">
If you?re using Fusebox, write this code in the fbx_layouts.cfm layout file on the root:
<cfmodule template = "admin/act_tracker.cfm" page_track = "#fusebox.circuit#">
In the examples above we have the tracker.cfm file in the directory admin. Change this if you?re using another path to tracker.cfm.
Creating the database:
Here's an example of an Access database for the user tracking:
Field Name
Data Type
Description
Tracking_ID AutoNumber Primary Key.
Tracking_Date Date/Time The date and time.
Tracking_Referrer Text The referring page information.
Tracking_Client_Address Text The IP address of the client computer.
Tracking_Client_Host Text The client hostname.
Tracking_Client_Browser Text The browser type of the visitor.
Tracking_Resource Text The page name on your site.
Follow this link to see an animated tutorial how to add and manage your data source connections and Data Source Names (DSNs).
Setting global variables in the application file.
The application file:
<!--- The name of your database. --->
<cfset request.main_access_DB = "database_name">
<!--- The database username. --->
<cfset request.dbusername = "your_username">
<!--- The database password. --->
<cfset request.dbpassword = "your_password">
The act_tracker.cfm file:
The purpose of this file is to get the name of the page(s) you want to track, and save information to the database.
If you have access to the CustomTag directory on your server you can save the file there, or you can save the file in another directory and use cfmodule tag to call the act_tracker.cfm file.
This file needs one parameter, the name of the page you want to track. Below are some examples of the code you need to implement on the pages you want to track.
Here's an example using the cfmodule tag.
<cfmodule template="admin/act_tracker.cfm"
page_track = "Home">
In the example the act_tracker.cfm file is located under the admin directory and the page we want to track is 'Home'.
If you want to track a page called 'Products' in the directory products:
<cfmodule template="admin/act_tracker.cfm"
page_track = "Products">
Or if you track your index.cfm file:
<cfmodule template="admin/act_tracker.cfm"
page_track = "The index file">
If you are using FuseBox, put the code in the fbx_layouts.cfm file:
<cfmodule template="admin/act_tracker.cfm"
page_track = "#fusebox.circuit#">
Notice: The #fusebox.circuit# contains the fuseaction which is being processed.
Here?s code for the act_tracker.cfm file:
<!--- The date and time. --->
<cfset Tracking_Date = Now()>
<!--- The referring page information. --->
<cfparam name="cgi.http_referer" type="string"default="">
<!--- The IP address of the client computer. --->
<cfparam name="cgi.remote_addr" type="string"default="">
<!--- The client hostname. --->
<cfparam name="cgi.http_host" type="string"default="">
<!--- The browser type of the visitor. --->
<cfparam name="cgi.http_user_agent" type="string"default="">
<!--- The page name on your site. --->
<cfparam name="attributes.page_track" type="string" default="Page Name">
<!--- Ok we have that data. Insert them into our database. --->
<cfquery name="tracker_insert" datasource="your_datasource" username="your_username" password="your_password">
INSERT INTO tracker_db
(Tracking_Date,
Tracking_Referrer,
Tracking_Client_Address,
Tracking_Client_Host,
Tracking_Client_Browser,
Tracking_Resource)
VALUES
(#Tracking_Date#,
'#left(cgi.http_referer,128)#',
'#left(cgi.remote_addr,128)#',
'#left(cgi.http_host,128)#',
'#left(cgi.http_user_agent,128)#',
'#attributes.page_track#')
</cfquery>
If you?re running SQL delete the
<!--- The date and time. --->
<cfset Tracking_Date = Now()>
and replace the insert code:
INSERT INTO tracker_db
(Tracking_Date,
Tracking_Referrer,
Tracking_Client_Address,
Tracking_Client_Host,
Tracking_Client_Browser,
Tracking_Resource)
VALUES (getdate(),
(getdate(),
'#left(cgi.http_referer,128)#',
'#left(cgi.remote_addr,128)#',
'#left(cgi.http_host,128)#',
'#left(cgi.http_user_agent,128)#',
'#attributes.page_track#')
The dsp_tracker.cfm file:
This file will display the contains in the database. You can specify in the query what you want to display.
Here's an example displaying all the fileds and the last 100 records:
<cfquery name="User_tracking" datasource="# request.main_access_DB#" username="#request.dbusername#" password="#request.dbpassword #">
SELECT * FROM tracker_db
order by Tracking_ID Desc
</cfquery>
<cfoutput query="User_tracking" maxrows="100">
#Tracking_Date# #Tracking_Referrer# #Tracking_Client_Address# #Tracking_Client_Host# #Tracking_Client_Browser# #Tracking_Resource# <br>
</cfoutput>
You can also add an automatic refrech on the dsp_tracker.cfm file, example refrech = 30 sec.
ColdFusion,Dotnet,JavaScript,Html,SqlServer and Everything
About Programming Tips and Tricks
Tuesday, October 14, 2008
Monday, October 13, 2008
poll in coldfusion
DOWNLOAD CFPOLL SOURCECODE
Have you ever wanted to have your own website poll in ColdFusion. If so, then hopefully the tuto-
rial below will allow you to finally add one. Or perhaps it will provide you with the incentive to
improve this one.
Some important poll features:
- Writes a cookie once the poll has been used so that the voter may not vote in the current poll
again.
(and is once again useable).
- Checks to see if a person tries to use their browser’s back button to make multiple votes and
informs them this is not allowed.
- Checks to see if the user made a selection when voting and informs them if they haven’t made
a selection.
- Checks to see if a user accessed the results page without hitting the ‘Vote’ button and then dis-
plays the current votes without adding a vote to the poll.
- Allows for users to view previous polls and results.
- Displays the results for all polls using a graphical bar as well as the numerical vote count (indi-
vidual and total) and vote results as percentages.
I also created an administration side to this system so the website owner can add, edit or remove
polls online. You will find more information on this towards the end of this tutorial. Of course, you
should only upload these pages to a secure area of your website so random people don’t edit your
polls ;)
This poll system has been created so that the poll question/answers or results are displayed in a
webpage’s header or footer using ColdFusion’s ‘cfinclude template’ code.
<CFAPPLICATION NAME=”Cookies”
SessionManagement=”Yes”
setDomainCookies=”Yes”
setClientCookies=”Yes”>
vote.cfm
From here on in, it gets harder. But hopefully it’ll all make sense once you get into it. The next
<cfif IsDefined(”cookie.poll”)>
<cfif “#Cookie.Poll#” is “#CurrentID.QuestionID#”>
Display the poll results
<cfelse>
Show the poll form with ‘Vote’ button
</cfif>
<cfelse>
Cookie does not exist. Show the poll form with ‘Vote’ button
</cfif>
What we check for first, is if the cookie for the poll already exists.
<cfif IsDefined(”cookie.poll”)>
Next, we check to see if the existing cookie is current. We do this by checking to see if the cookie’s
value is the same as the last (most recent) ‘QuestionID’ in the ‘Questions’ table of our database.
We do this by returning one row of ‘QuestionID’ in descending order.
<cfquery datasource=”fusionpoll” name=”CurrentID” MAXROWS=”1”>
SELECT Questions.QuestionID
FROM Questions
ORDER BY QuestionID DESC
</cfquery>
<cfif “#Cookie.Poll#” is “#CurrentID.QuestionID#”>
If the cookie is current, then the user has already voted and we display the current poll results. To
do this, we need to query the database for the current question, answers and votes.
<cfquery datasource=”fusionpoll” name=”Totals”>
SELECT Questions.Question, SUM(Answers.Votes) AS TotalVotes
FROM Questions INNER JOIN Answers
ON Questions.QuestionID=Answers.QuestionID
WHERE Questions.QuestionID=#Cookie.Poll#
GROUP BY Questions.Question
<!--- Query the answers and the number of votes for each one. --->
<cfquery datasource=”fusionpoll” name=”Results”>
SELECT Answers.Answer, Answers.Votes
FROM Answers
WHERE Answers.QuestionID=#Cookie.Poll#
ORDER BY Answers.AnswerID
</cfquery>
Once we have done this, we display the results using cfoutput. Below is the code I used to display
the results.
<table width=”175” border=”0” align=”center” cellpadding=”2” cellspacing=”0”>
<!--- Display the question --->
<cfoutput query=”Totals”>
<tr>
<td><div align=”center”><strong>#Question#</strong></div></td>
</tr>
</cfoutput>
<!--- Display the answers and their number of votes. --->
<cfoutput query=”Results”>
<!--- Set the percent of total votes for each answer. --->
<cfset Percent=Round((Votes / Totals.TotalVotes) * 100)>
<tr>
<td><div align=”left”>#Answer#</div></td>
</tr>
<tr>
<!--- Display the percentage of votes in a graph format. --->
<td><div align=”left”><img align=”middle” src=”images/poll-graph.gif” width=”#Percent#%”
height=”5”></div></td>
</tr>
<tr>
<td><div align=”right”><em>#Votes# votes - #Percent#%</em></div></td>
</tr>
</cfoutput>
<!--- Display the total number of votes --->
<cfoutput query=”Totals”>
<tr>
<td><div align=”right”><strong>Total:</strong><em><strong>
</strong>#Int(TotalVotes)# votes</em></div></td>
</tr>
</cfoutput>
</table>
The way you display the code is entirely up to you of course, but there are some things to take
notice of in the code above. For example:
<cfset Percent=Round((Votes / Totals.TotalVotes) * 100)>
This code sets ‘Percent’ as the percentage an individual vote has received by dividing the
‘Answers.Votes’ by the total number of votes(as defined in the previous ‘Totals’ query) and multi-
plying that number by 100. This is then used to set the width of the graphical display for the poll.
width=”#Percent#%”
In the image attributes, we have set the width of the image as the same percentage we calculated
previously. The last important note in the above code is that #Int(TotalVotes)# votes displays the
total number of votes for the current poll.
Continuing on with the vote.cfm page, the next step covers what to do if the cookie is not current.
If the cookie is not current, then the user has not yet voted in this poll and therefore needs to
view the question and answer choices with the ‘Vote’ button so they can vote. To make this possi-
database. We discover what the latest question is in the same way we did when checking to see if
the cookie was current.
<cfquery datasource=”fusionpoll” name=”Current” MAXROWS = “1”>
SELECT Questions.QuestionID
FROM Questions
ORDER BY Questions.QuestionID DESC
</cfquery>
<cfset display = #Current.QuestionID#>
<cfquery datasource=”fusionpoll” name=”Question”>
SELECT Questions.QuestionID, Questions.Question, Answers.AnswerID, Answers.Answer
FROM Questions INNER JOIN Answers
ON Questions.QuestionID = Answers.QuestionID
WHERE Questions.QuestionID = #display#
ORDER BY Answers.AnswerID
</cfquery>
The first query (’Current’) selects the latest question from the ‘Questions’ table thanks to our hav-
ing the MAXROWS set at “1” and by querying in descending order. Then we set ‘display’ as the
current question so we can select the corresponding answers from the ‘Answers’ table. All that is
required then is to display the form using the selected query output.
<form action=”results.cfm” method=”post” name=”Poll”>
<table border=”0” align=”center” cellpadding=”4” cellspacing=”0”>
<cfoutput query=”Question” group=”QuestionID”>
<!--- Pass the question id as a hidden variable. --->
<input type=”hidden” name=”QuestionID” value=”#QuestionID#”>
<tr>
<td colspan=”2”><div align=”center”><strong>#Question#</strong></div></td>
</tr>
<!--- Display the answers and their checkboxes --->
<cfoutput>
<td width=”10”><input type=”radio” name=”AnswerID” value=”#AnswerID#”></td>
<td><div align=”left”>#Answer#</div></td>
</tr>
</cfoutput>
</cfoutput>
<tr>
<td colspan=”2” align=”center”><input name=”Submit” type=”submit” value=”Vote”></td>
</tr>
<tr>
<td colspan=”2” align=”center”><div align=”center”>[<a
href=”results.cfm.QuestionID=<cfoutput>#display#</cfoutput>”>View
Poll Results</a>]
<br>
[<a href=”results.cfm”>Previous Poll Results</a>]</div></td>
</tr>
</table>
</form>
You should notice two links to results.cfm after the ‘Vote’ button in the code above. These will be
explained a little bit later.
Next, we have to check if none of the previous rules applied. What to do if the cookie did not ex-ist at all. If this is the case, then we simply use the same code as above to show the current poll
question and multiple choice answers with the ‘Vote’ button. If a cookie does not exist, the person
has not yet voted at all.
results.cfm
The next page is the results.cfm page which is where our vote.cfm page sent the form details
to. Unlike vote.cfm however, results.cfm is not placed in the header or footer of the website. The
results.cfm pageincludes the footer file (which then includes the vote.cfm page).
Shown below is a basic rundown of the layout of this page.
<cfif isDefined(’Form.QuestionID’)>
<cfif IsDefined(”cookie.poll”)>
<cfif “#Cookie.Poll#” is “#CurrentID.QuestionID#”>
Show warning for attempted multiple votes
<cfelse>
Nothing
</cfif>
</cfif>
Set Cookie, add vote to database and display the answer selected by the vote
<cfelse>
Show warning for no answer selected
</cfif>
<cfelse>
<cfif isdefined (’URL.QuestionID’)>
<cfif check.AllVotes is “0”>
Show warning for no votes in current poll
<cfelse>
Display poll results
</cfif>
<cfelse>
Show the droplist for the previous polls
</cfif>
</cfif>
The first check we must perform is to see if the page was reached by somebody using the form.
We do this by checking for ‘QuestionID’ from the votes.cfm page.
<cfif isDefined(’Form.QuestionID’)>
8
And next we check to see if the poll user made a selection when they hit the ‘Vote’ button. And we
do this by checking for ‘AnswerID’ from the votes.cfm page.
<cfif isDefined(’Form.AnswerID’)>
And the next check is to stop people from voting more than once by using their browser’s back
button. We check for the existence of a cookie.
<cfif IsDefined(”cookie.poll”)>
vote.cfm page. If it is current, we display a message telling the user they can not vote more than
once.
<cfquery datasource=”fusionpoll” name=”CurrentID” MAXROWS=”1”>
SELECT Questions.QuestionID
FROM Questions
ORDER BY QuestionID DESC
</cfquery>
<cfif “#Cookie.Poll#” is “#CurrentID.QuestionID#”>
<br>
<div align=”center”>Sorry, you can only vote once.</div>
<cfinclude template=”foot.cfm”>
<cfabort>
It is important to have the ‘cfabort’ code in this part of the webpage or else you will end up with
two footers in your page display. Once we have performed those checks, we know the cookie is
not current (or existing) so we set a new cookie.
<cfcookie name=”Poll” value=”#Form.QuestionID#” expires=”never”>
The value of the cookie is set as the ‘QuestionID’ value so that we can later tell if a cookie is
current when we add a new poll question. The cookie’s expiration is set to “never” because we
will simply update it whenever we add a new poll to our website. If you set your cookie to expire
before you set a new poll, people will be able to vote again.
Once the cookie is set and the vote has been made, we must update the ‘Answers’ table with the
new vote count. We select the current vote count from the ‘Answers’ table for the current ques-
tion and chosen answer (from vote.cfm) and then set ‘NewVotes’ as the current vote plus one new
vote. Then we update the votes where the ‘QuestionID’ and ‘AnswerID’ are the same as the ones
passed through from our vote.cfm page.
<cftransaction>
SELECT Votes
FROM Answers
WHERE QuestionID=#QuestionID# AND AnswerID=#AnswerID#
</cfquery>
<cfset NewVotes=LastVote.Votes + 1>
<cfquery datasource=”fusionpoll” name=”NewVote”>
UPDATE Answers
SET Votes=#NewVotes#
WHERE QuestionID=#QuestionID# AND AnswerID=#AnswerID#
</cfquery>
</cftransaction>
Next, we create queries so we can display the new vote count for all answers in the current poll.
Once this is done, you simply display the ‘QuestionID’ and ‘AnswerID’ to show the user how they
voted in the poll.
<cfquery datasource=”fusionpoll” name=”showanswer”>
SELECT Answers.Answer, Answers.AnswerID
FROM Answers
WHERE Answers.AnswerID = #AnswerID#
</cfquery>
<cfquery datasource=”fusionpoll” name=”showquestion”>
SELECT Questions.QuestionID, Questions.Question
FROM Questions
WHERE Questions.QuestionID = #QuestionID#
</cfquery>
However, if the user had hit the ‘Vote’ button without making a selection from the radio button list,
we would need to tell them of their mistake and not update the database with any votes.
<cfelse>
<!--- No radio button selected, so tell the user to try again --->
<br>
<div align=”center”>Sorry, you didn’t select anything. Please select an answer before hitting the
Next, we check to see if the page was accessed without somebody using the poll form. For exam-
ple, an option I’ve added to the poll is for a user to view the current poll votes before they vote for
themselves (this is one of the links I mentioned earlier that appears under the ‘Vote’ button of the
poll). So we must check to see if that is what they are doing.
<cfif isdefined (’URL.QuestionID’)>
However, we will get an error if nobody has voted yet when somebody tries to check for the cur-
rent results. So we have to provide an alternative for if this happens. If the total vote count for the
current question is zero, we tell the poll user that there are no current votes and ask them to be
the first person to vote.
<cfquery datasource=”fusionpoll” name=”check”>
SELECT SUM(Votes) AS AllVotes
FROM Answers
WHERE Answers.QuestionID=#URL.QuestionID#
</cfquery>
<cfif check.AllVotes is “0”>
<br>
<div align=”center”>There are currently no votes for this poll. Vote now to be the first.</div>
Otherwise we query the database and display the current results for the poll. This is done in the
same fashion as we did earlier in the vote.cfm page.
The final way for somebody to access the results.cfm page without using the form is when they
are looking for previous poll results (this is the other link I mentioned previously). We now display
the previous poll droplist which is dynamically populated by querying the database.
What we must do is query the ‘Questions’ table to look for the current poll. We then set the cur-
rent poll ‘QuestionID’ as ‘Current’. Next we query the ‘Questions’ table again looking for any ‘Ques-
tionID’ not equal to the current question and display them in a descending order. There is no need
We then dynamically populate the droplist with the questions.
<form action=”pastresults.cfm” method=”post”>
<cfquery datasource=”fusionpoll” name=”CurrentID” MAXROWS=”1”>
SELECT Questions.QuestionID
FROM Questions
ORDER BY QuestionID DESC
</cfquery>
<cfset Current=CurrentID.QuestionID>
<cfquery datasource=”fusionpoll” name=”PastPolls”>
SELECT Question, QuestionID
FROM Questions
WHERE QuestionID <> #Current#
ORDER by QuestionID DESC
</cfquery>
<select name=”QuestionID”>
<cfoutput query=”PastPolls”>
<option value=”#QuestionID#”>#Question#</option>
</cfoutput>
</select>
<input type=”submit” name=”Submit” value=”Show me”>
</form>
The form values are sent to pastresults.cfm, which like results.cfm, is its own page and not used
in the header or footer. This page then displays the results of the requested past poll in the same
way that results.cfm displayed the current poll results.
That then completes the user/voting side of the poll system.
Now we have to create the administration side of the poll system. I have used the same header
and footer system I used in my previous pages, but you do not have to for these pages to all
work. It’s just how I like to do things :)
The pages you need to create are:
polladd.cfm
polladdaction.cfm
polldeleteconfirm.cfm
polls.cfm
pollupdate.cfm
pollupdateaction.cfm
polls.cfm
The first page I would create is polls.cfm as it is the administration page that gives you access to
the pages that add, edit and delete polls. The first link you see on the page is a simple link to the
‘Add a poll’ page (polladd.cfm). The links to edit and delete polls however require some simple
ColdFusion. First we must query the database to get the ‘Question’ and ‘QuestionID’ details.
<cfquery name=”GetPolls” datasource=”fusionpoll”>
SELECT Questions.QuestionID, Questions.Question
FROM Questions
ORDER by QuestionID DESC
</cfquery>
We can then display the poll questions and offer links to the edit and delete pages where the
‘QuestionID’ is carried onto those pages.
polladd.cfm and polladdaction.cfm
The first administering page we will look at is the polladd.cfm page. This is a simple HTML page
where the question gets passed through to the polladdaction.cfm page through the formfield
‘Question’ and the answers all get passed through as the formfield ‘Answer’. It is important that
you inform whoever is creating these polls on your website that each answer is to be provided by
some predetermined dilimiter. For this tutorial, I will use the colon (:) as my dilimiter.
For example, if the poll question was Where did I find this Hip Poll System., then when creating
the answers, they would be typed out as TwoHipDudes:webWICKED:I don’t know:What poll!.!.
The tricky part of the polladdaction.cfm page is the looping of the ‘Answer’ field to make sure that
each provided answer gets added to the ‘Answers’ table with the matching ‘QuestionID’.
<cfquery name=”getLastID” datasource=”fusionpoll”>
SELECT MAX(QuestionID) as LastID
</cfquery>
<cfloop list=”#form.Answer#” index=”FormAnswer” delimiters=”:”>
<cfquery name=”InsertAnswers” datasource=”fusionpoll”>
INSERT INTO Answers(QuestionID, Answer)
VALUES(’#getLastID.LastID#’,’#FormAnswer#’)
</cfquery>
</cfloop>
The first query above shows how we get the most recent ‘QuestionID’ and then insert it with our
loop of provided answers. The second query shows how we set ‘Form.Answer’ in the loop to add
each new existence of the formfield to a new row in the ‘Answers’ table. Because each answer was
seperated by the colon (:) in the formfield in the polladd.cfm page, the polladdaction.cfm page
loops until all answers have been added to the database. This is because we have set the delimit-
ers in the cfloop code.
polldeleteconfirm.cfm and polldeleteaction.cfm
The polldeleteconfirm.cfm page simply provides the option to delete the selected question from
the database. The ‘QuestionID’ is passed on from the polls.cfm page. If you click the ‘Delete’ but-
ton then the poll is deleted by the processing page – polldeleteaction.cfm.
The poll is removed by polldeleteaction.cfm by deleting the question and corresponding answers
from both the ‘Questions’ and ‘Answers’ tables.
<cfquery name=”DeleteQuestion” datasource=”fusionpoll”>
DELETE
FROM Questions
WHERE QuestionID = #Form.QuestionID#
</cfquery>
<cfquery name=”DeleteAnswer” datasource=”fusionpoll”>
FROM Answers
WHERE QuestionID = #Form.QuestionID#
</cfquery>
pollupdate.cfm and pollupdateaction.cfm
The last function of the administration system is the editing feature. This is the trickiest part of the
administration process. Calling the answers from the ‘Answers’ table and then editing them re-
quires they be edited separately as they are in the same formfield name, but with separate values.
<cfoutput query=”GetAnswerDetails”>
<form method=”post” action=”pollupdateaction.cfm”>
<table width=”100%” border=”0” cellspacing=”0” cellpadding=”2”>
<tr>
<td width=”25%”><p><strong>Answer:</strong></p></td>
<td width=”75%”>
<input type=”text” name=”Answer” size=”40” maxlength=”50”
Value=”#GetAnswerDetails.Answer#”> <input type=”submit” name=”SubmitButton” value=”Make
the changes”>
<input type=”Hidden” name=”AnswerID” Value=”#GetAnswerDetails.AnswerID#”>
</td>
</tr>
</table>
</form>
</cfoutput>
For each answer in the corresponding poll there will be a form element created with its own sub-
mit button. So to edit an answer, you make your changes and press the corresponding ‘Make the
changes’ button. The changes are then updated when the form is sent to pollupdateaction.cfm.
Well, that’s it. Hopefully the tutorial makes sense and you are now able to add a poll to your web-
site. Make sure you check out the included working poll system that came with this tutorial and
see the poll working for a better idea of how everything works. The file you downloaded contains
everything you need to add the poll to your own site. You could use the database, edit the head-
ers and footers and have a fully operational poll onsite before you know what to do with it :)
This tutorial has been offered for free. I would however appreciate an email letting me know if u used in your project .
DOWNLOAD CFPOLL SOURCECODE
Have you ever wanted to have your own website poll in ColdFusion. If so, then hopefully the tuto-
rial below will allow you to finally add one. Or perhaps it will provide you with the incentive to
improve this one.
Some important poll features:
- Writes a cookie once the poll has been used so that the voter may not vote in the current poll
again.
(and is once again useable).
- Checks to see if a person tries to use their browser’s back button to make multiple votes and
informs them this is not allowed.
- Checks to see if the user made a selection when voting and informs them if they haven’t made
a selection.
- Checks to see if a user accessed the results page without hitting the ‘Vote’ button and then dis-
plays the current votes without adding a vote to the poll.
- Allows for users to view previous polls and results.
- Displays the results for all polls using a graphical bar as well as the numerical vote count (indi-
vidual and total) and vote results as percentages.
I also created an administration side to this system so the website owner can add, edit or remove
polls online. You will find more information on this towards the end of this tutorial. Of course, you
should only upload these pages to a secure area of your website so random people don’t edit your
polls ;)
This poll system has been created so that the poll question/answers or results are displayed in a
webpage’s header or footer using ColdFusion’s ‘cfinclude template’ code.
<CFAPPLICATION NAME=”Cookies”
SessionManagement=”Yes”
setDomainCookies=”Yes”
setClientCookies=”Yes”>
vote.cfm
From here on in, it gets harder. But hopefully it’ll all make sense once you get into it. The next
<cfif IsDefined(”cookie.poll”)>
<cfif “#Cookie.Poll#” is “#CurrentID.QuestionID#”>
Display the poll results
<cfelse>
Show the poll form with ‘Vote’ button
</cfif>
<cfelse>
Cookie does not exist. Show the poll form with ‘Vote’ button
</cfif>
What we check for first, is if the cookie for the poll already exists.
<cfif IsDefined(”cookie.poll”)>
Next, we check to see if the existing cookie is current. We do this by checking to see if the cookie’s
value is the same as the last (most recent) ‘QuestionID’ in the ‘Questions’ table of our database.
We do this by returning one row of ‘QuestionID’ in descending order.
<cfquery datasource=”fusionpoll” name=”CurrentID” MAXROWS=”1”>
SELECT Questions.QuestionID
FROM Questions
ORDER BY QuestionID DESC
</cfquery>
<cfif “#Cookie.Poll#” is “#CurrentID.QuestionID#”>
If the cookie is current, then the user has already voted and we display the current poll results. To
do this, we need to query the database for the current question, answers and votes.
<cfquery datasource=”fusionpoll” name=”Totals”>
SELECT Questions.Question, SUM(Answers.Votes) AS TotalVotes
FROM Questions INNER JOIN Answers
ON Questions.QuestionID=Answers.QuestionID
WHERE Questions.QuestionID=#Cookie.Poll#
GROUP BY Questions.Question
<!--- Query the answers and the number of votes for each one. --->
<cfquery datasource=”fusionpoll” name=”Results”>
SELECT Answers.Answer, Answers.Votes
FROM Answers
WHERE Answers.QuestionID=#Cookie.Poll#
ORDER BY Answers.AnswerID
</cfquery>
Once we have done this, we display the results using cfoutput. Below is the code I used to display
the results.
<table width=”175” border=”0” align=”center” cellpadding=”2” cellspacing=”0”>
<!--- Display the question --->
<cfoutput query=”Totals”>
<tr>
<td><div align=”center”><strong>#Question#</strong></div></td>
</tr>
</cfoutput>
<!--- Display the answers and their number of votes. --->
<cfoutput query=”Results”>
<!--- Set the percent of total votes for each answer. --->
<cfset Percent=Round((Votes / Totals.TotalVotes) * 100)>
<tr>
<td><div align=”left”>#Answer#</div></td>
</tr>
<tr>
<!--- Display the percentage of votes in a graph format. --->
<td><div align=”left”><img align=”middle” src=”images/poll-graph.gif” width=”#Percent#%”
height=”5”></div></td>
</tr>
<tr>
<td><div align=”right”><em>#Votes# votes - #Percent#%</em></div></td>
</tr>
</cfoutput>
<!--- Display the total number of votes --->
<cfoutput query=”Totals”>
<tr>
<td><div align=”right”><strong>Total:</strong><em><strong>
</strong>#Int(TotalVotes)# votes</em></div></td>
</tr>
</cfoutput>
</table>
The way you display the code is entirely up to you of course, but there are some things to take
notice of in the code above. For example:
<cfset Percent=Round((Votes / Totals.TotalVotes) * 100)>
This code sets ‘Percent’ as the percentage an individual vote has received by dividing the
‘Answers.Votes’ by the total number of votes(as defined in the previous ‘Totals’ query) and multi-
plying that number by 100. This is then used to set the width of the graphical display for the poll.
width=”#Percent#%”
In the image attributes, we have set the width of the image as the same percentage we calculated
previously. The last important note in the above code is that #Int(TotalVotes)# votes displays the
total number of votes for the current poll.
Continuing on with the vote.cfm page, the next step covers what to do if the cookie is not current.
If the cookie is not current, then the user has not yet voted in this poll and therefore needs to
view the question and answer choices with the ‘Vote’ button so they can vote. To make this possi-
database. We discover what the latest question is in the same way we did when checking to see if
the cookie was current.
<cfquery datasource=”fusionpoll” name=”Current” MAXROWS = “1”>
SELECT Questions.QuestionID
FROM Questions
ORDER BY Questions.QuestionID DESC
</cfquery>
<cfset display = #Current.QuestionID#>
<cfquery datasource=”fusionpoll” name=”Question”>
SELECT Questions.QuestionID, Questions.Question, Answers.AnswerID, Answers.Answer
FROM Questions INNER JOIN Answers
ON Questions.QuestionID = Answers.QuestionID
WHERE Questions.QuestionID = #display#
ORDER BY Answers.AnswerID
</cfquery>
The first query (’Current’) selects the latest question from the ‘Questions’ table thanks to our hav-
ing the MAXROWS set at “1” and by querying in descending order. Then we set ‘display’ as the
current question so we can select the corresponding answers from the ‘Answers’ table. All that is
required then is to display the form using the selected query output.
<form action=”results.cfm” method=”post” name=”Poll”>
<table border=”0” align=”center” cellpadding=”4” cellspacing=”0”>
<cfoutput query=”Question” group=”QuestionID”>
<!--- Pass the question id as a hidden variable. --->
<input type=”hidden” name=”QuestionID” value=”#QuestionID#”>
<tr>
<td colspan=”2”><div align=”center”><strong>#Question#</strong></div></td>
</tr>
<!--- Display the answers and their checkboxes --->
<cfoutput>
<td width=”10”><input type=”radio” name=”AnswerID” value=”#AnswerID#”></td>
<td><div align=”left”>#Answer#</div></td>
</tr>
</cfoutput>
</cfoutput>
<tr>
<td colspan=”2” align=”center”><input name=”Submit” type=”submit” value=”Vote”></td>
</tr>
<tr>
<td colspan=”2” align=”center”><div align=”center”>[<a
href=”results.cfm.QuestionID=<cfoutput>#display#</cfoutput>”>View
Poll Results</a>]
<br>
[<a href=”results.cfm”>Previous Poll Results</a>]</div></td>
</tr>
</table>
</form>
You should notice two links to results.cfm after the ‘Vote’ button in the code above. These will be
explained a little bit later.
Next, we have to check if none of the previous rules applied. What to do if the cookie did not ex-ist at all. If this is the case, then we simply use the same code as above to show the current poll
question and multiple choice answers with the ‘Vote’ button. If a cookie does not exist, the person
has not yet voted at all.
results.cfm
The next page is the results.cfm page which is where our vote.cfm page sent the form details
to. Unlike vote.cfm however, results.cfm is not placed in the header or footer of the website. The
results.cfm pageincludes the footer file (which then includes the vote.cfm page).
Shown below is a basic rundown of the layout of this page.
<cfif isDefined(’Form.QuestionID’)>
<cfif IsDefined(”cookie.poll”)>
<cfif “#Cookie.Poll#” is “#CurrentID.QuestionID#”>
Show warning for attempted multiple votes
<cfelse>
Nothing
</cfif>
</cfif>
Set Cookie, add vote to database and display the answer selected by the vote
<cfelse>
Show warning for no answer selected
</cfif>
<cfelse>
<cfif isdefined (’URL.QuestionID’)>
<cfif check.AllVotes is “0”>
Show warning for no votes in current poll
<cfelse>
Display poll results
</cfif>
<cfelse>
Show the droplist for the previous polls
</cfif>
</cfif>
The first check we must perform is to see if the page was reached by somebody using the form.
We do this by checking for ‘QuestionID’ from the votes.cfm page.
<cfif isDefined(’Form.QuestionID’)>
8
And next we check to see if the poll user made a selection when they hit the ‘Vote’ button. And we
do this by checking for ‘AnswerID’ from the votes.cfm page.
<cfif isDefined(’Form.AnswerID’)>
And the next check is to stop people from voting more than once by using their browser’s back
button. We check for the existence of a cookie.
<cfif IsDefined(”cookie.poll”)>
vote.cfm page. If it is current, we display a message telling the user they can not vote more than
once.
<cfquery datasource=”fusionpoll” name=”CurrentID” MAXROWS=”1”>
SELECT Questions.QuestionID
FROM Questions
ORDER BY QuestionID DESC
</cfquery>
<cfif “#Cookie.Poll#” is “#CurrentID.QuestionID#”>
<br>
<div align=”center”>Sorry, you can only vote once.</div>
<cfinclude template=”foot.cfm”>
<cfabort>
It is important to have the ‘cfabort’ code in this part of the webpage or else you will end up with
two footers in your page display. Once we have performed those checks, we know the cookie is
not current (or existing) so we set a new cookie.
<cfcookie name=”Poll” value=”#Form.QuestionID#” expires=”never”>
The value of the cookie is set as the ‘QuestionID’ value so that we can later tell if a cookie is
current when we add a new poll question. The cookie’s expiration is set to “never” because we
will simply update it whenever we add a new poll to our website. If you set your cookie to expire
before you set a new poll, people will be able to vote again.
Once the cookie is set and the vote has been made, we must update the ‘Answers’ table with the
new vote count. We select the current vote count from the ‘Answers’ table for the current ques-
tion and chosen answer (from vote.cfm) and then set ‘NewVotes’ as the current vote plus one new
vote. Then we update the votes where the ‘QuestionID’ and ‘AnswerID’ are the same as the ones
passed through from our vote.cfm page.
<cftransaction>
SELECT Votes
FROM Answers
WHERE QuestionID=#QuestionID# AND AnswerID=#AnswerID#
</cfquery>
<cfset NewVotes=LastVote.Votes + 1>
<cfquery datasource=”fusionpoll” name=”NewVote”>
UPDATE Answers
SET Votes=#NewVotes#
WHERE QuestionID=#QuestionID# AND AnswerID=#AnswerID#
</cfquery>
</cftransaction>
Next, we create queries so we can display the new vote count for all answers in the current poll.
Once this is done, you simply display the ‘QuestionID’ and ‘AnswerID’ to show the user how they
voted in the poll.
<cfquery datasource=”fusionpoll” name=”showanswer”>
SELECT Answers.Answer, Answers.AnswerID
FROM Answers
WHERE Answers.AnswerID = #AnswerID#
</cfquery>
<cfquery datasource=”fusionpoll” name=”showquestion”>
SELECT Questions.QuestionID, Questions.Question
FROM Questions
WHERE Questions.QuestionID = #QuestionID#
</cfquery>
However, if the user had hit the ‘Vote’ button without making a selection from the radio button list,
we would need to tell them of their mistake and not update the database with any votes.
<cfelse>
<!--- No radio button selected, so tell the user to try again --->
<br>
<div align=”center”>Sorry, you didn’t select anything. Please select an answer before hitting the
Next, we check to see if the page was accessed without somebody using the poll form. For exam-
ple, an option I’ve added to the poll is for a user to view the current poll votes before they vote for
themselves (this is one of the links I mentioned earlier that appears under the ‘Vote’ button of the
poll). So we must check to see if that is what they are doing.
<cfif isdefined (’URL.QuestionID’)>
However, we will get an error if nobody has voted yet when somebody tries to check for the cur-
rent results. So we have to provide an alternative for if this happens. If the total vote count for the
current question is zero, we tell the poll user that there are no current votes and ask them to be
the first person to vote.
<cfquery datasource=”fusionpoll” name=”check”>
SELECT SUM(Votes) AS AllVotes
FROM Answers
WHERE Answers.QuestionID=#URL.QuestionID#
</cfquery>
<cfif check.AllVotes is “0”>
<br>
<div align=”center”>There are currently no votes for this poll. Vote now to be the first.</div>
Otherwise we query the database and display the current results for the poll. This is done in the
same fashion as we did earlier in the vote.cfm page.
The final way for somebody to access the results.cfm page without using the form is when they
are looking for previous poll results (this is the other link I mentioned previously). We now display
the previous poll droplist which is dynamically populated by querying the database.
What we must do is query the ‘Questions’ table to look for the current poll. We then set the cur-
rent poll ‘QuestionID’ as ‘Current’. Next we query the ‘Questions’ table again looking for any ‘Ques-
tionID’ not equal to the current question and display them in a descending order. There is no need
We then dynamically populate the droplist with the questions.
<form action=”pastresults.cfm” method=”post”>
<cfquery datasource=”fusionpoll” name=”CurrentID” MAXROWS=”1”>
SELECT Questions.QuestionID
FROM Questions
ORDER BY QuestionID DESC
</cfquery>
<cfset Current=CurrentID.QuestionID>
<cfquery datasource=”fusionpoll” name=”PastPolls”>
SELECT Question, QuestionID
FROM Questions
WHERE QuestionID <> #Current#
ORDER by QuestionID DESC
</cfquery>
<select name=”QuestionID”>
<cfoutput query=”PastPolls”>
<option value=”#QuestionID#”>#Question#</option>
</cfoutput>
</select>
<input type=”submit” name=”Submit” value=”Show me”>
</form>
The form values are sent to pastresults.cfm, which like results.cfm, is its own page and not used
in the header or footer. This page then displays the results of the requested past poll in the same
way that results.cfm displayed the current poll results.
That then completes the user/voting side of the poll system.
Now we have to create the administration side of the poll system. I have used the same header
and footer system I used in my previous pages, but you do not have to for these pages to all
work. It’s just how I like to do things :)
The pages you need to create are:
polladd.cfm
polladdaction.cfm
polldeleteconfirm.cfm
polls.cfm
pollupdate.cfm
pollupdateaction.cfm
polls.cfm
The first page I would create is polls.cfm as it is the administration page that gives you access to
the pages that add, edit and delete polls. The first link you see on the page is a simple link to the
‘Add a poll’ page (polladd.cfm). The links to edit and delete polls however require some simple
ColdFusion. First we must query the database to get the ‘Question’ and ‘QuestionID’ details.
<cfquery name=”GetPolls” datasource=”fusionpoll”>
SELECT Questions.QuestionID, Questions.Question
FROM Questions
ORDER by QuestionID DESC
</cfquery>
We can then display the poll questions and offer links to the edit and delete pages where the
‘QuestionID’ is carried onto those pages.
polladd.cfm and polladdaction.cfm
The first administering page we will look at is the polladd.cfm page. This is a simple HTML page
where the question gets passed through to the polladdaction.cfm page through the formfield
‘Question’ and the answers all get passed through as the formfield ‘Answer’. It is important that
you inform whoever is creating these polls on your website that each answer is to be provided by
some predetermined dilimiter. For this tutorial, I will use the colon (:) as my dilimiter.
For example, if the poll question was Where did I find this Hip Poll System., then when creating
the answers, they would be typed out as TwoHipDudes:webWICKED:I don’t know:What poll!.!.
The tricky part of the polladdaction.cfm page is the looping of the ‘Answer’ field to make sure that
each provided answer gets added to the ‘Answers’ table with the matching ‘QuestionID’.
<cfquery name=”getLastID” datasource=”fusionpoll”>
SELECT MAX(QuestionID) as LastID
</cfquery>
<cfloop list=”#form.Answer#” index=”FormAnswer” delimiters=”:”>
<cfquery name=”InsertAnswers” datasource=”fusionpoll”>
INSERT INTO Answers(QuestionID, Answer)
VALUES(’#getLastID.LastID#’,’#FormAnswer#’)
</cfquery>
</cfloop>
The first query above shows how we get the most recent ‘QuestionID’ and then insert it with our
loop of provided answers. The second query shows how we set ‘Form.Answer’ in the loop to add
each new existence of the formfield to a new row in the ‘Answers’ table. Because each answer was
seperated by the colon (:) in the formfield in the polladd.cfm page, the polladdaction.cfm page
loops until all answers have been added to the database. This is because we have set the delimit-
ers in the cfloop code.
polldeleteconfirm.cfm and polldeleteaction.cfm
The polldeleteconfirm.cfm page simply provides the option to delete the selected question from
the database. The ‘QuestionID’ is passed on from the polls.cfm page. If you click the ‘Delete’ but-
ton then the poll is deleted by the processing page – polldeleteaction.cfm.
The poll is removed by polldeleteaction.cfm by deleting the question and corresponding answers
from both the ‘Questions’ and ‘Answers’ tables.
<cfquery name=”DeleteQuestion” datasource=”fusionpoll”>
DELETE
FROM Questions
WHERE QuestionID = #Form.QuestionID#
</cfquery>
<cfquery name=”DeleteAnswer” datasource=”fusionpoll”>
FROM Answers
WHERE QuestionID = #Form.QuestionID#
</cfquery>
pollupdate.cfm and pollupdateaction.cfm
The last function of the administration system is the editing feature. This is the trickiest part of the
administration process. Calling the answers from the ‘Answers’ table and then editing them re-
quires they be edited separately as they are in the same formfield name, but with separate values.
<cfoutput query=”GetAnswerDetails”>
<form method=”post” action=”pollupdateaction.cfm”>
<table width=”100%” border=”0” cellspacing=”0” cellpadding=”2”>
<tr>
<td width=”25%”><p><strong>Answer:</strong></p></td>
<td width=”75%”>
<input type=”text” name=”Answer” size=”40” maxlength=”50”
Value=”#GetAnswerDetails.Answer#”> <input type=”submit” name=”SubmitButton” value=”Make
the changes”>
<input type=”Hidden” name=”AnswerID” Value=”#GetAnswerDetails.AnswerID#”>
</td>
</tr>
</table>
</form>
</cfoutput>
For each answer in the corresponding poll there will be a form element created with its own sub-
mit button. So to edit an answer, you make your changes and press the corresponding ‘Make the
changes’ button. The changes are then updated when the form is sent to pollupdateaction.cfm.
Well, that’s it. Hopefully the tutorial makes sense and you are now able to add a poll to your web-
site. Make sure you check out the included working poll system that came with this tutorial and
see the poll working for a better idea of how everything works. The file you downloaded contains
everything you need to add the poll to your own site. You could use the database, edit the head-
ers and footers and have a fully operational poll onsite before you know what to do with it :)
This tutorial has been offered for free. I would however appreciate an email letting me know if u used in your project .
DOWNLOAD CFPOLL SOURCECODE
Subscribe to:
Posts (Atom)