// SEI_library.js //Copyright © 2002 Sponsorship Effectiveness Index LLC // Library of javaScript functions used in the // Sponsorhip Effectiveness Survey process. // 1.5 2000/01/25 Jason Venner of Responsible Solutions. Initial version. // 1.5g 2000/04/04 Gerry Despain. Made more portable to different sites. // 1.5g1 2000/06/15 Gerry Despain. Changed cookie name to force reset of cookies for YourBabyToday // 2.0 2000/07/12 Gerry Despain. Major enhancement to cookie processing. // 2.1 2000/08/25 Gerry Despain. MinSecondsConnected enhancement. // 2.2 2000/08/31 Gerry Despain. Fixed problem for when numVisits < 1 that can occur when minSecondsConnected option is used. // Added numVisitSoFar to cookie. // 2.3 2000/11/27 Gerry Despain. Deleted reference to $$ certificate incentive. // 2.4 2000/12/19 Gerry Despain. Changes for catching abusers: SurveySubmit. // 2.5 2001/01/09 Gerry Despain. Added functions for checking form fields. // 2.6 2001/02/15 Gerry Despain. Added functionality to track all visitors. // 2.7 2001/03/07 Gerry Despain. Changes to track code. // 2.8 2001/03/09 Gerry Despain. Added catchOnExit option. // 2.8a 2001/03/09 Gerry Despain. Set variables for RFRF. // 2.8b 2001/09/28 Gerry Despain. Set variables for RFRF. // 2.9c 2001/10/01 Gerry Despain. Changed text of invitation. // 2.10 2001/10/11 Gerry Despain. Enhanced checkOneField. // 2.11 2002/06/25 Gerry Despain. Enhanced checkOneField for SELECT tags. // 2.12 2002/09/17 Gerry Despain. Generalized parameters, to be customized per site. Added hyperlink_click. // 2.13 2005/05/02 Gerry Despain. Added sponsorLink(), testGetCookie(). // 2.14 2005/05/03 Gerry Despain. Added goto_page(), randomizeSite(). // 2.15 2005/05/04 Gerry Despain. Corrections to support invitation as HTML page instead of JavaScript alert box. //************************** //Global variables whose values may need to be customized. var ControlFrameTimeoutInterval = 10000; // How often to check if we have left our site, in milliseconds var CookieExpireTime = 12; // The time in months not to ask about the survey var ignoreCookie = 0; // 0 ==> use cookie to only ask one time, 1 ==> disable cookies var cookieName = "SurveyCookie"; // The name of the cookie we set var track = 0; // 1 to track disposition of all visitors, otherwise 0. var catchOnExit = 0; // 0=ask on entry to site, 1=ask on exit var questionProb = 1; // The probability of a user being questioned. var siteSwitchProb = 0.5; var delaySurveyProb = 0.0; //var siteSwitchProb = 0.33;// The probability of the user going to the non-sponsored Site. //var delaySurveyProb = 0.5; // The probability of a user who is sent to the sponsored site // being asked to do the survey after surveyAfterVisits visits // (the "sponsored, delayed" bucket). var surveyAfterVisits= 0; // If delaySurveyProb > 0, ask survey after this number of visits // for those visitors put in the "sponsored, delayed" bucket. // Typical values for the above 4 values are // (1, .5, 0, 0) no delayed bucket users. // (1, .33, .5, 4) divide users into 3 equal size buckets. var minSecondsConnected=0; // Don't present survey unless user has been connected to site this long. // Note however that if the user Refreshes the screen, this // unavoidably resets the "start viewing" clock. //var UrlControlFrame = "frameCatchExit.html"; var UrlSurveyPopup = "SEI_survey1.html";// The url to open when we leave our site, to present the survey. var UrlSiteNormal = "../home.html"; // normal site, no survey var UrlSiteSurveyNormal = "framesetLogo.html"; // normal site with logos, survey participant var UrlSiteSurveyCompare= "framesetNoLogo.html"; // normal site no logos, survey participant var question = "Would you take a moment to answer a few short questions when you have " + "looked at IT Business Insider to help us make it even better?\n" + "If you will we would be happy to send you a free copy of MIND GAMES, fun " + "brain teasers and mind puzzles aimed at increasing mental agility.\n"; //+ "Please take one minute to browse our content to activate the survey." var questionDelayed = "Would you take a moment to answer a few short questions after you have " + "visited IT Business Insider a few times to help us make it even better?\n" + "If you will we would be happy to send you a free copy of MIND GAMES, fun " + "brain teasers and mind puzzles aimed at increasing mental agility.\n"; //+ "Please take one minute to browse our content to activate the survey." //************************** //Other global variabls var ControlFrameSite; // Used to store the site we think we are in //Cookie values are separated by ":" and include these fields: // 1. siteVersion: Bucket in which we placed visitor on initial visit: // 0 ==> un-sponsored. // 1 ==> sponsored. // 2. willParticipate: State of the visitor // 0 ==> do not ask (for example, // visitor was excluded by questionProb, // visitor declined the invitation, // visitor already submitted survey). // 1 ==> agreed to participate, not yet submitted survey. // 3. numVisits: Number remaining times visitor must come to the site before showing survey. // 4. numVisitSoFar: Total number times visitor came to site so far (before answering survey). // 5. clickOn: identifier for link(s) visitor clicked on (normally a sponsoship logo). // 6. userID: string of numbers that uniquely identifies each visitor across multiple sessions var unsponsored = 0; var sponsored = 1; var unknown = -1; var siteVersion; // one of above three values var doNotAsk = 0; var agreedToParticipate = 1; var willParticipate; // one of above two values, or unknown var numVisits; // number visits until we show survey var numVisitSoFar; // number visits before survey responded to var clickOn; // links visitor clicked on. var userID; // number to uniquely identify visitor var startClock; // time stamp when viewer started at site //************************** //automatically go to another page function goto_page(page) { if( document.images ) { // javascript 1.2 or later location.replace(page); // The back button will work, no looping } else { location.href(page); // can't back out of this page :-) } } function randomizeSite() { if( Math.random() > questionProb ) { // We are not questioning this user willParticipate = doNotAsk; disposition = "Randomly decided to not ask"; } else { var randomNumber = new Number(Math.random()); if( randomNumber <= siteSwitchProb ) { // Assign to the non-sponsored site siteVersion = unsponsored; disposition = "assigned unsponsored"; } else { // Assign to the sponsored site siteVersion = sponsored; if( Math.random() < delaySurveyProb) { // Show survey after surveyAfterVisits visits numVisits = surveyAfterVisits; disposition = "assigned delayed sponsored"; } else { // Show survey after this visit numVisits = 1; disposition = "assigned immediate sponsored"; } } willParticipate= agreedToParticipate; } saveCookie(); //alert("randomizeSite: " + randomNumber + " " + siteSwitchProb + " " + siteVersion); } /************************************************************************************** * Manually decided whether or not to show the logo. This function may be called * instead of randomizeSite() when non-random criteria determine if the logo should be * displayed. * * Created by mitch@comandsolutions.com 3/14/2007 */ function setSite( showLogo ) { if( Math.random() > questionProb ) { // We are not questioning this user willParticipate = doNotAsk; disposition = "Randomly decided to not ask"; } else if(showLogo) { // Assign to the sponsored site siteVersion = sponsored; if( Math.random() < delaySurveyProb) { // Show survey after surveyAfterVisits visits numVisits = surveyAfterVisits; disposition = "assigned delayed sponsored"; } else { // Show survey after this visit numVisits = 1; disposition = "assigned immediate sponsored"; } } else { // Assign to the non-sponsored site siteVersion = unsponsored; disposition = "assigned unsponsored"; } willParticipate= agreedToParticipate; saveCookie(); } //Action to set value when user clicked on a sponsorship logo. //flag is bit map to identify one or more links clicked on. function Hyperlink_Click(flag) { parseCookie("hyperlink_click"); clickOn = clickOn | flag; saveCookie(); } //Get our cookie. Note, document.cookie might have multiple cookies, as in // "name1=value1; 0;name2=value2" //If there are multiple cookie names, one should not be the same as the other //except for a prefix string. I.E., this code will be confused by two //cookie names such as "abcdef" and "def". function Get_Cookie(name) { var start = document.cookie.indexOf(name + "="); if (start == -1) return null; //cookie not found var len = start+name.length+1; var end = document.cookie.indexOf(";",len); if (end == -1) end = document.cookie.length; return unescape(document.cookie.substring(len, end)); } // Note: we don't use the UTC string method here since it is // not available in javascript 1.0 function Set_Cookie(name, value, expires /*, path, domain, secure */) { var str; str = name + "=" + escape(value); str += ( (expires) ? ";expires=" + expires.toString() : ""); /* str += ( (path) ? ";path=" + path : ""); str += ( (domain) ? ";domain=" + domain : ""); str += ( (secure) ? ";secure" : ""); */ document.cookie = str; } function generateNewUserID() { var timeStamp = new Date(); var randomNumber = Math.round(100000*Math.random()); return '' + timeStamp.getTime() + randomNumber; } //Get and parse cookie value (siteVersion:willParticipate:numVisits:numVisitSoFar:clickOn) //and set global flags. function parseCookie(value, title) { siteVersion = "NaN"; willParticipate = "NaN"; numVisits = "NaN"; numVisitSoFar = "NaN"; clickOn = 0; userID = "NaN"; value = Get_Cookie(cookieName); if (value != null) { arrayOfValues = value.split(":", 6); if (arrayOfValues.length >= 1) { siteVersion = arrayOfValues[0]; if (arrayOfValues.length >= 2) { willParticipate = arrayOfValues[1]; if (arrayOfValues.length >= 3) { numVisits = arrayOfValues[2]; if (arrayOfValues.length >= 4) { numVisitSoFar = arrayOfValues[3]; if (arrayOfValues.length >= 5) { clickOn = arrayOfValues[4]; if (arrayOfValues.length >= 6) { userID = arrayOfValues[5]; } } } } } } } else { //No cookie yet, does the user have cookies enabled? if (testCookiesEnabled() != 0) { willParticipate = doNotAsk; //cookies disabled, do not participate } } // Check for valid values from cookie. // If anything is invalid, ignore previous cookie and assume this is // first visit to site. if ( siteVersion == "NaN" || willParticipate == "NaN" || numVisits == "NaN" || numVisitSoFar == "NaN" || clickOn == "NaN" || userID == "NaN" ) { siteVersion = unknown; willParticipate = unknown; numVisits = 0; numVisitSoFar = 0; clickOn = 0; userID = generateNewUserID(); } //showCookie(value, title); return value; } function saveCookie() { if( userID == null || userID == "NaN" ) { userID = generateNewUserID(); } var value = siteVersion + ":" + willParticipate + ":" + numVisits + ":" + numVisitSoFar + ":" + clickOn + ":" + userID + ":"; var expire = make_expire_months(CookieExpireTime); Set_Cookie(cookieName, value, expire); } function resetCookie() { Set_Cookie(cookieName, unknown + ":" + unknown + ":" + unknown + ":" + 0 + ":" + 0, make_expire_months(-1)); } function getTextCookie(value, title) { var msg; msg = title + " Cookie: " + cookieName + "=" + value; msg += "\nraw cookie: " + unescape(document.cookie); msg += "\nsite version to show = "; if (siteVersion == unsponsored) msg += "unsponsored"; else if (siteVersion == sponsored) msg += "sponsored"; else msg += "unknown"; msg += "\nwill participate in survey = "; if (willParticipate == doNotAsk) msg += "declined or already responded"; else if (willParticipate == agreedToParticipate) msg += "agreed to participate"; else msg += "unknown"; msg += "\nnum visits until show survey= " + numVisits; msg += "\nnum visits so far = " + numVisitSoFar; msg += "\nlinks clicked on = "; if (clickOn == 0) msg += "none"; else msg += clickOn; if (userID == 0) msg += "none"; else msg += userID; return msg; } function showCookie(value, title) { alert(getTextCookie(value, title)); } function testCookiesEnabled() { var value = Get_Cookie(cookieName); if (value == null) { //See if cookies are disabled Set_Cookie("testCookiesEnabled", "test:enabled", make_expire_months(1)); value = Get_Cookie("testCookiesEnabled"); Set_Cookie("testCookiesEnabled", "test:enabled", -1); if (value == null) return 0; //cookies are disabled else return 2; //cookies are enabled but our cookie is not yet set } else { return 1; //they are enabled } } function textCookie(title) { var msg; var value = Get_Cookie(cookieName); switch (testCookiesEnabled()) { case 0: msg - "Cookies not enabled"; break; case 2: msg = "Cookie: " + cookieName + " not found"; break; case 1: parseCookie(title); msg = getTextCookie(value, title); break; } return msg; } function testGetCookie() { switch (testCookiesEnabled()) { case 0: alert("Cookies not enabled"); break; case 2: alert("Cookie: " + cookieName + " not found"); break; case 1: parseCookie("testGetCookie"); showCookie(value, ""); break; } } // compute a date in seconds in the future for use with cookies function make_expire_secs(secs) { var today = new Date(); var expires = new Date(today.getTime() + (secs*1000)); // alert( "Today is " + today + " " + today.toGMTString() + " " + secs + " " + "expires is " + expires + " " + expires.toGMTString() ); return expires; } function make_expire_hours(hours) { return make_expire_secs(hours*3600); // hours to seconds } function make_expire_days(days) { return make_expire_hours(days*24); // days to hours } function make_expire_months(months) { return make_expire_days(months*30.44); // months to days } // This section is the code used in our control frame page function encodeNow(timeStamp) { return Date.parse(timeStamp.toString()); } // Set up our site variable, hopefully the url has a site= tag on the end function ControlFrameOnLoad() { if( document.URL.indexOf('?') != -1 ) { ControlFrameSite = document.URL.substr( document.URL.indexOf('?') ); } else { ControlFrameSite = "?" + 'site=unknown'; } parseCookie("ControlFrameOnLoad--"); //get cookie settings into this frame's space startClock = new Date(); ControlFrameSite += '&v=' + numVisitSoFar; ControlFrameSite += '&s=' + Date.parse(startClock.toString()); UrlSurveyPopup += ControlFrameSite; // alert( "Onload Document site = " + ControlFrameSite + "\nUrlSurveyPopup = " + UrlSurveyPopup ); } function addEndAt(arg, timeStamp) { return arg + '&e=' + encodeNow(timeStamp); } // Note: we can not access the cookie in either // ControlFrameSimpleErrorHandler or ControlFrameUnloadHandler. // So, we test instead the variables set by parseCookie, which we set in // Set_Cookie and ControlFrameSimpleErrorHandler. // We test for a cookie with this timer method incase the user // filled out the survey and somehow we didn't catch it here. // If the interval is too short, we slow down the browser. function ControlFrameSimpleErrorHandler(errorMessage,url,line) { if( willParticipate != agreedToParticipate ) { // This visitor is not participating // alert( "ErrorHandler: visitor not participating or already submitted survey" ); return true; } // alert( "Unload handler opening " + UrlSurveyPopup ); var stopClock = new Date(); if (stopClock - startClock >= minSecondsConnected * 1000) { var win = window.open( addEndAt(UrlSurveyPopup, stopClock), 'surveyFrame' ); win.document.site = ControlFrameSite; } else { // alert("Unload handler, not intab by timing"); } return true; } //Called via frameCatchExit.html
questionProb ) { // We are not questioning this user willParticipate = doNotAsk; disposition = "Randomly decided to not ask"; } else { q = question; if( Math.random() <= siteSwitchProb ) { // Assign to the non-sponsored site siteVersion = unsponsored; disposition = "assigned unsponsored"; } else { // Assign to the sponsored site siteVersion = sponsored; if( Math.random() < delaySurveyProb) { // Show survey after surveyAfterVisits visits numVisits = surveyAfterVisits; q = questionDelayed; disposition = "assigned delayed sponsored"; } else { // Show survey after this visit numVisits = 1; disposition = "assigned immediate sponsored"; } } // Now ask if he'll participate if (catchOnExit) { willParticipate = agreedToParticipate; disposition = disposition + ", ask on exit"; } else { if( !confirm( q ) ) { // user has declined to take our survey willParticipate = doNotAsk; disposition = disposition + ", declined"; } else { // user has agreed to take our survey willParticipate = agreedToParticipate; disposition = disposition + ", agreed"; } } } } else { disposition = "cookie found, " + siteVersion + ", willParticipate=" + willParticipate + ", numVisits=" + numVisits; } } saveCookie(); if (willParticipate || catchOnExit) { if (siteVersion == sponsored) site = UrlSiteSurveyNormal; else if (siteVersion == unsponsored) site = UrlSiteSurveyCompare; else site = UrlSiteNormal; } else site = UrlSiteNormal; // alert( "Going to site " + site); // We will lose control after the location changes if (track) { //Site is a location relative to the current page. //Where we redirect to depends on where we are. //But the submit() call below changes the current directory to cgi-bin, //and we don't know where that might be in general. //So, we resolve this by changing site to a fully qualified path. var newURL; var i; newURL = new String(location.href); i = newURL.lastIndexOf("/"); site = newURL.substring(0, i+1) + site; if( document.images ) { // javascript 1.2 or later location.replace(site); // The back button will work, no looping } else { //window.location.href = site; location.href(site); // can't back out of this page :-) } document.surveyForm.cookie.value = parseCookie("SurveySubmit"); var subClock = new Date(); document.surveyForm.redirect.value = site; document.surveyForm.disposition.value = disposition; document.surveyForm.linkFrom.value = document.referrer; document.surveyForm.submitW.value = Date.parse(subClock.toString()); document.surveyForm.submit(); } else { if( document.images ) { // javascript 1.2 or later location.replace(site); // The back button will work, no looping } else { location.href(site); // can't back out of this page :-) } } } // Beginning of the survey section // This function is called when the user submits our form. // It sets the cookie that we have already received the survey from // this browser, so we won't ask again. // Validation on data or any other thing you need done at submit time // could be done here. // When this is called we are no longer in the SEI frameset. function SurveySubmit() { document.surveyForm.cookie.value = parseCookie("SurveySubmit"); willParticipate = doNotAsk; numVisits = 0; saveCookie(); var subClock = new Date(); document.surveyForm.submitW.value = Date.parse(subClock.toString()); } //This function is used for the onChange event in an field //to validate input on the client side. function isPosInt(s) { var v; if (s.value == "" || s.value == null) return true; v = parseInt(s.value); if (parseInt(s.value) >= 0 && s.value==v) return true; alert("Please enter a positive number or 0."); s.value == ""; return false; } //This function is used for the onChange event in an field //to validate input on the client side. function is1to9(s) { var v; if (s.value == "" || s.value == null) return true; v = parseInt(s.value); if (v > 0 && v <= 9 && s.value == v) return true; alert("Please enter a number from 1 to 9."); s.value = ""; return false; } //This function is used for the onSubmit event in an