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

No comments: