Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

1. Initial commit to git

  • Loading branch information...
commit 4a1b6cb4558639e2a6099564e4c2fbfe291a7e72 0 parents
@mattlevine mattlevine authored
Showing with 16,167 additions and 0 deletions.
  1. +5 −0 .gitignore
  2. +29 −0 Application.cfc
  3. +68 −0 ApplicationProxy.cfm
  4. +34 −0 admin/Application.cfc
  5. +19 −0 admin/Application_not_used.cfm
  6. +27 −0 admin/index.cfm
  7. +195 −0 admin/javaScripts.cfm
  8. +51 −0 admin/login.cfm
  9. +88 −0 admin/otherviewer.cfm
  10. +74 −0 admin/password.cfm
  11. +14 −0 admin/preview.cfm
  12. +64 −0 admin/print.cfm
  13. +70 −0 admin/questions.cfm
  14. +125 −0 admin/questions_edit.cfm
  15. +43 −0 admin/questiontypes.cfm
  16. +92 −0 admin/questiontypes_edit.cfm
  17. +476 −0 admin/stats.cfm
  18. +28 −0 admin/stats_matrix.cfm
  19. +21 −0 admin/stats_mc.cfm
  20. +9 −0 admin/stats_pie.cfm
  21. +12 −0 admin/style.xml
  22. +9 −0 admin/style_pie.xml
  23. +54 −0 admin/surveys.cfm
  24. +386 −0 admin/surveys_edit.cfm
  25. +88 −0 admin/template_edit.cfm
  26. +47 −0 admin/templates.cfm
  27. +82 −0 admin/textviewer.cfm
  28. +46 −0 admin/users.cfm
  29. +118 −0 admin/users_edit.cfm
  30. +37 −0 admin/viewemaillist.cfm
  31. +16 −0 admin/xml.questions.cfm
  32. +360 −0 cfcs/question.cfc
  33. +127 −0 cfcs/questiontype.cfc
  34. +10 −0 cfcs/settings.xml.cfm
  35. +35 −0 cfcs/soundings.cfc
  36. +607 −0 cfcs/survey.cfc
  37. +69 −0 cfcs/surveyProxy.cfc
  38. +154 −0 cfcs/template.cfc
  39. +116 −0 cfcs/toxml.cfc
  40. +187 −0 cfcs/user.cfc
  41. +96 −0 cfcs/utils.cfc
  42. +48 −0 dsp_list.cfm
  43. +107 −0 handlers/matrix/display.cfm
  44. +333 −0 handlers/matrix/edit.cfm
  45. +50 −0 handlers/matrix/preview.cfm
  46. +49 −0 handlers/matrix/save.cfm
  47. +104 −0 handlers/matrix/stats.cfm
  48. +87 −0 handlers/multiplechoice/display.cfm
  49. +214 −0 handlers/multiplechoice/edit.cfm
  50. +27 −0 handlers/multiplechoice/preview.cfm
  51. +48 −0 handlers/multiplechoice/print.cfm
  52. +55 −0 handlers/multiplechoice/save.cfm
  53. +117 −0 handlers/multiplechoice/stats.cfm
  54. +24 −0 handlers/multiplechoicemulti/display.cfm
  55. +16 −0 handlers/multiplechoicemulti/edit.cfm
  56. +6 −0 handlers/multiplechoicemulti/preview.cfm
  57. +17 −0 handlers/multiplechoicemulti/print.cfm
  58. +18 −0 handlers/multiplechoicemulti/save.cfm
  59. +20 −0 handlers/multiplechoicemulti/stats.cfm
  60. +24 −0 handlers/multiplechoicemultiother/display.cfm
  61. +16 −0 handlers/multiplechoicemultiother/edit.cfm
  62. +6 −0 handlers/multiplechoicemultiother/preview.cfm
  63. +18 −0 handlers/multiplechoicemultiother/save.cfm
  64. +21 −0 handlers/multiplechoicemultiother/stats.cfm
  65. +24 −0 handlers/multiplechoiceother/display.cfm
  66. +16 −0 handlers/multiplechoiceother/edit.cfm
  67. +6 −0 handlers/multiplechoiceother/preview.cfm
  68. +18 −0 handlers/multiplechoiceother/save.cfm
  69. +21 −0 handlers/multiplechoiceother/stats.cfm
  70. +131 −0 handlers/nextquestion.cfm
  71. +9 −0 handlers/nextquestionlogic.cfm
  72. +48 −0 handlers/textbox/display.cfm
  73. +92 −0 handlers/textbox/edit.cfm
  74. +10 −0 handlers/textbox/preview.cfm
  75. +26 −0 handlers/textbox/print.cfm
  76. +36 −0 handlers/textbox/save.cfm
  77. +41 −0 handlers/textbox/stats.cfm
  78. +24 −0 handlers/textboxmulti/display.cfm
  79. +16 −0 handlers/textboxmulti/edit.cfm
  80. +10 −0 handlers/textboxmulti/preview.cfm
  81. +18 −0 handlers/textboxmulti/print.cfm
  82. +18 −0 handlers/textboxmulti/save.cfm
  83. +20 −0 handlers/textboxmulti/stats.cfm
  84. +53 −0 handlers/truefalse/display.cfm
  85. +99 −0 handlers/truefalse/edit.cfm
  86. +10 −0 handlers/truefalse/preview.cfm
  87. +28 −0 handlers/truefalse/save.cfm
  88. +54 −0 handlers/truefalse/stats.cfm
  89. +23 −0 handlers/yesno/display.cfm
  90. +16 −0 handlers/yesno/edit.cfm
  91. +10 −0 handlers/yesno/preview.cfm
  92. +18 −0 handlers/yesno/save.cfm
  93. +21 −0 handlers/yesno/stats.cfm
  94. +3 −0  htmlHead.cfm
  95. BIN  images/bg.gif
  96. BIN  images/bodyBg.gif
  97. BIN  images/bodyBottom.gif
  98. BIN  images/headerTop.gif
  99. BIN  images/input.gif
  100. BIN  images/left.gif
  101. BIN  images/login.gif
  102. BIN  images/logo.gif
  103. BIN  images/menu1.gif
  104. BIN  images/menu1Hot.gif
  105. BIN  images/menu2.gif
  106. BIN  images/menu2Hot.gif
  107. BIN  images/menu3.gif
  108. BIN  images/menu3Hot.gif
  109. BIN  images/menu4.gif
  110. BIN  images/menu4Hot.gif
  111. BIN  images/menuLeft.gif
  112. BIN  images/menuRight.gif
  113. BIN  images/right.gif
  114. BIN  images/shim.gif
  115. +4,595 −0 includes/SpryData.js
  116. +16 −0 includes/jquery-1.5.2.min.js
  117. +31 −0 includes/jquery.json-2.2.min.js
  118. +93 −0 includes/udf.cfm
  119. +2,499 −0 includes/xpath.js
  120. +53 −0 index.cfm
  121. BIN  install/Welcome to Soundings.pdf
  122. +4 −0 install/migrate3/Application.cfm
  123. +11 −0 install/migrate3/assignsurveys.cfm
  124. +15 −0 install/migrate3/userid.cfm
  125. +154 −0 install/mysql.sql
  126. +219 −0 install/postgres.sql
  127. +303 −0 install/readme.txt
  128. +136 −0 install/sqlserver.sql
  129. +29 −0 pagetemplates/admin_footer.cfm
  130. +56 −0 pagetemplates/admin_header.cfm
  131. +16 −0 pagetemplates/main_footer.cfm
  132. +16 −0 pagetemplates/main_header.cfm
  133. +17 −0 pagetemplates/plain_footer.cfm
  134. +26 −0 pagetemplates/plain_header.cfm
  135. +13 −0 plugin/config.cfm
  136. +13 −0 plugin/config.xml
  137. +11 −0 plugin/dbScripts/mssqlDelete.cfm
  138. +116 −0 plugin/dbScripts/mssqlInstall.cfm
  139. +11 −0 plugin/dbScripts/mysqlDelete.cfm
  140. +153 −0 plugin/dbScripts/mysqlInstall.cfm
  141. +7 −0 plugin/dbScripts/updates/mssql.cfm
  142. +5 −0 plugin/dbScripts/updates/mysql.cfm
  143. +146 −0 plugin/plugin.cfc
  144. +88 −0 stylesheets/adminStyle.css
  145. +63 −0 stylesheets/embed.css
  146. +100 −0 stylesheets/style.css
  147. +45 −0 survey.cfm
  148. +23 −0 tags/datacol.cfm
  149. +178 −0 tags/datatable.cfm
  150. +31 −0 tags/layout.cfm
  151. +37 −0 tags/surveycomplete.cfm
  152. +306 −0 tags/surveydisplay.cfm
5 .gitignore
@@ -0,0 +1,5 @@
+/.project
+/.settings
+/.DS_Store
+/settings.xml
+/.rdsTempFiles
29 Application.cfc
@@ -0,0 +1,29 @@
+<!--- This file is part of Mura CMS.
+
+ Mura CMS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, Version 2 of the License.
+
+ Mura CMS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Mura CMS. If not, see <http://www.gnu.org/licenses/>. --->
+<cfcomponent output="false">
+
+ <cfinclude template="../../config/applicationSettings.cfm">
+
+ <cffunction name="onRequestStart" returnType="boolean" output="false">
+ <cfargument name="thePage" type="string" required="true">
+
+ <cfinclude template="../../config/settings.cfm">
+ <cfinclude template="plugin/config.cfm" />
+ <cfinclude template="ApplicationProxy.cfm">
+
+
+ <cfreturn true>
+ </cffunction>
+
+</cfcomponent>
68 ApplicationProxy.cfm
@@ -0,0 +1,68 @@
+<cfsetting enablecfoutputonly=true showdebugoutput=false>
+<!---
+ Name : Application.cfm
+ Author : Raymond Camden
+ Created : September 2, 2004
+ Last Updated : August 3, 2007
+ History : change application.cfc to soundings.cfc
+ : Stupid IE. If you hit ENTER instead of clicking the button, it wouldn't send the value. (rkc 3/1/06)
+ : work w/o mapping (rkc 3/10/06)
+ : user changes (rkc 8/3/07)
+ Purpose :
+--->
+
+
+<cfset pApp=request.pluginConfig.getApplication() />
+<cfset pSession=request.pluginConfig.getSession() />
+
+
+<cfif not pApp.valueExists("init") or structKeyExists(url,"reinit")>
+
+ <!--- Get main settings --->
+ <cfset pApp.setValue("soundings",createObject("component","cfcs.soundings"))>
+ <cfset pApp.setValue("settings",pApp.getValue("soundings").getSettings())>
+
+ <!--- Mura plugin --->
+ <cfset pApp.getValue("settings").dsn = application.configBean.getDatasource()>
+ <cfset pApp.getValue("settings").dbtype = application.configBean.getDBType()>
+ <cfset pApp.getValue("settings").fromaddress = application.configBean.getAdminEmail()>
+ <cfset pApp.getValue("settings").tableprefix = "sp" & request.pluginConfig.getPluginID() & "_">
+ <!--- --->
+
+ <cfset pApp.setValue("survey",createObject("component","cfcs.surveyProxy").init(pApp.getValue("settings").dsn,pApp.getValue("settings").dbtype,pApp.getValue("settings").tableprefix))>
+ <cfset pApp.setValue("question",createObject("component","cfcs.question").init(pApp.getValue("settings").dsn,pApp.getValue("settings").dbtype,pApp.getValue("settings").tableprefix))>
+ <cfset pApp.setValue("questiontype",createObject("component","cfcs.questiontype").init(pApp.getValue("settings").dsn,pApp.getValue("settings").dbtype,pApp.getValue("settings").tableprefix))>
+ <cfset pApp.setValue("template",createObject("component","cfcs.template").init(pApp.getValue("settings").dsn,pApp.getValue("settings").dbtype,pApp.getValue("settings").tableprefix))>
+ <cfset pApp.setValue("user",createObject("component","cfcs.user").init(pApp.getValue("settings").dsn,pApp.getValue("settings").dbtype,pApp.getValue("settings").tableprefix))>
+ <cfset pApp.setValue("utils",createObject("component","cfcs.utils"))>
+ <cfset pApp.setValue("toxml",createObject("component","cfcs.toxml"))>
+
+ <cfset request.pSession.surveys = structNew()>
+ <cfset pApp.setValue("init",true)>
+
+</cfif>
+
+<cfset request.pApp=pApp.getAllValues() />
+<cfset request.pSession=pSession.getAllValues() />
+
+<!--- include UDFs --->
+<cfinclude template="includes/udf.cfm">
+
+<cfif isDefined("url.logout")>
+ <cfset structDelete(request.pSession, "loggedin")>
+</cfif>
+
+<!--- handle security --->
+<cfif not request.udf.isLoggedOn()>
+
+ <!--- are we trying to logon? --->
+ <cfif isDefined("form.username") and isDefined("form.password")>
+ <cfif request.pApp.user.authenticate(form.username,form.password)>
+ <cfset request.pSession.user = request.pApp.user.getUser(form.username)>
+ <cfset request.pSession.loggedin = true>
+ </cfif>
+ </cfif>
+
+</cfif>
+
+<cfsetting enablecfoutputonly=false>
34 admin/Application.cfc
@@ -0,0 +1,34 @@
+<cfcomponent output="false">
+
+ <cfinclude template="../../../config/applicationSettings.cfm">
+
+ <cffunction name="onRequestStart" returnType="boolean" output="false">
+ <cfargument name="thePage" type="string" required="true">
+
+
+ <cfinclude template="../../../config/settings.cfm">
+ <cfinclude template="../plugin/config.cfm" />
+ <cfinclude template="../ApplicationProxy.cfm">
+
+ <cfif not request.udf.isLoggedOn()>
+ <cfset userBean = application.userManager.read(session.mura.userid)>
+ <cfset user = request.pApp.user.getUser(userBean.getUsername())>
+
+ <cfif user.username eq "">
+ <cfset data = structNew()>
+ <cfset data.username = userBean.getUsername()>
+ <cfset data.password = "password">
+ <cfset data.isAdmin = 1>
+ <cfset request.pApp.user.addUser(argumentCollection=data)>
+ </cfif>
+
+ <cfset request.pSession.user = request.pApp.user.getUser(userBean.getUsername())>
+ <cfset request.pSession.loggedin = true>
+ </cfif>
+
+ <cfreturn true>
+ </cffunction>
+
+
+</cfcomponent>
+
19 admin/Application_not_used.cfm
@@ -0,0 +1,19 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : request.pApp.cfm
+ Author : Raymond Camden
+ Created : September 2, 2004
+ Last Updated : September 2, 2004
+ History :
+ Purpose :
+--->
+
+<!--- include root app --->
+<cfinclude template="../ request.pApp.cfm">
+
+<cfif not request.udf.isLoggedOn()>
+ <cfinclude template="login.cfm">
+ <cfabort>
+</cfif>
+
+<cfsetting enablecfoutputonly=false>
27 admin/index.cfm
@@ -0,0 +1,27 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : index.cfm
+ Author : Raymond Camden
+ Created : September 01, 2004
+ Last Updated : February 11, 2006
+ History : Just changed the text a bit.
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<tags:layout templatename="admin" title="Welcome to the Soundings Administrator">
+
+<cfoutput>
+<p>
+Welcome to Soundings # request.pApp.settings.version#. This administrator allows you to edit all aspects of your surveys. Please select an option from the top menu to begin.
+</p>
+
+<p>
+Please send any bug reports to <a href="mailto:ray@camdenfamily.com">Raymond Camden</a>. For the latest
+news and updates, visit the <a href="http://soundings.riaforge.org">Soundings project page</a>.
+</p>
+</cfoutput>
+
+</tags:layout>
+
+<cfsetting enablecfoutputonly=false>
195 admin/javaScripts.cfm
@@ -0,0 +1,195 @@
+//Contents for menu 1
+var menu1=new Array()
+menu1[0]='<a href="surveys.cfm">Surveys</a>'
+menu1[1]='<a href="questions.cfm">Questions</a>'
+<cfif isBoolean(request.pSession.user.isAdmin) and request.pSession.user.isAdmin>menu1[menu1.length+1]='<a href="questiontypes.cfm">Question Types</a>'</cfif>
+menu1[menu1.length+1]='<a href="templates.cfm">Templates</a>'
+
+//Contents for menu 2
+var menu2=new Array()
+menu2[0]='<a href="password.cfm">Set Password</a>'
+<cfif isBoolean(request.pSession.user.isAdmin) and request.pSession.user.isAdmin>menu2[1]='<a href="users.cfm">Users</a>'</cfif>
+
+
+//Contents for menu 3
+var menu3=new Array()
+menu3[0]='<a href="stats.cfm">Reporting</a>'
+
+
+//Contents for menu 4
+var menu4=new Array()
+menu4[0]='<a href="index.cfm">Admin Home</a>'
+menu4[1]='<a href="../">Soundings Home</a>'
+menu4[2]='<a href="index.cfm?logout=1">Logout</a>'
+
+
+var menuwidth='185px' //default menu width
+var menubgcolor='#407ED8' //menu bgcolor
+var disappeardelay=250 //menu disappear speed onMouseout (in miliseconds)
+var hidemenu_onclick="yes" //hide menu when user clicks within menu?
+
+/////No further editting needed
+
+var ie4=document.all
+var ns6=document.getElementById&&!document.all
+
+if (ie4||ns6)
+document.write('<div id="dropmenudiv" style="visibility:hidden;width:'+menuwidth+';background-color:'+menubgcolor+'" onMouseover="clearhidemenu()" onMouseout="dynamichide(event)"></div>')
+
+function getposOffset(what, offsettype){
+var totaloffset=(offsettype=="left")? what.offsetLeft : what.offsetTop;
+var parentEl=what.offsetParent;
+while (parentEl!=null){
+totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop;
+parentEl=parentEl.offsetParent;
+}
+return totaloffset;
+}
+
+
+function showhide(obj, e, visible, hidden, menuwidth){
+if (ie4||ns6)
+dropmenuobj.style.left=dropmenuobj.style.top=-500
+if (menuwidth!=""){
+dropmenuobj.widthobj=dropmenuobj.style
+dropmenuobj.widthobj.width=menuwidth
+}
+if (e.type=="click" && obj.visibility==hidden || e.type=="mouseover")
+obj.visibility=visible
+else if (e.type=="click")
+obj.visibility=hidden
+}
+
+function iecompattest(){
+return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
+}
+
+function clearbrowseredge(obj, whichedge){
+var edgeoffset=0
+if (whichedge=="rightedge"){
+var windowedge=ie4 && !window.opera? iecompattest().scrollLeft+iecompattest().clientWidth-15 : window.pageXOffset+window.innerWidth-15
+dropmenuobj.contentmeasure=dropmenuobj.offsetWidth
+if (windowedge-dropmenuobj.x < dropmenuobj.contentmeasure)
+edgeoffset=dropmenuobj.contentmeasure-obj.offsetWidth
+}
+else{
+var topedge=ie4 && !window.opera? iecompattest().scrollTop : window.pageYOffset
+var windowedge=ie4 && !window.opera? iecompattest().scrollTop+iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18
+dropmenuobj.contentmeasure=dropmenuobj.offsetHeight
+if (windowedge-dropmenuobj.y < dropmenuobj.contentmeasure){ //move up?
+edgeoffset=dropmenuobj.contentmeasure+obj.offsetHeight
+if ((dropmenuobj.y-topedge)<dropmenuobj.contentmeasure) //up no good either?
+edgeoffset=dropmenuobj.y+obj.offsetHeight-topedge
+}
+}
+return edgeoffset
+}
+
+function populatemenu(what){
+if (ie4||ns6)
+dropmenuobj.innerHTML=what.join("")
+}
+
+
+function dropdownmenu(obj, e, menucontents, menuwidth){
+if (window.event) event.cancelBubble=true
+else if (e.stopPropagation) e.stopPropagation()
+clearhidemenu()
+dropmenuobj=document.getElementById? document.getElementById("dropmenudiv") : dropmenudiv
+populatemenu(menucontents)
+
+if (ie4||ns6){
+showhide(dropmenuobj.style, e, "visible", "hidden", menuwidth)
+dropmenuobj.x=getposOffset(obj, "left")
+dropmenuobj.y=getposOffset(obj, "top")
+dropmenuobj.style.left=dropmenuobj.x-clearbrowseredge(obj, "rightedge")+"px"
+dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px"
+}
+
+return clickreturnvalue()
+}
+
+function clickreturnvalue(){
+if (ie4||ns6) return false
+else return true
+}
+
+function contains_ns6(a, b) {
+while (b.parentNode)
+if ((b = b.parentNode) == a)
+return true;
+return false;
+}
+
+function dynamichide(e){
+if (ie4&&!dropmenuobj.contains(e.toElement))
+delayhidemenu()
+else if (ns6&&e.currentTarget!= e.relatedTarget&& !contains_ns6(e.currentTarget, e.relatedTarget))
+delayhidemenu()
+}
+
+function hidemenu(e){
+if (typeof dropmenuobj!="undefined"){
+if (ie4||ns6)
+dropmenuobj.style.visibility="hidden"
+}
+}
+
+function delayhidemenu(){
+if (ie4||ns6)
+delayhide=setTimeout("hidemenu()",disappeardelay)
+}
+
+function clearhidemenu(){
+if (typeof delayhide!="undefined")
+clearTimeout(delayhide)
+}
+
+if (hidemenu_onclick=="yes")
+document.onclick=hidemenu
+
+function MM_preloadImages() { //v3.0
+ var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
+ var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
+ if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
+}
+
+function MM_swapImgRestore() { //v3.0
+ var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
+}
+
+function MM_findObj(n, d) { //v4.01
+ var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+ d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+ if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+ for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+ if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+function MM_swapImage() { //v3.0
+ var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
+ if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
+}
+
+
+function MM_swapImgRestore() { //v3.0
+ var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
+}
+function MM_preloadImages() { //v3.0
+ var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
+ var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
+ if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
+}
+
+function MM_findObj(n, d) { //v4.01
+ var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+ d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+ if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+ for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+ if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+function MM_swapImage() { //v3.0
+ var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
+ if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
+}
51 admin/login.cfm
@@ -0,0 +1,51 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : login.cfm
+ Author : Raymond Camden
+ Created : September 01, 2004
+ Last Updated : March 4, 2005
+ History : removed bad js
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<tags:layout templatename="plain" title="Soundings Admin Login">
+
+<cfoutput>
+
+<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="0" height="90%" width="100%">
+ <TR>
+ <TD ALIGN="center" VALIGN="middle">
+
+<form action="#cgi.script_name#?#cgi.query_string#" method="post" name="login">
+<table width="585" height="115" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><div align="center"><img src="../images/logo.gif" width="172" height="185"></div></td>
+ </tr>
+ <tr>
+ <td height="115" background="../images/login.gif"><table width="68%" border="0" align="right" cellpadding="7" cellspacing="0">
+ <tr>
+ <td>
+ <input type="text" name="username" value="">
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="password" name="password" value=""> <input type="submit" name="logon" value="Login"></td>
+ </tr>
+
+ </table></td>
+ </tr>
+</table>
+</form>
+ </TD>
+ </TR>
+</TABLE>
+<script>
+document.login.username.focus();
+</script>
+</cfoutput>
+
+</tags:layout>
+
+<cfsetting enablecfoutputonly=false>
88 admin/otherviewer.cfm
@@ -0,0 +1,88 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : textviewer.cfm
+ Author : Raymond Camden
+ Created : September 16, 2004
+ Last Updated : September 16, 2004
+ History :
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<cfif not isDefined("url.questionidfk")>
+ <cfabort>
+</cfif>
+<cfparam name="url.earliestdate" default="">
+<cfparam name="url.latestdate" default="">
+
+<cfset question = request.pApp.question.getQuestion(url.questionidfk)>
+<cfset qt = request.pApp.questiontype.getQuestionType(question.questiontypeidfk)>
+
+<cfmodule template="../handlers/#qt.handlerRoot#/stats.cfm"
+ questionidfk="#url.questionidfk#"
+ getOther="true"
+ r_data="data"
+ earliestdate="#url.earliestdate#"
+ latestdate="#url.latestdate#"
+/>
+
+<cfparam name="url.start" default="1">
+<cfset perpage = 20>
+
+<tags:layout templatename="plain" title="Text Answers">
+
+<cfoutput>
+<h2>Text Answers for #question.question#</h2>
+</cfoutput>
+
+<cfif data.recordCount is 0>
+
+ <cfoutput>
+ <p>
+ There are no results for this answer.
+ </p>
+ </cfoutput>
+
+<cfelse>
+
+ <cfif data.recordCount gt perpage>
+ <cfoutput>
+ <p align="right">
+
+ </cfoutput><cfif url.start gt 1>
+ <cfoutput>
+ <a href="otherviewer.cfm?questionidfk=#url.questionidfk#&start=#url.start-perpage#">Previous</a>
+ </cfoutput>
+ </cfif>
+ <cfif (url.start + perpage - 1) lt data.recordCount>
+ <cfoutput>
+ <a href="otherviewer.cfm?questionidfk=#url.questionidfk#&start=#url.start+perpage#">Next</a>
+ </cfoutput>
+ </cfif>
+ </cfif>
+
+ <cfoutput>
+ <p>
+ <table width="100%" border="1">
+ </cfoutput>
+
+ <cfset column = listFirst(data.columnlist)>
+ <cfoutput query="data" startrow="#url.start#" maxrows="#perpage#">
+ <cfset val = data[column][currentRow]>
+ <tr
+ <cfif currentRow mod 2>bgcolor="yellow"</cfif>
+ >
+ <td>#currentRow#</td>
+ <td width="95%">#val#</td>
+ </tr>
+ </cfoutput>
+
+ <cfoutput>
+ </table>
+ </p>
+ </cfoutput>
+
+</cfif>
+
+</tags:layout>
+
74 admin/password.cfm
@@ -0,0 +1,74 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : password.cfm
+ Author : Raymond Camden
+ Created : September 01, 2004
+ Last Updated : October 8, 2005
+ History : Refresh settings on pword change (10/8/05)
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<cfif isDefined("form.cancel")>
+ <cflocation url="index.cfm" addToken="false">
+</cfif>
+
+<cfif isDefined("form.save")>
+ <cfset errors = "">
+ <!---
+ <cfif hash(form.oldpassword) is not request.pApp.settings.password>
+ <cfset errors = errors & "The old password did not match.<br>">
+ </cfif>
+ --->
+ <cfif not len(form.newpassword) or form.newpassword neq form.newpassword2>
+ <cfset errors = errors & "Your new password was blank or did not match the confirmation.<br>">
+ </cfif>
+ <cfif not len(errors)>
+ <cftry>
+ <cfset request.pApp.user.updatePassword(request.pSession.user.username,form.oldpassword,form.newpassword)>
+ <cfset msg = "Your password has been updated.">
+ <cfcatch>
+ <cfset errors = cfcatch.message>
+ </cfcatch>
+ </cftry>
+ </cfif>
+</cfif>
+
+<tags:layout templatename="admin" title="Set Password">
+
+<cfoutput>
+<p>
+Use the form below to update your password. You must enter the old password first.
+</p>
+
+<cfif isDefined("errors")><ul><b>#errors#</b></ul></cfif>
+<cfif isDefined("msg")>
+ <p><b>#msg#</b></p>
+<cfelse>
+<form action="#cgi.script_name#" method="post">
+<table cellspacing=0 cellpadding=5 class="adminEditTable" width="500">
+ <tr valign="top">
+ <td width="200"><b>(*) Old Password:</b></td>
+ <td><input type="password" name="oldpassword" value="" size="50"></td>
+ </tr>
+ <tr valign="top">
+ <td><b>(*) New Password:</b></td>
+ <td><input type="password" name="newpassword" value="" size="50"></td>
+ </tr>
+ <tr valign="top">
+ <td nowrap="true"><b>(*) Confirm Password:</b></td>
+ <td><input type="password" name="newpassword2" value="" size="50"></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td><input type="submit" name="save" value="Save"> <input type="submit" name="cancel" value="Cancel"></td>
+ </tr>
+</table>
+</form>
+</p>
+</cfif>
+</cfoutput>
+
+</tags:layout>
+
+<cfsetting enablecfoutputonly=false>
14 admin/preview.cfm
@@ -0,0 +1,14 @@
+<cfparam name="form.data" default="">
+<cfparam name="form.questiontype" default="">
+
+<cfif not isJSON(form.data)>
+ <cfoutput>
+ Sorry, we cannot render this preview.
+ </cfoutput>
+ <cfabort/>
+</cfif>
+<cfset data = deserializeJSON(form.data)>
+<cfset qt = request.pApp.questionType.getQuestionType(form.questionType)>
+
+<cfmodule template="../handlers/#qt.handlerRoot#/preview.cfm"
+ data="#data#" />
64 admin/print.cfm
@@ -0,0 +1,64 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : survey_edit.cfm
+ Author : Raymond Camden
+ Created : September 7, 2004
+ Last Updated : March 30, 2006
+ History : support for clearing results (rkc 3/30/06)
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<cfif not structKeyExists(url, "id")>
+ <cflocation url="index.cfm" addToken="false">
+</cfif>
+
+<cfif not request.pSession.user.isAdmin>
+ <cfset survey = request.pApp.survey.getSurvey(url.id, request.pSession.user.id)>
+<cfelse>
+ <cfset survey = request.pApp.survey.getSurvey(url.id)>
+</cfif>
+
+<cfset questions = request.pApp.question.getQuestions(url.id)>
+
+<cfsavecontent variable="output">
+<cfoutput>
+<html>
+
+<head>
+<style>
+.box {
+ border: thin solid rgb(0,0,0);
+ width: 500px;
+ height: 100px;
+}
+</style>
+</head>
+<body>
+
+<h1>#survey.name#</h1>
+</cfoutput>
+
+<cfloop query="questions" endrow="3">
+ <cfset questionob = request.pApp.question.getQuestions(url.id, currentRow)>
+
+ <cfmodule template="../handlers/#handlerRoot#/print.cfm"
+ step="#currentRow#" question="#questionob#" />
+
+</cfloop>
+
+<cfoutput>
+</body>
+</html>
+</cfoutput>
+
+</cfsavecontent>
+<cfif 1>
+<cfoutput>#output# <hr>#htmlCodeFormat(output)#</cfoutput><cfabort>
+</cfif>
+<cfdocument format="pdf" name="content"><cfoutput>#output#</cfoutput></cfdocument>
+
+<cfheader name="Content-Disposition" value="inline; filename=survey.pdf">
+<cfcontent type="application/pdf" reset="true" variable="#content#">
+
+
+<cfsetting enablecfoutputonly=false>
70 admin/questions.cfm
@@ -0,0 +1,70 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : questions.cfm
+ Author : Raymond Camden
+ Created : September 6, 2004
+ Last Updated : September 6, 2004
+ History :
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<cfif isDefined("url.surveyidfk")>
+ <cfset form.surveyidfk = url.surveyidfk>
+</cfif>
+<cfparam name="form.surveyidfk" default="">
+
+<tags:layout templatename="admin" title="Question Editor">
+
+ <!--- handle deletions --->
+ <cfif isDefined("form.mark") and len(form.mark)>
+ <cfloop index="id" list="#form.mark#">
+ <cfset request.pApp.question.deleteQuestion(id)>
+ </cfloop>
+ <cfoutput>
+ <p>
+ <b>Questions(s) deleted.</b>
+ </p>
+ </cfoutput>
+ </cfif>
+
+ <!--- get surveys --->
+ <cfif not request.pSession.user.isAdmin>
+ <cfset surveys = request.pApp.survey.getSurveys(useridfk=request.pSession.user.id)>
+ <cfelse>
+ <cfset surveys = request.pApp.survey.getSurveys()>
+ </cfif>
+
+ <cfoutput>
+ <script>
+ function checkSubmit() {
+ if(document.surveys.surveyidfk.selectedIndex != 0) document.surveys.submit();
+ }
+ </script>
+ <p>
+ <form action="#cgi.script_name#" method="get" name="surveys">
+ Select a Survey <select name="surveyidfk" onChange="checkSubmit()">
+ <option value="">---</option>
+ <cfloop query="surveys">
+ <option value="#id#" <cfif id is form.surveyidfk>selected</cfif>>#name#</option>
+ </cfloop>
+ </select>
+ </form>
+ </p>
+ </cfoutput>
+
+ <cfif form.surveyidfk neq "">
+ <cfset questions = request.pApp.question.getQuestions(form.surveyidfk)>
+
+ <tags:datatable data="#questions#" list="question,questiontype,rank" editlink="questions_edit.cfm" linkcol="question" label="Question" queryString="surveyidfk=#form.surveyidfk#">
+ <tags:datacol colname="question" label="Question" width="400" />
+ <tags:datacol colname="questiontype" label="Question Type" width="280" />
+ <tags:datacol colname="required" label="Req." width="30" format="YesNo"/>
+ <tags:datacol colname="rank" label="Rank" width="40" />
+ </tags:datatable>
+
+ </cfif>
+
+</tags:layout>
+
+<cfsetting enablecfoutputonly=false>
125 admin/questions_edit.cfm
@@ -0,0 +1,125 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : questions_edit.cfm
+ Author : Raymond Camden
+ Created : September 17, 2004
+ Last Updated : September 17, 2004
+ History :
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<cfif not isDefined("url.surveyidfk")>
+ <cflocation url="questions.cfm" addToken="false">
+</cfif>
+<cfif isDefined("form.cancel")>
+ <cflocation url="questions.cfm?surveyidfk=#url.surveyidfk#" addToken="false">
+</cfif>
+
+<!--- get question if not new --->
+<cfif url.id neq 0>
+ <cfset question = request.pApp.question.getQuestion(url.id)>
+ <cfset form.questionType = question.questionTypeIDFK>
+</cfif>
+
+
+<!--- get question types --->
+<cfset qts = request.pApp.questiontype.getQuestionTypes()>
+<!--- get all questions for survey --->
+<cfset questions = request.pApp.question.getQuestions(url.surveyidfk)>
+
+<tags:layout templatename="admin" title="Question Editor">
+
+<cfif isDefined("url.questionType")>
+ <cfset form.questionType = url.questionType>
+</cfif>
+<cfif not isDefined("form.questionType")>
+
+ <cfoutput>
+ <p>
+ <form action="questions_edit.cfm?#cgi.query_string#" method="post">
+ Please select a question type:
+ <select name="questionType">
+ <cfloop query="qts">
+ <option value="#id#">#name#</option>
+ </cfloop>
+ </select>
+ <br>
+ <input type="submit" value="Submit"> <input type="submit" name="cancel" value="Cancel">
+ </form>
+ </p>
+ </cfoutput>
+
+<cfelse>
+
+ <cfset qt = request.pApp.questionType.getQuestionType(form.questionType)>
+
+ <cfset qs = cgi.query_string>
+ <cfif not findNoCase("questionType",qs)>
+ <cfset qs = qs & "&questionType=#form.questionType#">
+ </cfif>
+
+ <cfset extra = structNew()>
+ <cfif url.id is not 0>
+ <!--- pass the question in --->
+ <cfset extra.question = question>
+ </cfif>
+
+ <cfset top = request.pApp.survey.getTopRank(surveyidfk)>
+
+ <!--- fire edit handler for qt --->
+ <cfoutput><div id="formwatcher"></cfoutput>
+
+ <cfmodule template="../handlers/#qt.handlerRoot#/edit.cfm"
+ queryString="#qs#"
+ surveyidfk="#surveyidfk#"
+ topRank="#top#"
+ questionType="#qt#"
+ attributeCollection="#extra#"
+ questions="#questions#"
+
+ />
+ <cfoutput></div></cfoutput>
+
+ <!--- live preview box --->
+ <cfoutput>
+ <script>
+ $(document).ready(function() {
+ function doPreview(){
+ //gather all the form fields
+ var fields = $("##formwatcher input").serializeArray();
+ var data = $.toJSON(fields);
+ $.post("preview.cfm", {data:data,questiontype:'#qt.id#'}, function(res) {
+ $("##livepreviewbox").html(res);
+ });
+ }
+ $("##formwatcher input").change(doPreview);
+ doPreview();
+ });
+ </script>
+ <style>
+ ##livepreview {
+ width: 90%;
+ //height: 200px;
+ margin:10px;
+ padding: 5px;
+ border-style:solid;
+ border-width: thin;
+ }
+
+ ##livepreview h2 {
+ margin-top:0px;
+ }
+ </style>
+ <div id="livepreview">
+ <h2>Live Preview</h2>
+ <div id="livepreviewbox"></div>
+ </div>
+ </cfoutput>
+
+</cfif>
+
+
+</tags:layout>
+
+<cfsetting enablecfoutputonly=false>
43 admin/questiontypes.cfm
@@ -0,0 +1,43 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : questiontypes.cfm
+ Author : Raymond Camden
+ Created : September 6, 2004
+ Last Updated : September 6, 2004
+ History :
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<!--- Security Check --->
+<cfif not isBoolean(request.pSession.user.isAdmin) or not request.pSession.user.isAdmin>
+ <cflocation url="index.cfm" addToken="false">
+</cfif>
+
+<tags:layout templatename="admin" title="Question Type Editor">
+
+ <!--- handle deletions --->
+ <cfif isDefined("form.mark") and len(form.mark)>
+ <cfloop index="id" list="#form.mark#">
+ <cfset request.pApp.questionType.deleteQuestionType(id)>
+ </cfloop>
+ <cfoutput>
+ <p>
+ <b>QuestionType(s) deleted.</b>
+ </p>
+ </cfoutput>
+ </cfif>
+
+ <!--- get qts --->
+ <cfset qts = request.pApp.questionType.getQuestionTypes()>
+
+
+ <tags:datatable data="#qts#" list="name,handlerroot" editlink="questiontypes_edit.cfm" linkcol="name" label="QuestionType"
+ deleteMsg="Warning - this will delete the questionType including all related questions.">
+ <tags:datacol colname="name" label="Name" width="400" />
+ <tags:datacol colname="handlerroot" label="Handler Root" width="200" />
+ </tags:datatable>
+
+</tags:layout>
+
+<cfsetting enablecfoutputonly=false>
92 admin/questiontypes_edit.cfm
@@ -0,0 +1,92 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : questiontypes_edit.cfm
+ Author : Raymond Camden
+ Created : September 7, 2004
+ Last Updated : September 7, 2004
+ History :
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<!--- Security Check --->
+<cfif not isBoolean(request.pSession.user.isAdmin) or not request.pSession.user.isAdmin>
+ <cflocation url="index.cfm" addToken="false">
+</cfif>
+
+<cfif isDefined("form.cancel") or not isDefined("url.id")>
+ <cflocation url="questiontypes.cfm" addToken="false">
+</cfif>
+
+<cfscript>
+function validHandlerRoot(s) {
+ if(reFindNoCase("[^a-z0-9]",s)) return false;
+ return true;
+}
+</cfscript>
+
+<cfif isDefined("form.save")>
+ <cfset form = request.udf.cleanStruct(form)>
+ <cfset errors = "">
+ <cfif not len(form.name)>
+ <cfset errors = errors & "You must specify a name.<br>">
+ </cfif>
+ <cfif not len(form.handlerRoot) or not validHandlerRoot(form.handlerRoot)>
+ <cfset errors = errors & "You must specify a valid handler root. This must be a string of letters or numbers with no spaces.<br>">
+ </cfif>
+
+ <cfif not len(errors)>
+
+ <cfif url.id neq 0>
+ <cfset request.pApp.questionType.updateQuestionType(url.id, form.name, form.handlerRoot)>
+ <cfelse>
+ <cfset request.pApp.questionType.addQuestionType(form.name, form.handlerRoot)>
+ </cfif>
+
+ <cfset msg = "QuestionType, #form.name#, has been updated.">
+ <cflocation url="questiontypes.cfm?msg=#urlEncodedFormat(msg)#">
+ </cfif>
+</cfif>
+
+<!--- get questionType if not new --->
+<cfif url.id gte 1>
+ <cfset qt = request.pApp.questionType.getQuestionType(url.id)>
+ <cfparam name="form.name" default="#qt.name#">
+ <cfparam name="form.handlerRoot" default="#qt.handlerRoot#">
+<cfelse>
+ <cfparam name="form.name" default="">
+ <cfparam name="form.handlerRoot" default="">
+</cfif>
+
+<tags:layout templatename="admin" title="QuestionType Editor">
+
+<cfoutput>
+<p>
+Please use the form below to enter details about the QuestionType. All required fields are marked (*). QuestionTypes
+allow you to define the types of questions in use by Soundings. The handlerroot should be a folder underneath the handlers folder.
+</p>
+
+<p>
+<cfif isDefined("errors")><ul><b>#errors#</b></ul></cfif>
+<form action="#cgi.script_name#?#cgi.query_string#" method="post">
+<table width="100%" cellspacing=0 cellpadding=5 class="adminEditTable">
+ <tr valign="top">
+ <td align="right"><b>(*) Name:</b></td>
+ <td><input type="text" name="name" value="#form.name#" size="50"></td>
+ </tr>
+ <tr valign="top">
+ <td align="right"><b>(*) Handler Root:</b></td>
+ <td><input type="text" name="handlerRoot" value="#form.handlerRoot#" size="50"></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td><input type="submit" name="save" value="Save"> <input type="submit" name="cancel" value="Cancel"></td>
+ </tr>
+</table>
+</form>
+</p>
+</cfoutput>
+
+</tags:layout>
+
+<cfsetting enablecfoutputonly=false>
476 admin/stats.cfm
@@ -0,0 +1,476 @@
+<cfsetting enablecfoutputonly=true showdebugoutput=false>
+<!---
+ Name : stats.cfm
+ Author : Raymond Camden
+ Created : September 6, 2004
+ Last Updated : December 12, 2007
+ History : For some dumb reason, Excel output was commented out (rkc 8/26/05)
+ Support matrix (rkc 10/8/05)
+ Forgot some debug output (rkc 10/28/05)
+ Fixed ordering in matrix questions (rkc 2/11/06)
+ Fixed CFMX6 support (rkc 3/22/06)
+ tableprefix fix (rkc 3/30/06)
+ fix for excel link, and add pdf link (rkc 12/12/07)
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<!--- Is this a mx7 box? --->
+<cfif structKeyExists(getFunctionList(), "GetLocaleDisplayName")>
+ <cfset cfmx7 = true>
+<cfelse>
+ <cfset cfmx7 = false>
+</cfif>
+
+<cfif isDefined("url.surveyidfk")>
+ <cfset form.surveyidfk = url.surveyidfk>
+</cfif>
+<cfparam name="form.surveyidfk" default="">
+
+<cfif isDefined("url.format")>
+ <cfset form.format = url.format>
+</cfif>
+
+<cfif form.surveyidfk is "">
+
+ <tags:layout templatename="admin" title="Survey Stats and Reports" loadspry="true">
+
+ <!--- get surveys --->
+ <cfif not request.pSession.user.isAdmin>
+ <cfset surveys = request.pApp.survey.getSurveys(useridfk=request.pSession.user.id)>
+ <cfelse>
+ <cfset surveys = request.pApp.survey.getSurveys()>
+ </cfif>
+
+
+ <cfif surveys.recordCount gte 1>
+
+ <cfoutput>
+ <script>
+ var dsQuestions = new Spry.Data.XMLDataSet("", "/questions/question");
+
+ function getQuestions() {
+ var selq = Spry.$("selquestions");
+ if(!selq.checked) {
+ clearQuestions();
+ return;
+ }
+ surveydd = Spry.$("surveyidfk");
+ survey = surveydd.options[surveydd.selectedIndex].value;
+ dsQuestions.setURL("xml.questions.cfm?survey="+survey);
+ dsQuestions.loadData();
+ }
+
+ function clearQuestions() {
+ var q = Spry.$("questionlist");
+ q.innerHTML = '';
+ }
+ </script>
+ <p>
+ <form action="#cgi.script_name#" method="post" name="surveys">
+ <table>
+ <tr>
+ <td>Select a Survey</td>
+ <td>
+ <select name="surveyidfk" id="surveyidfk">
+ <cfloop query="surveys">
+ <option value="#id#" <cfif id is form.surveyidfk>selected</cfif>>#name#</option>
+ </cfloop>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>Format</td>
+ <td>
+ <select name="format">
+ <option value="html">HTML</option>
+ <option value="excel">Excel</option>
+ <option value="pdf">PDF</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>Earliest Date:</td>
+ <td><input type="text" name="earliestdate" /></td>
+ </tr>
+ <tr>
+ <td>Latest Date:</td>
+ <td><input type="text" name="latestdate" /></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td><input type="submit" value="Generate"></td>
+ </tr>
+ </table>
+ <input type="checkbox" id="selquestions" value="selectquestions" onclick="getQuestions()">Select Questions:
+ <div id="questionlist" spry:region="dsQuestions">
+ <ul>
+ <div spry:repeat="dsQuestions">
+ <input type="checkbox" name="questionfilter" value="{ID}"><span spry:content="{QUESTION}"></span><br />
+ </div>
+ </ul>
+ </div>
+ </form>
+ </p>
+ </cfoutput>
+
+ <cfelse>
+
+ <cfoutput>
+ <p>
+ You do not have any surveys available to report on.
+ </p>
+ </cfoutput>
+
+ </cfif>
+
+ </tags:layout>
+
+<!--- begin report handling --->
+<cfelse>
+
+ <!--- get survey security check --->
+ <cfif not request.pSession.user.isAdmin>
+ <cfset survey = request.pApp.survey.getSurvey(form.surveyidfk, request.pSession.user.id)>
+ </cfif>
+
+ <!--- handle questions and possible filter --->
+ <cfset questions = request.pApp.question.getQuestions(form.surveyidfk)>
+
+ <cfparam name="url.earliestdate" default="">
+ <cfparam name="url.latestdate" default="">
+ <cfparam name="form.earliestdate" default="#url.earliestdate#">
+ <cfparam name="form.latestdate" default="#url.latestdate#">
+
+ <cfif not isDate(form.earliestdate)>
+ <cfset form.earliestdate = "">
+ </cfif>
+ <cfif not isDate(form.latestdate)>
+ <cfset form.latestdate = "">
+ </cfif>
+
+ <cfif structKeyExists(form, "questionfilter") and len(form.questionfilter)>
+ <cfquery name="questions" dbtype="query">
+ select *
+ from questions
+ where id in (<cfqueryparam cfsqltype="cf_sql_varchar" value="#form.questionfilter#" list="true">)
+ </cfquery>
+ </cfif>
+
+
+ <!--- html --->
+ <cfif form.format is "html">
+
+ <!--- Begin Stat Display --->
+ <cfset survey = request.pApp.survey.getSurvey(form.surveyidfk)>
+ <cfset stats = request.pApp.survey.getStats(form.surveyidfk,form.earliestdate,form.latestdate)>
+
+ <cfset title = "Stats for #survey.name#">
+ <cfif isDate(form.earliestdate) or isDate(form.latestdate)>
+ <cfset title = title & " (Restricted to ">
+ <cfif isDate(form.earliestdate)>
+ <cfset title = title & "results after #dateFormat(form.earliestdate)# ">
+ </cfif>
+ <cfif isDate(form.earliestdate) and isDate(form.latestdate)>
+ <cfset title = title & " and ">
+ </cfif>
+ <cfif isDate(form.latestdate)>
+ <cfset title = title & "results before #dateFormat(form.latestdate)#">
+ </cfif>
+ <cfset title = title & ")">
+ </cfif>
+
+ <tags:layout templatename="admin" title="#title#">
+
+ <cfoutput>
+
+ <script>
+ function popup(loc) {
+ theWin = window.open(loc,'theWin','width=600,height=600,scrollbars=1');
+ theWin.focus();
+ }
+ </script>
+
+ <p>
+ <table cellspacing=0 cellpadding=5 class="adminListTable" width="600">
+ <tr class="adminListHeader">
+ <td colspan="2">General Stats</td>
+ </tr>
+ <tr>
+ <td><b>Total Number of Survey Results</b></td>
+ <td>#stats.totalresults#</td>
+ </tr>
+ <tr>
+ <td><b>First Result</b></td>
+ <td>#dateFormat(stats.firstresult,"m/dd/yy")# #timeFormat(stats.firstresult,"h:mm tt")#&nbsp;</td>
+ </tr>
+ <tr>
+ <td><b>Last Result</b></td>
+ <td>#dateFormat(stats.lastresult,"m/dd/yy")# #timeFormat(stats.lastresult,"h:mm tt")#&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <a href="#cgi.script_name#?surveyidfk=#form.surveyidfk#&earliestdate=#form.earliestdate#&latestdate=#form.latestdate#&format=excel">Excel Report</a> / <a href="#cgi.script_name#?surveyidfk=#form.surveyidfk#&earliestdate=#form.earliestdate#&latestdate=#form.latestdate#&&format=pdf">PDF Report</a>
+ </td>
+ </tr>
+ </table>
+ </p>
+ </cfoutput>
+
+ <cfset colorList = "##E48701,##A5BC4E,##1B95D9,##CACA9E,##6693B0,##F05E27,##86D1E4,##E4F9A0,##FFD512,##75B000,##0662B0">
+ <cfset currentColorIndex = 1>
+
+ <cfloop query="questions">
+
+ <!--- fire stats handler for qt --->
+ <cfmodule template="../handlers/#handlerRoot#/stats.cfm"
+ surveyidfk="#form.surveyidfk#"
+ questionidfk="#id#"
+ r_data="data"
+ earliestDate="#form.earliestDate#"
+ latestDate="#form.latestDate#"
+ />
+
+ <cfif isStruct(data) and questiontype is not "matrix">
+ <!--- get max data --->
+ <cfset max = 1>
+ <cfloop item="key" collection="#data#">
+ <cfif data[key] gt max>
+ <cfset max = data[key]>
+ </cfif>
+ </cfloop>
+ </cfif>
+
+ <cfset currentColor = listGetAt(colorList, currentColorIndex)>
+ <cfoutput>
+ <p>
+ <table cellspacing=0 cellpadding=5 class="adminListTable" width="600">
+ <tr class="adminListHeader">
+ <td colspan="2">
+ #currentRow#. #question# (#questiontype#)
+ <cfif not required>
+ <cfset total = "">
+ <cfswitch expression="#questiontype#">
+ <cfcase value="Multiple Choice (Single Selection),Multiple Choice (Multiple Selection)">
+ <cfset total = 0>
+ <cfloop item="k" collection="#data#">
+ <cfset total = total + data[k]>
+ </cfloop>
+ </cfcase>
+ <cfcase value="Matrix">
+ <cfset total = data.realTotal>
+ </cfcase>
+ <cfcase value="Text Box (Single),Text Box (Multi)">
+ <cfset total = data.recordCount>
+ </cfcase>
+ <cfcase value="True/False,Yes/No">
+ <cfset total = data.true + data.false>
+ </cfcase>
+ </cfswitch>
+
+ <cfif isNumeric(total) and stats.totalresults gt 0>
+ <cfset perc = total/stats.totalresults*100>
+ (Response Rate: #numberFormat(perc,0.0)#%)
+ </cfif>
+ </cfif>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <cfswitch expression="#questiontype#">
+
+ <cfcase value="true/false,yes/no">
+ <cfif questiontype is "true/false">
+ <cfset t = "True">
+ <cfset f = "False">
+ <cfelse>
+ <cfset t = "Yes">
+ <cfset f = "No">
+ </cfif>
+ <cfif cfmx7>
+ <cfinclude template="stats_pie.cfm">
+ <cfelse>
+ <!---<cfchart format="flash" chartWidth="575" chartHeight="575"
+ rotated="yes" gridLines="#max+1#" show3d="true">--->
+ <cfchart format="flash" chartWidth="575" chartHeight="575"
+ gridLines="#max+1#" show3d="true">
+ <cfchartseries type="pie" paintStyle="raise" seriesColor="#currentColor#" dataLabelStyle="pattern">
+ <cfchartdata item="#f#" value="#data.false#">
+ <cfchartdata item="#t#" value="#data.true#">
+ </cfchartseries>
+ </cfchart>
+ </cfif>
+ <cfset currentColorIndex = currentColorIndex + 1>
+ </cfcase>
+
+ <cfcase value="multiple choice (single selection),Multiple Choice (Multi Selection) with Other,Multiple Choice (Single Selection) with Other,Multiple Choice (Multi Selection)">
+ <cfset answers = request.pApp.question.getAnswers(id)>
+
+ <cfif cfmx7>
+
+ <cfinclude template="stats_mc.cfm">
+
+ <cfelse>
+
+ <!---<cfchart format="flash" chartWidth="575" chartHeight="575"
+ rotated="yes" gridlines="#max+1#" scaleFrom="0">--->
+ <cfchart format="flash" chartWidth="575" chartHeight="575"
+ gridlines="#max+1#" scaleFrom="0">
+ <cfchartseries type="bar" paintStyle="raise" seriesColor="#currentColor#">
+ <cfif structKeyExists(data,"other")>
+ <cfchartdata item="Other" value="#data.other#">
+ </cfif>
+ <cfloop query="answers">
+ <cfchartdata item="#answer#" value="#data[id]#">
+ </cfloop>
+ </cfchartseries>
+ <cfset currentColorIndex = currentColorIndex + 1>
+ </cfchart>
+
+ </cfif>
+
+ <cfif findNoCase("other",questiontype)>
+ <cfoutput>
+ <p>
+ <a href="javascript:popup('otherviewer.cfm?questionidfk=#id#&earliestdate=#form.earliestdate#&latestdate=#form.latestdate#')">View Other Results</a>
+ </p>
+ </cfoutput>
+ </cfif>
+
+ </cfcase>
+
+ <cfcase value="text box (single),text box (multi)">
+ <cfoutput>
+ <a href="javascript:popup('textviewer.cfm?questionidfk=#id#&earliestdate=#form.earliestdate#&latestdate=#form.latestdate#')">View Answers</a>
+ </cfoutput>
+ </cfcase>
+
+ <cfcase value="matrix">
+
+ <cfset sortedAnswers = data.sortedAnswers>
+ <cfset structDelete(data, "sortedAnswers")>
+ <cfset sortedItems = data.sortedItems>
+ <cfset structDelete(data, "sortedItems")>
+ <cfset structDelete(data, "realTotal")>
+ <cfif cfmx7>
+
+ <cfinclude template="stats_matrix.cfm">
+
+ <cfelse>
+
+ <!---<cfchart format="flash" chartWidth="575" chartHeight="575" rotated="yes" show3d=true showLegend=true>--->
+ <cfchart format="flash" chartWidth="575" chartHeight="575" show3d=true showLegend=true>
+ <cfloop list="#sortedItems#" index="item">
+ <cfset label = data[item].label>
+ <cfchartseries type="bar" paintStyle="raise" seriesColor="#currentColor#" seriesLabel="#label#">
+ <cfloop list="#sortedAnswers#" index="v">
+ <cfif v is not "label">
+ <cfchartdata item="#data[item][v].label#" value="#data[item][v].count#">
+ </cfif>
+ </cfloop>
+ </cfchartseries>
+ <cfset currentColorIndex = currentColorIndex + 1>
+ <cfif currentColorIndex gt listLen(colorList)>
+ <cfset currentColorIndex = 1>
+ </cfif>
+ <cfset currentColor = listGetAt(colorList, currentColorIndex)>
+ </cfloop>
+ </cfchart>
+
+ </cfif>
+
+ <cfset currentColorIndex = currentColorIndex + 1>
+ </cfcase>
+
+ <cfdefaultcase>
+ <!--- This should not happen --->
+ </cfdefaultcase>
+
+ </cfswitch>
+
+ <cfif currentColorIndex gt listLen(colorList)>
+ <cfset currentColorIndex = 1>
+ </cfif>
+
+ </td>
+ </tr>
+ </table>
+ </p>
+ </cfoutput>
+ </cfloop>
+
+ </tags:layout>
+
+ <!--- handles both excel and pdf --->
+ <cfelse>
+
+ <!---
+ Excel Generation
+ It's like the Pepsi Generation - but not as cool. And not in a can.
+
+ So, I'm going to use queries here. Normally I'd do everything via the CFC.
+ This is so special though I think it may make more sense here.
+ Then again, I may just be lazy.
+ But does anyone actually even look at the source code?
+ I doubt it.
+ Either way.
+ Just know I really wanted to put this in the CFC.
+ I feel really bad about it.
+ But I'll live.
+ --->
+
+ <!--- step one. get all users who responded --->
+ <cfquery name="getSurveyTakers" datasource="# request.pApp.settings.dsn#">
+ select ownerid, completed
+ from # request.pApp.settings.tableprefix#survey_results
+ where surveyidfk = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" maxlength="35" value="#form.surveyidfk#">
+ <cfif isDate(form.earliestdate)>
+ and completed >= <cfqueryparam cfsqltype="cf_sql_date" value="#form.earliestdate#">
+ </cfif>
+ <cfif isDate(form.latestdate)>
+ and completed <= <cfqueryparam cfsqltype="cf_sql_date" value="#form.latestdate#">
+ </cfif>
+
+ </cfquery>
+
+ <!--- output headers for excel --->
+ <cfsavecontent variable="report">
+ <cfoutput><table border="1" width="100%"></cfoutput>
+
+ <cfoutput><tr><td>Survey Taker ID</td><td>Survey Taken</td><cfloop query="questions"><td>#question#</td></cfloop></tr></cfoutput>
+
+ <cfloop query="getSurveyTakers">
+
+ <cfset answerRow = "">
+ <cfset oid = ownerid>
+ <cfloop query="questions">
+ <cfset answerRow = answerRow & "<td>" & htmlEditFormat( request.pApp.survey.getAnswerResult(id,oid)) & "</td>">
+ </cfloop>
+
+ <cfoutput><tr><td>#ownerid#</td><td>#dateFormat(completed,"mm/dd/yy")# #timeFormat(completed,"h:mm tt")#</td>#answerRow#</tr></cfoutput>
+ </cfloop>
+
+ <cfoutput></table></cfoutput>
+ </cfsavecontent>
+
+
+ <cfif form.format is "excel">
+ <cfcontent type="application/msexcel">
+ <cfheader name="content-disposition" value="attachment;filename=report.xls">
+ <cfoutput>#report#</cfoutput>
+ <cfabort>
+ </cfif>
+
+ <cfif form.format is "pdf">
+ <cfcontent type="application/pdf">
+ <cfheader name="content-disposition" value="attachment;filename=report.pdf">
+ <cfdocument format="pdf" orientation="landscape">
+ <cfoutput>#report#</cfoutput>
+ </cfdocument>
+ </cfif>
+
+ </cfif>
+
+</cfif>
+
+<cfsetting enablecfoutputonly=false>
28 admin/stats_matrix.cfm
@@ -0,0 +1,28 @@
+<!---
+ Name : C:\projects\soundings\wwwroot\soundings\admin\stats_matrix.cfm
+ Author : Raymond Camden
+ Created : 03/02/06
+ Last Updated :
+ History :
+--->
+
+
+<cfchart format="flash" chartWidth="575" chartHeight="575" show3d=true showLegend=true style="style.xml">
+<!---<cfchart format="flash" chartWidth="575" chartHeight="575" rotated="yes" show3d=true showLegend=true style="style.xml">--->
+<cfloop list="#sortedItems#" index="item">
+ <cfset label = data[item].label>
+ <cfchartseries type="bar" paintStyle="raise" seriesColor="#currentColor#" seriesLabel="#label#">
+ <cfloop list="#sortedAnswers#" index="v">
+ <cfif v is not "label">
+ <cfchartdata item="#data[item][v].label#" value="#data[item][v].count#">
+ </cfif>
+ </cfloop>
+ </cfchartseries>
+ <cfset currentColorIndex = currentColorIndex + 1>
+ <cfif currentColorIndex gt listLen(colorList)>
+ <cfset currentColorIndex = 1>
+ </cfif>
+ <cfset currentColor = listGetAt(colorList, currentColorIndex)>
+</cfloop>
+</cfchart>
+
21 admin/stats_mc.cfm
@@ -0,0 +1,21 @@
+<!---
+ Name : C:\projects\soundings\wwwroot\soundings\admin\stats_mc.cfm
+ Author : Raymond Camden
+ Created : 03/02/06
+ Last Updated :
+ History :
+ style="style.xml"
+--->
+
+<cfchart format="flash" chartWidth="575" chartHeight="575"
+ gridlines="#max+1#" style="style.xml" scaleFrom="0">
+ <cfchartseries type="bar" paintStyle="raise" seriesColor="#currentColor#">
+ <cfif structKeyExists(data,"other")>
+ <cfchartdata item="Other" value="#data.other#">
+ </cfif>
+ <cfloop query="answers">
+ <cfchartdata item="#answer#" value="#data[id]#">
+ </cfloop>
+ </cfchartseries>
+ <cfset currentColorIndex = currentColorIndex + 1>
+</cfchart>
9 admin/stats_pie.cfm
@@ -0,0 +1,9 @@
+
+
+<cfchart format="flash" chartWidth="575" chartHeight="575"
+ show3d="true" style="style_pie.xml">
+ <cfchartseries type="pie" paintStyle="raise" seriesColor="#currentColor#">
+ <cfchartdata item="#f#" value="#data.false#">
+ <cfchartdata item="#t#" value="#data.true#">
+ </cfchartseries>
+</cfchart>
12 admin/style.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<frameChart>
+<xAxis>
+ <labelStyle isHideOverlapped="false" orientation="Vertical"/>
+</xAxis>
+<legend placement="Top" equalCols="false">
+<![CDATA[
+$(colLabel) [$(value) or $(colPercent)]
+]]>
+</legend>
+<paint palette="Modern" paint="Plain" isVertical="true" min="47" max="83"/>
+</frameChart>
9 admin/style_pie.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pieChart style="Solid">
+<legend placement="Top" equalCols="false">
+<![CDATA[
+$(colLabel) ($(value)/$(colPercent))
+]]>
+</legend>
+<paint palette="Modern" paint="Plain" min="44" max="95"/>
+</pieChart>
54 admin/surveys.cfm
@@ -0,0 +1,54 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : surveys.cfm
+ Author : Raymond Camden
+ Created : September 6, 2004
+ Last Updated : December 12, 2007
+ History : Added a quick way to go to questions (rkc 11/14/07)
+ Typo in table header (rkc 12/12/07)
+ Purpose :
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<tags:layout templatename="admin" title="Survey Editor">
+
+ <!--- handle deletions --->
+ <cfif isDefined("form.mark") and len(form.mark)>
+ <cfloop index="id" list="#form.mark#">
+ <cfset request.pApp.survey.deleteSurvey(id)>
+ </cfloop>
+ <cfoutput>
+ <p>
+ <b>Survey(s) deleted.</b>
+ </p>
+ </cfoutput>
+ </cfif>
+
+ <!--- get surveys --->
+ <cfif not request.pSession.user.isAdmin>
+ <cfset surveys = request.pApp.survey.getSurveys(useridfk=request.pSession.user.id)>
+ <cfelse>
+ <cfset surveys = request.pApp.survey.getSurveys()>
+ </cfif>
+
+ <cfset queryAddColumn(surveys, "questions", arrayNew(1))>
+ <cfloop query="surveys">
+ <cfset querySetCell(surveys, "questions", "<a href='questions.cfm?surveyidfk=#id#'>Questions</a>", currentRow)>
+ </cfloop>
+
+ <tags:datatable data="#surveys#" list="name,description,active" editlink="surveys_edit.cfm" linkcol="name" label="Survey"
+ deleteMsg="Warning - this will delete the survey including all related questions and responses.">
+ <tags:datacol colname="name" label="Name" width="200" />
+ <tags:datacol colname="description" label="Description" width="400" />
+ <cfif request.pSession.user.isAdmin>
+ <tags:datacol colname="username" label="User" width="100" />
+ </cfif>
+ <tags:datacol colname="active" label="Active" width="50" format="YesNo" />
+ <tags:datacol colname="totalresults" label="Results" width="50" />
+ <tags:datacol colname="questions" label="Questions" width="50" />
+
+ </tags:datatable>
+
+</tags:layout>
+
+<cfsetting enablecfoutputonly=false>
386 admin/surveys_edit.cfm
@@ -0,0 +1,386 @@
+<cfsetting enablecfoutputonly=true>
+<!---
+ Name : survey_edit.cfm
+ Author : Raymond Camden
+ Created : September 7, 2004
+ Last Updated : March 30, 2006
+ History : support for clearing results (rkc 3/30/06)
+--->
+<cfimport taglib="../tags/" prefix="tags">
+
+<cfif isDefined("form.cancel") or not isDefined("url.id")>
+ <cflocation url="surveys.cfm" addToken="false">
+</cfif>
+
+<cfif isDefined("form.save")>
+ <cfset form = request.udf.cleanStruct(form,"thankyoumsg")>
+ <cfset errors = "">
+ <cfif not len(form.name)>
+ <cfset errors = errors & "You must specify a name.<br>">
+ </cfif>
+ <cfif not len(form.description)>
+ <cfset errors = errors & "You must specify a description.<br>">
+ </cfif>
+ <cfif len(form.dateBegin) and not isDate(form.dateBegin)>
+ <cfset errors = errors & "If you specify a survey starting date, it must be a valid date.<br>">
+ <cfset form.dateBegin = "">
+ </cfif>
+ <cfif len(form.dateEnd) and not isDate(form.dateEnd)>
+ <cfset errors = errors & "If you specify a survey ending date, it must be a valid date.<br>">
+ <cfset form.dateEnd = "">
+ </cfif>
+ <cfif len(form.dateBegin) and isDate(form.dateBegin) and len(form.dateEnd) and isDate(form.dateEnd)
+ and dateCompare(form.dateBegin,form.dateEnd,"s") gte 0>
+ <cfset errors = errors & "If you specify a survey starting and ending date, the start date must be before the ending date.<br>">
+ </cfif>
+ <cfif len(form.resultMailTo)>
+ <cfloop index="e" list="#form.resultMailTo#">
+ <cfif not isValid("email", e)>
+ <cfset errors = errors & "The value to send results to must be a valid email address or a list of valid email addresses. #e# is not valid.<br>">
+ </cfif>
+ </cfloop>
+ </cfif>
+ <cfif len(form.questionsperpage) and (
+ not isNumeric(form.questionsperpage)
+ or
+ form.questionsperpage lte 0
+ )>
+ <cfset errors = errors & "The value for questions per page must be numeric and positive.<br/>">
+ </cfif>
+ <cfif form.active>
+ <cfif url.id eq 0>
+ <cfset errors = errors & "A new survey cannot be active. You must first add questions.<br>">
+ <cfelse>
+ <!--- get questions --->
+ <cfset q = request.pApp.question.getQuestions(url.id)>
+ <cfif q.recordCount is 0>
+ <cfset errors = errors & "This survey cannot be marked active until questions are added.<br>">
+ </cfif>
+ </cfif>
+ </cfif>
+
+ <!--- Nuke the old list --->
+ <cfif isDefined("form.nukeEL")>
+ <cfset request.pApp.survey.resetEmailList(url.id)>
+ </cfif>
+
+ <cfif not len(errors)>
+
+ <cfset data = structNew()>
+ <cfset data.name = form.name>
+ <cfset data.description = form.description>
+ <cfset data.active = form.active>
+ <cfif isDate(form.dateBegin)>
+ <cfset data.dateBegin = form.dateBegin>
+ </cfif>
+ <cfif isDate(form.dateEnd)>
+ <cfset data.dateEnd = form.dateEnd>
+ </cfif>
+ <cfset data.resultMailTo = form.resultMailTo>
+ <cfset data.surveyPassword = form.surveyPassword>
+ <cfset data.thankYouMsg = form.thankYouMsg>
+
+ <cfset data.templateidfk = form.templateidfk>
+ <cfset data.allowembed = form.allowembed>
+ <cfset data.showinpubliclist = form.showinpubliclist>
+ <cfif form.questionsperpage neq "">
+ <cfset data.questionsperpage = form.questionsperpage>
+ </cfif>
+
+ <cfif url.id neq 0>
+ <cfset data.id = url.id>
+ <cfset request.pApp.survey.updateSurvey(argumentCollection=data)>
+ <cfelse>
+ <cfset data.useridfk = request.pSession.user.id>
+ <cfset url.id = request.pApp.survey.addSurvey(argumentCollection=data)>
+ </cfif>
+
+ <cfif len(trim(form.emailList))>
+ <cfset emails = arrayNew(1)>
+ <cffile action="UPLOAD" filefield="form.emailList" destination="#expandPath("./uploads")#" nameconflict="MAKEUNIQUE">
+ <cfset theFile = cffile.serverDirectory & "/" & cffile.serverFile>
+ <cffile action="read" file="#theFile#" variable="buffer">
+ <!--- attempt to read the buffer --->
+ <cfloop index="line" list="#buffer#" delimiters="#chr(10)#">
+ <cfif len(trim(line)) and request.udf.isEmail(trim(line))>
+ <cfset arrayAppend(emails, trim(line))>
+ </cfif>
+ </cfloop>
+ <cfset request.pApp.survey.resetEmailList(url.id)>
+ <cfif arrayLen(emails)>
+ <cfset request.pApp.survey.addEmailList(url.id,emails)>
+ </cfif>
+ <!--- cleanup --->
+ <cffile action="delete" file="#theFile#">
+ </cfif>
+
+ <cfset msg = "Survey, #form.name#, has been updated.">
+ <cflocation url="surveys.cfm?msg=#urlEncodedFormat(msg)#">
+ </cfif>
+</cfif>
+
+<cfif isDefined("form.dupe") and url.id neq 0>
+ <cfset request.pApp.survey.duplicateSurvey(url.id)>
+ <cfset msg = "Survey, #form.name#, has been duplicated.">
+ <cflocation url="surveys.cfm?msg=#urlEncodedFormat(msg)#">
+</cfif>
+
+<cfif isDefined("form.clear") and url.id neq 0>
+ <cfset request.pApp.survey.clearResults(url.id)>
+ <cfset msg = "Survey, #form.name#, has had its results cleared.">
+ <cflocation url="surveys.cfm?msg=#urlEncodedFormat(msg)#">
+</cfif>
+
+<!--- get survey if not new --->
+<cfif url.id neq 0>
+ <cfif not request.pSession.user.isAdmin>
+ <cfset survey = request.pApp.survey.getSurvey(url.id, request.pSession.user.id)>
+ <cfelse>
+ <cfset survey = request.pApp.survey.getSurvey(url.id)>
+ </cfif>
+ <!--- get the templates based on the survey owner, which may not be me if I'm a admin --->
+ <cfset templates = request.pApp.template.getTemplates(survey.useridfk)>
+ <cfset emailList = request.pApp.survey.getEmailList(url.id)>
+ <cfparam name="form.name" default="#survey.name#">
+ <cfparam name="form.description" default="#survey.description#">
+ <cfparam name="form.active" default="#survey.active#">
+ <cfparam name="form.dateBegin" default="#survey.dateBegin#">
+ <cfparam name="form.dateEnd" default="#survey.dateEnd#">
+ <cfparam name="form.resultMailTo" default="#survey.resultMailTo#">
+ <cfparam name="form.surveyPassword" default="#survey.surveyPassword#">
+ <cfparam name="form.thankYouMsg" default="#survey.thankYouMsg#">
+ <cfparam name="form.templateidfk" default="#survey.templateidfk#">
+ <cfparam name="form.allowembed" default="#survey.allowembed#">
+ <cfparam name="form.showinpubliclist" default="#survey.showinpubliclist#">
+ <cfparam name="form.questionsperpage" default="#survey.questionsperpage#">
+<cfelse>
+ <cfparam name="form.name" default="">
+ <cfparam name="form.description" default="">
+ <cfparam name="form.active" default="false">
+ <cfparam name="form.dateBegin" default="">
+ <cfparam name="form.dateEnd" default="">
+ <cfparam name="form.resultMailTo" default="">
+ <cfparam name="form.surveyPassword" default="">
+ <cfparam name="form.thankYouMsg" default="">
+ <cfparam name="form.templateidfk" default="">
+ <cfparam name="form.allowembed" default="">
+ <cfparam name="form.showinpubliclist" default="">
+ <cfparam name="form.questionsperpage" default="">
+ <cfset templates = request.pApp.template.getTemplates(request.pSession.user.id)>
+</cfif>
+
+<tags:layout templatename="admin" title="Survey Editor">
+
+<cfoutput>
+<script>
+function viewEmailList() {
+ window.open("viewemaillist.cfm?id=#url.id#","viewEmailList","width=500,height=600");
+}
+</script>
+
+<p>
+Please use the form below to enter details about the survey. All required fields are marked (*). The values
+for date survey begins and ends allows you to restrict by date when surveys can be answered. If a survey password
+is set, then it must be provided before the user can take the survey.
+</p>
+
+<cfif structKeyExists(variables, "survey") and survey.active>
+ <!--- create a link to index.cfm --->
+ <cfset rootURL = cgi.script_name>
+ <cfset rootURL = listDeleteAt(rootURL, listLen(rootURL, "/"), "/")>
+ <!--- pop out one more --->
+ <cfset rootURL = listDeleteAt(rootURL, listLen(rootURL, "/"), "/")>
+ <!--- now add root server --->