/*
* Name:
* content_rater.js
*
* Description:
* Defines functions for making AJAX queries via the HTTP protocol's GET method.
*
* Pre-conditions:
* 'q' : Content Rating
* 'contentId' : contentId
* 'contentTypeId : contentTypeId
*
* Post-conditions:
* - Calls the upd_content_rater.php which updates/inserts
* content rating and displays RatingAvg
* - Updates the hit counts, miss counts, and calculated ratings of all instances of a piece of content onscreen.
*
* Log:
* Kripa Shenai 08/15/2006
* - Creation
* Randall Betta 11/13/2006
* - Rewritten to update raw hit counts and raw miss counts.
* - Altered to update all instances of the content's rating values onscreen automagically.
* Randall Betta 12/01/2006
* - Renamed most functions and all global variables to avoid namespace collisions with secret_word.js.
*
*/
var contentRatingXmlHttp;
function rate_content(rating, contentTypeId, contentId) {
var url;
// Cast rating as a string.
rating = '' + rating;
// Ensure the rating string is a valid integer representation.
if (rating.match(/([-])?[0-9]+/)) {
url = "/upd_content_rater.php";
url += "?q=" + rating;
url += "&contentTypeId=" + contentTypeId;
url += "&contentId=" + contentId;
url += "&sid=" + Math.random();
contentRatingXmlHttp = getContentRatingXmlHttpObject(function () { contentRatingStateChanged(contentTypeId, contentId); })
contentRatingXmlHttp.open("GET", url , true)
contentRatingXmlHttp.send(null)
} // End if: rating is a valid integer.
} // End function: rate_content.
function contentRatingStateChanged(contentTypeId, contentId) {
var responseText;
var propObj;
var pairsArray;
var pairIndex;
var keyValueArray;
var pairKey;
var pairValue;
var messageElts;
var eltIndex;
var messageEltId;
// Returned AJAX values.
var hits;
var misses;
var rating;
var debugMsg;
var userMsg;
var success;
if (contentRatingXmlHttp.readyState == 4 || contentRatingXmlHttp.readyState == "complete") { // If: the HTTP response is valid.
responseText = contentRatingXmlHttp.responseText;
// Initialize an object whose properties will be set via the AJAX response's key-value pairs.
propObj = new Object();
// Parse the AJAX response for key-value pairs. Keys and values are URL-encoded, in the
// form: key=value,key=value,key=value,...,key=value
pairsArray = responseText.split(',');
for (pairIndex = pairsArray.length - 1; pairIndex >= 0; pairIndex--) { // For: iterate through pairs.
keyValueArray = (pairsArray[pairIndex]).split('=');
pairKey = '' + unescape(keyValueArray[0]);
pairValue = '' + unescape(keyValueArray[1]);
propObj[pairKey] = pairValue;
} // End for: iterate through pairs.
// Store known key-value pairs as local variables.
hits = propObj['hits'];
isHit = propObj['isHit']; // Set to 1 if the content is a hit.
misses = propObj['misses'];
rating = propObj['rating'];
success = propObj['success']; // Set to 1 if rating was successful.
userMsg = propObj['userMsg']; // For display to the user.
debugMsg = propObj['debugMsg']; // For AJAX debugging.
if ('1' == ('' + success)) { // If: Rating was successful.
// Update the front-end displays of this content's rating.
updateHitOrMissDisplays(contentTypeId, contentId, hits, misses, rating, isHit, userMsg);
} else { // Else: the content could not be rated.
// Display any necessary message.
if (userMsg) { // If: a message is defined.
displayRatingMessages(contentTypeId, contentId, userMsg);
} // End if: a message is defined.
} // Else: the content could not be rated.
} // End if: the HTTP response is valid.
} // End function: contentRatingStateChanged.
/*
function rate_content(str1,str2,str3,str4)
{
var str = str1;
if (str1.length==0)
{
var obj = document.getElementById(str4);
if (obj) obj.innerHTML = '';
}
else {
var url="/upd_content_rater.php";
url=url+"?q="+str1;
url=url+"&contentTypeId="+str2;
url=url+"&contentId="+str3;
url=url+"&sid="+Math.random();
var txtLink = "txtLink"+str4;
contentRatingXmlHttp=getContentRatingXmlHttpObject(function () { contentRatingStateChanged(txtLink); })
contentRatingXmlHttp.open("GET", url , true)
contentRatingXmlHttp.send(null)
}
}
*/
/*
function contentRatingStateChanged(txtLink)
{
if (contentRatingXmlHttp.readyState==4 || contentRatingXmlHttp.readyState=="complete")
{
var obj = document.getElementById(txtLink);
if (obj) obj.innerHTML = contentRatingXmlHttp.responseText;
document.getElementById(txtLink).innerHTML = contentRatingXmlHttp.responseText
}
}
*/
function getContentRatingXmlHttpObject(handler)
{
var objXmlHttp = null;
if (navigator.userAgent.indexOf("Opera")>=0)
{
alert("This doesn't work in Opera")
return
}
if (navigator.userAgent.indexOf("MSIE")>=0)
{
var strName="Msxml2.XMLHTTP"
if (navigator.appVersion.indexOf("MSIE 5.5")>=0)
{
strName="Microsoft.XMLHTTP"
}
try
{
objXmlHttp=new ActiveXObject(strName)
objXmlHttp.onreadystatechange=handler
return objXmlHttp
}
catch(e)
{
alert("Error: Scripting for ActiveX might be disabled")
return
}
}
if (navigator.userAgent.indexOf("Mozilla")>=0)
{
objXmlHttp=new XMLHttpRequest()
objXmlHttp.onload=handler
objXmlHttp.onerror=handler
return objXmlHttp
}
}
/*
* Name:
* updateContentRatingDisplays
*
* Description:
* Given the contentTypeId and contentId of some content, and its hit and miss count, update any
* onscreen
elements containing that content's hit-or-miss status to reflect the new numbers.
*
* Pre-conditions:
* The following arguments are expected:
* contentTypeId REQUIRED The numeric content type of the content.
* contentId REQUIRED The Id of the content.
* hits REQUIRED The number of positive ratings earned.
* misses REQUIRED The number of negative ratings earned.
* rating REQUIRED The overall derived (i.e. calculated) rating earned.
* isHit REQUIRED True if the content is a hit, false if it is a miss.
* message REQUIRED A message to display to the user. Can be empty.
* Additionally, the HTML id properties of the
tags holding the ratings must be as follows:
* The id must consist of a set of key-value pairs, with each key separated from its value
* by a colon (":"). The pairs are separated from each other by a hyphen ("-"). The pairs
* should be as follows:
* 1: rating:hitOrMiss
* 2: type:hit or type:miss or type:rating or type:message
* 3: contentTypeId:43 (value for example only)
* 4: contentId:23862 (value for example only)
* 5: hash:1 (value for example only)
* The "hash" key is an alphanumeric suffix to allow for uniqueness, since HTML does not
* allow identical ID properties on different elements in the same document.
* Example HTML snippet for content with 34 misses:
* Misses:
34
*
* Post-conditions:
* Updates any onscreen displays of the given content's numeric hit-or-miss status.
*
* Libraries:
* html_element_search.js
*
* Log:
* Randall Betta 11/07/2006
* - Creation
*
*/
function updateHitOrMissDisplays(contentTypeId, contentId, hits, misses, rating, isHit, message) {
// HTML elements with nodeValues of numeric hit or miss counts, or rating totals.
var hitElts;
var missElts;
var ratingElts;
var hitGraphicElts;
var missGraphicElts;
// Regexes that describe the IDs of HTML elements to change.
var hitEltRegex = 'rating\:hitOrMiss\-type\:hit\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
var hitGraphicRegex = 'rating\:hitOrMiss\-type\:hitGraphic\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
var missEltRegex = 'rating\:hitOrMiss\-type\:miss\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
var missGraphicRegex = 'rating\:hitOrMiss\-type\:missGraphic\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
var ratingEltRegex = 'rating\:hitOrMiss\-type\:rating\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
// Counters and temporary variables.
var eltIndex;
var elt;
// Obtain separate arrays of all
elements containing hit, miss,
// and rating numbers, as well as messages to be displayed.
hitElts = getRelatedElements('div', hitEltRegex, true, true);
missElts = getRelatedElements('div', missEltRegex, true, true);
ratingElts = getRelatedElements('div', ratingEltRegex, true, true);
hitGraphicElts = getRelatedElements('div', hitGraphicRegex, true, true);
missGraphicElts = getRelatedElements('div', missGraphicRegex, true, true);
// Update the numeric hit displays.
for (eltIndex = hitElts.length - 1; eltIndex >= 0; eltIndex--) { // For: HTML hit elements.
// Store current hit element.
elt = hitElts[eltIndex];
// Update its contents.
try {
if (elt.firstChild) {
elt.firstChild.nodeValue = hits;
}
else {
elt.appendChild(document.createTextNode(hits));
}
}
catch (exc) { ; } // Silently fail on a JavaScript permissions error.
} // End for: iteration through HTML hit elements.
// Update the numeric miss displays.
for (eltIndex = missElts.length - 1; eltIndex >= 0; eltIndex--) { // For: HTML miss elements.
// Store current miss element.
elt = missElts[eltIndex];
// Update its contents.
try {
if (elt.firstChild) {
elt.firstChild.nodeValue = misses;
}
else {
elt.appendChild(document.createTextNode(misses));
}
}
catch (exc) { ; } // Silently fail on a JavaScript permissions error.
} // End for: iteration through HTML miss elements.
// Update the numeric rating displays.
for (eltIndex = ratingElts.length - 1; eltIndex >= 0; eltIndex--) { // For: HTML rating elements.
// Store current rating element.
elt = ratingElts[eltIndex];
// Update its contents.
try {
if (elt.firstChild) {
elt.firstChild.nodeValue = rating;
}
else {
elt.appendChild(document.createTextNode(rating));
}
}
catch (exc) { ; } // Silently fail on a JavaScript permissions error.
} // End for: iteration through HTML miss elements.
// Update the graphical hit displays.
for (eltIndex = hitGraphicElts.length - 1; eltIndex >= 0; eltIndex--) { // For: hit graphic elements.
// Store current hit graphic element.
elt = hitGraphicElts[eltIndex];
// Update its visibility.
try {
elt.style.display = (isHit == 1) ? 'block' : 'none';
}
catch (exc) { ; } // Silently fail on a JavaScript permissions error.
} // End for: iteration through hit graphic elements.
// Update the graphical miss displays.
for (eltIndex = missGraphicElts.length - 1; eltIndex >= 0; eltIndex--) { // For: miss graphic elements.
// Store current miss graphic element.
elt = missGraphicElts[eltIndex];
// Update its visibility.
try {
elt.style.display = (isHit != 1) ? 'block' : 'none';
}
catch (exc) { ; } // Silently fail on a JavaScript permissions error.
} // End for: iteration through miss graphic elements.
// Update the message displays.
message = (message) ? message : '';
displayRatingMessages (contentTypeId, contentId, message);
return;
} // End function: updateHitOrMissDisplays
/*
* Name:
* displayRatingMessages
*
* Description:
* Displays a message to the user regarding rating a given piece of content.
*
* Pre-conditions:
* The following arguments are expected:
* contentTypeId REQUIRED The numeric content type of the content.
* contentId REQUIRED The Id of the content.
* message REQUIRED A message to display to the user. Can be empty.
*
* Post-conditions:
* Updates any onscreen displays of the given content's rating messages.
*
* Libraries:
* html_element_search.js
*
* Log:
* Randall Betta 11/14/2006
* - Creation
*
*/
function displayRatingMessages(contentTypeId, contentId, message) {
// HTML elements with text nodes to store the message.
var messageElts;
var messageEltId;
// Regexes that describe the IDs of HTML elements to change.
var messageEltRegex = 'rating\:hitOrMiss\-type\:message\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
// Counters and temporary variables.
var eltIndex;
var elt;
// Obtain separate arrays of all
elements containing messages to be displayed.
messageElts = getRelatedElements('div', messageEltRegex, true, true);
// Update the message displays.
message = (message) ? message : '';
for (eltIndex = messageElts.length - 1; eltIndex >= 0; eltIndex--) { // For: HTML message elements.
// Store current rating element.
elt = messageElts[eltIndex];
// Update its contents.
try {
if (elt.firstChild) {
elt.firstChild.nodeValue = message;
}
else {
elt.appendChild(document.createTextNode(message));
}
messageEltId = elt.id;
document.getElementById(messageEltId).style.display = 'block';
window.setTimeout("document.getElementById('" + messageEltId + "').style.display = 'none';", 3000);
}
catch (exc) { ; } // Silently fail on a JavaScript permissions error.
} // End for: iteration through HTML message elements.
return messageElts;
} // End function: displayRatingMessages