Created
March 25, 2014 10:46
-
-
Save bennadel/9759096 to your computer and use it in GitHub Desktop.
Ask Ben: Building A jQuery And ColdFusion Rating System
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- Create a unified API resposne. ---> | |
<cfset apiResponse = { | |
success = true, | |
errors = [], | |
data = "" | |
} /> | |
<!--- Try to execute the api request / response. ---> | |
<cftry> | |
<!--- Param the FORM variable. ---> | |
<cfparam name="form.image_id" type="numeric" /> | |
<cfparam name="form.rating" type="numeric" /> | |
<!--- | |
Check to see if this user has already rated this image. | |
We do not want to allow duplicate ratings. | |
---> | |
<cfquery name="existingRating" datasource="#application.dsn#"> | |
SELECT | |
r.id | |
FROM | |
rating r | |
WHERE | |
r.image_id = <cfqueryparam value="#form.image_id#" cfsqltype="cf_sql_integer" /> | |
AND | |
r.ip_address = <cfqueryparam value="#cgi.remote_addr#" cfsqltype="cf_sql_varchar" /> | |
AND | |
r.user_agent = <cfqueryparam value="#cgi.http_user_agent#" cfsqltype="cf_sql_varchar" /> | |
</cfquery> | |
<!--- Check to see if the rating exists. ---> | |
<cfif existingRating.recordCount> | |
<!--- Add error. ---> | |
<cfset arrayAppend( | |
apiResponse.errors, | |
"You have already rated this image." | |
) /> | |
</cfif> | |
<!--- Check to see if we have any errors. ---> | |
<cfif NOT arrayLen( apiResponse.errors )> | |
<!--- Insert new rating. ---> | |
<cfquery name="insertRating" datasource="#application.dsn#"> | |
INSERT INTO rating | |
( | |
ip_address, | |
user_agent, | |
rating, | |
date_created, | |
image_id | |
) VALUES ( | |
<cfqueryparam value="#cgi.remote_addr#" cfsqltype="cf_sql_varchar" />, | |
<cfqueryparam value="#cgi.http_user_agent#" cfsqltype="cf_sql_varchar" />, | |
<cfqueryparam value="#form.rating#" cfsqltype="cf_sql_integer" />, | |
<cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp" />, | |
<cfqueryparam value="#form.image_id#" cfsqltype="cf_sql_integer" /> | |
); | |
<!--- Get the new overall rating. ---> | |
SELECT | |
( | |
SUM( r.rating ) / | |
COUNT( r.rating ) | |
) AS overall_rating | |
FROM | |
rating r | |
WHERE | |
r.image_id = <cfqueryparam value="#form.image_id#" cfsqltype="cf_sql_integer" /> | |
; | |
</cfquery> | |
<!--- Set the current rating as the response data. ---> | |
<cfset apiResponse.data = insertRating.overall_rating /> | |
</cfif> | |
<!--- Catch any api errors. ---> | |
<cfcatch> | |
<!--- Set the error in our api response object. ---> | |
<cfset apiResponse.errors = [ cfcatch.message, cfcatch.detail ] /> | |
</cfcatch> | |
</cftry> | |
<!--- Check to see if we have any errors at this point. ---> | |
<cfif arrayLen( apiResponse.errors )> | |
<!--- Flag the API request as unsuccessful. ---> | |
<cfset apiResponse.success = false /> | |
</cfif> | |
<!--- Searialize the API response into our JSON value. ---> | |
<cfset jsonResponse = serializeJSON( apiResponse ) /> | |
<!--- Convert the response string to binary for streaming. ---> | |
<cfset binaryResponse = toBinary( toBase64( jsonResponse ) ) /> | |
<!--- Stream the binary data back. ---> | |
<cfheader | |
name="content-length" | |
value="#arrayLen( binaryResponse )#" | |
/> | |
<cfcontent | |
type="text/x-json" | |
variable="#binaryResponse#" | |
/> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- Query for images to rate. ---> | |
<cfquery name="image" datasource="#application.dsn#"> | |
SELECT | |
i.id, | |
<!--- Get the current rating for the image. ---> | |
( | |
CASE | |
WHEN | |
COUNT( r.rating ) > 0 | |
THEN | |
( | |
SUM( r.rating ) / | |
COUNT( r.rating ) | |
) | |
ELSE | |
0 | |
END | |
) AS rating, | |
<!--- Query for existing rating by user. ---> | |
COALESCE( er.id, 0 ) AS has_existing_rating | |
FROM | |
( | |
SELECT 1 AS id UNION ALL | |
SELECT 2 AS id UNION ALL | |
SELECT 3 AS id | |
) AS i | |
<!--- Join this to the rating table to get rating. ---> | |
LEFT OUTER JOIN | |
rating r | |
ON | |
i.id = r.image_id | |
<!--- | |
Join this to the rating table AGAIN to see if the current | |
user has already rated the given image. | |
---> | |
LEFT OUTER JOIN | |
rating er | |
ON | |
( | |
er.image_id = i.id | |
AND | |
er.ip_address = <cfqueryparam value="#cgi.remote_addr#" cfsqltype="cf_sql_varchar" /> | |
AND | |
er.user_agent = <cfqueryparam value="#cgi.http_user_agent#" cfsqltype="cf_sql_varchar" /> | |
) | |
GROUP BY | |
i.id, | |
r.image_id | |
ORDER BY | |
i.id ASC | |
</cfquery> | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html> | |
<head> | |
<title>jQuery And ColdFusion Rating System Demo</title> | |
<script type="text/javascript" src="jquery-1.3.2.min.js"></script> | |
<script type="text/javascript"> | |
// Define jquery plugin. | |
jQuery.fn.rating = function( postUrl ){ | |
// Loop over each list to apply meta data. | |
this.each( | |
function( index, listNode ){ | |
var list = $( this ); | |
var metaData = list.find( "script.meta-data" ); | |
// Check to see if meta data was found. | |
if (metaData.size()){ | |
// Apply meta data. | |
list.data( | |
"metaData", | |
eval( "(" + metaData.text() + ")" ) | |
); | |
// Remove the meta data node. | |
metaData.remove(); | |
} | |
} | |
); | |
// Initialize the links within the list. | |
this.find( "a" ) | |
.attr( "href", "javascript:void( 0 )" ) | |
.click( | |
function( clickEvent ){ | |
var link = $( this ); | |
var list = link.parents( "ul:first" ); | |
var metaData = list.data( "metaData" ); | |
// Post the rating. | |
jQuery.ajax({ | |
type: "post", | |
url: postUrl, | |
data: { | |
image_id: metaData.id, | |
rating: link.text() | |
}, | |
dataType: "json", | |
success: function( apiResponse ){ | |
// Check to see if the API request | |
// was valid. | |
if (apiResponse.SUCCESS){ | |
// Replace the list with the | |
// current rating. | |
list | |
.empty() | |
.append( | |
"<li>Rating: " + | |
apiResponse.DATA.toFixed( 1 ) + | |
"</li>" | |
) | |
; | |
} | |
} | |
}); | |
// Cancel default event. | |
return( false ); | |
}) | |
; | |
// Return jQuery object for chaining. | |
return( this ); | |
}; | |
// When the DOM is ready, initialize the plugin. | |
$(function(){ | |
$( "ul" ).rating( "rate_image.cfm" ); | |
}); | |
</script> | |
<style type="text/css"> | |
ul.rating { | |
height: 20px ; | |
list-style-type: none ; | |
margin: 10px 0px 0px 0px ; | |
padding: 0px 0px 0px 0px ; | |
} | |
ul.rating li { | |
float: left ; | |
margin: 0px 5px 0px 0px ; | |
padding: 0px 0px 0px 0px ; | |
} | |
ul.rating a { | |
background-color: #F0F0F0 ; | |
border: 1px solid #333333 ; | |
color: #333333 ; | |
float: left ; | |
height: 20px ; | |
line-height: 20px ; | |
text-align: center ; | |
text-decoration: none ; | |
width: 20px ; | |
} | |
</style> | |
</head> | |
<body> | |
<h1> | |
jQuery And ColdFusion Rating System Demo | |
</h1> | |
<cfoutput> | |
<cfloop query="image"> | |
<div style="float: left ; margin-right: 20px ;"> | |
<img | |
src="./images/girl#image.id#.jpg" | |
width="165" | |
style="display: block ;" | |
/> | |
<!--- Check to see if user has rated yet. ---> | |
<cfif image.has_existing_rating> | |
<!--- | |
User has already rated, just show the | |
current rating. | |
---> | |
<ul class="rating"> | |
<li> | |
Rating: #numberFormat( | |
image.rating, | |
"0.0" | |
)# | |
</li> | |
</ul> | |
<cfelse> | |
<!--- Show the rating options. ---> | |
<ul class="rating"> | |
<!--- | |
Set up the meta-data for this image. | |
This data will be applied when the | |
rating plugin is initialized. | |
---> | |
<script | |
type="application/x-json" | |
class="meta-data"> | |
{ | |
id: #image.id# | |
} | |
</script> | |
<li> | |
<a>1</a> | |
</li> | |
<li> | |
<a>2</a> | |
</li> | |
<li> | |
<a>3</a> | |
</li> | |
<li> | |
<a>4</a> | |
</li> | |
</ul> | |
</cfif> | |
</div> | |
</cfloop> | |
</cfoutput> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfcomponent | |
output="false" | |
hint="I define the application settings and event handlers."> | |
<!--- Define the application. ---> | |
<cfset this.name = hash( getCurrentTemplatePath() ) /> | |
<cfset this.applicationTimeout = createTimeSpan( 0, 0, 5, 0 ) /> | |
<!--- Define the page request settings. ---> | |
<cfsetting showdebugoutput="false" /> | |
<cffunction | |
name="onApplicationStart" | |
access="public" | |
returntype="boolean" | |
output="false" | |
hint="I initialize the application."> | |
<!--- Define the application. ---> | |
<cfset application.dsn = "xyz" /> | |
<!--- Return out. ---> | |
<cfreturn true /> | |
</cffunction> | |
</cfcomponent> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment