欢迎光临
我们一直在努力

用ASP技术开发WEB调查(投票)系统 (2)-ASP教程,ASP应用

建站超值云服务器,限时71元/月

二、调查项目的创建和维护
  作 者 : 仙人掌工作室
  
     本节我们说明调查项目创建和维护功能的实现。
  
     创建与维护调查项目的起始页面是startup.html,该页面负责设定pollmaker.asp和itemmaker.asp等页面使用的帧结构(从上到下共分三个帧)。起始页面所引用的blank.html只用于指定背景颜色,startmsg.html提供启动时显示在最下面帧的提示信息。
  
     pollmaker.asp和itemmaker.asp都包含运行于服务器的asp脚本,同时也包含(和创建)浏览器脚本以支持客户端操作。运行于服务器的脚本由vbscript写成,而客户端脚本则是javascript,这使得它既可以运行于netscape navigator,也适合于ie。
  
     pollmaker.asp通过查找poll数据库的msysobjects系统表获得已经定义的调查项目名字。因此,asp应用必须具有读取该表的权限。在access97中的设定方法是:先选择菜单“工具/选项”设置系统对象可见,然后在“工具/安全/用户与组的权限”下设定。在本文所附代码中poll.mdb已经设置了这个权限。如果要在不同的rdbms上实现这个调查系统,这部分代码必须改写,使它适应目标数据库上的系统表结构。
  
     要将这些已定义的调查项目名字显示到下拉列表框,首先需要从s_表的表名中除去“s_”前缀,然后将这些字符串格式化为< select>元素的< option>字符串:
  
   
   < select name=”pollname”>
   < option value=”startpoll” selected>new poll
   < %
    获取当前已经定义的调查项目名字
    set objconn = server.createobject(“adodb.connection”)
    objconn.open “poll”
    set objrs = _
    objconn.execute(“select name from msysobjects ” & _
    “where type=1 and name like s_% order by name”)
    do while not objrs.eof
    pollname = mid(objrs(“name”), 3)
    response.write(“< option value=””” & pollname & “””>” & pollname)
    objrs.movenext
    loop
   %>
   < /select>
  
     itemmaker将指定调查项目的所有定义信息下载到浏览器端的javascript数组中,从而实现问题的快速编辑和创建。所有的问题编辑操作都在浏览器内通过修改两个javascript数组完成,只有单击“保存” 按钮才可将修改结果写入数据库。
  
     itemmaker.asp首先将response.buffer设置为true,因此在页面生成完成之前html输出将一直缓冲在服务器上,这使得产生错误或执行非编辑功能时itemmaker.asp可以不下载那些javascript函数而退出。在sub main的开始处,程序通过检查表单变量optype来决定是创建新的调查项目,还是删除调查项目或调查结果。这三个操作均在itemmaker.asp内完成,即所有受密码保护的功能均在同一脚本内实现,这使得整个系统中密码只在一个地方存取。上述三个操作均需动态地生成与执行sql语句。不论是脚本执行出现错误,还是指定的操作执行成功,都调用response.redirect语句重新加载pollmaker.asp,并把一个说明字符串传递给它:
  
   
   < %
   dim pollname
   dim password
   dim objconn
   dim objrs
   
   pollname = request(“pollname”)
   password = ucase(request(“password”))
   optype = request(“optype”) 要求itemmaker.asp执行的操作
   
   sname = “[s_” & pollname & “]”
   aname = “[a_” & pollname & “]”
   rname = “[r_” & pollname & “]”
   call main
   sub main
   if password < > “webpoll” then 如密码错误返回pollmaker.asp并提示
    response.redirect “pollmaker.asp?msg=密码错误,请再试一次。”
    exit sub 从itemmaker.asp返回
   end if
   if optype = “edit” then 编辑或创建调查调查项目
    if pollname = “startpoll” then
    if not newpoll() then 用户没有给出调查项目的名字
    response.redirect “pollmaker.asp?msg=请输入调查项目名字”
    exit sub
    end if
    sname = “[s_” & pollname & “]”
    aname = “[a_” & pollname & “]”
    rname = “[r_” & pollname & “]”
    end if
   elseif optype = “delresp” then 删除调查项目的已有结果
    if pollname = “startpoll” then
    response.redirect “pollmaker.asp?msg=请输入调查项目名字”
    exit sub
    end if
    set objconn = server.createobject(“adodb.connection”)
    objconn.open “poll”
    set objrs = server.createobject(“adodb.recordset”)
    objconn.execute “delete from ” & rname
    response.redirect “pollmaker.asp?msg=已经删除指定调查项目的投票结果”
   elseif optype = “delpoll” then 删除整个调查项目
    if pollname = “startpoll” then
    response.redirect “pollmaker.asp?msg=不能删除新调查项目”
    exit sub
    end if
    set objconn = server.createobject(“adodb.connection”)
    objconn.open “poll”
    set objrs = server.createobject(“adodb.recordset”)
    objconn.execute “drop table ” & sname
    objconn.execute “drop table ” & aname
    objconn.execute “drop table ” & rname
    response.redirect “pollmaker.asp?msg=已经删除指定的调查项目。”
   end if
   %>
  
  
     在运行itemmaker.asp编辑调查项目时,程序提取poll数据库中定义的调查项目及其问题定义数据初始化数组stemarray[]和ansarray[]。这些用来初始化的字符串在写入时经过“转义”处理(即调用escape()函数),从而避免了由于嵌入的引号或其它控制字符可能导致的问题,在使用这些数组之前这些字符串被还原(initpoll()函数):
  
  
   
   < script language=”javascript”>
   var stemix = 0;
   var inumber;
   var noopinion;
   
   // 初始化数组stemarray[]与ansarray[]
   var stemarray = new array(
   < %
   set objconn = server.createobject(“adodb.connection”)
   objconn.open “poll”
   set objrs = server.createobject(“adodb.recordset”)
    从数据库读取数组内容
   objrs.open “select * from ” & sname & ” order by id”, objconn
   do while not objrs.eof
    转换问题与回答字符串以允许使用所有字符
    stemstr = escape(objrs(“stem”))
    response.write(“””” & objrs(“id”) & objrs(“itype”) & _
    left(objrs(“noopinion”),1) & stemstr & “”””)
    objrs.movenext
    if not objrs.eof then
    response.write(“,”)
    end if
   loop
   objrs.close
   %>
   );
   var ansarray = new array(
   < %
    从数据库读取数组内容
   objrs.open “select * from ” & aname & ” order by id, alabel”, objconn
   do while not objrs.eof
    ansstr = escape(objrs(“answer”))
    response.write(“””” & objrs(“id”) & objrs(“alabel”) & ansstr & “”””)
    objrs.movenext
    if not objrs.eof then
    response.write(“,”)
    end if
   loop
   objrs.close
   objconn.close
   %>
   );
   
   // 初始化
   function initpoll() {
    writemsgframe(< html>< body bgcolor=”#c0c0c0″> +
    < center>已经读取或创建调查项目”< %=pollname%>” +
    < /center>< /body>< /html>);
    if (stemarray.length > 0) inumber = stemarray[0].substr(0,3);
    for (i=0; i< stemarray.length; i++) stemarray[i] = unescape(stemarray[i]);
    for (i=0; i< ansarray.length; i++) ansarray[i] = unescape(ansarray[i]);
    donav(“< “); // 显示第1个问题
   } // initpoll()
  
  
     如前所述,图2所显示的页面由三个帧构成。最上面的帧(controlframe)包含由itemmaker.asp输出的文档,其中大部分代码是用来支持浏览器内的编辑操作的javascript。这些代码通过动态生成html表单在位于中间的帧(itemframe)显示问题。在编辑问题的时候,编辑事件将触发保存更新数据到stemarray[]和ansarray[]数组的javascript函数。最下面的一个帧(msgframe)用来显示提示信息。
  
     javascript函数donew()在调查项目的最后加入新的问题,它先在stemarray[]的最后加入一行,然后在ansarray[]数组中加入对应于问题类型的合适行数,最后调用donav()函数显示这个问题:
  
  
   // 创建新问题并将它加入到调查项目的最后
   function donew() {
    stemlen = stemarray.length;
    inumber = (stemlen > 0) ?
    parseint(stemarray[stemlen-1].substr(0,3)) : 0;
    inumber = ” ” + (++inumber).tostring();
    inumber = inumber.substr(inumber.length-3, 3);
    for (itype = 0; itype < 5; itype++) {
    if(document.itemtype.itype[itype].checked) break;
    }
    itype++;
    noopinion =
    (document.itemtype.noopinion.checked) ? “y” : “n”;
    stemarray[stemlen] = inumber + itype + noopinion;
    if (itype > 3) acount = parseint(document.itemtype.nchoices.value);
    else if (itype == 3) acount = 2; // 语义区别
    else acount = 0;
    if (acount > 26) acount = 26;
    if (acount > 0) {
    j = ansarray.length;
    for (i=0; i< acount; i++)
    ansarray[j+i] = inumber + string.fromcharcode(65+i);
    }
    stemix = stemlen;
    donav(“”); // 显示空白的问题
   } // donew()
   
  
     domove()函数修改问题在调查项目中的位置(序号),它先将指定问题与答案在各自的数组中重新编号,然后将这两个数组排序:
  
  
   // 将问题移到指定位置之后
   function domove() {
    if (stemarray.length < = 0) return; // 没有已定义的问题
    id = stemarray[stemix].substr(0,3); // 要移动问题的id
    qtemp = document.itemtype.iafter.value; // 移到哪里
    if (qtemp >= 0 && qtemp < stemarray.length)
    nid = stemarray[qtemp].substr(0,3); // 被移动问题新的id
    else if (qtemp == stemarray.length)
    nid = stemarray[stemarray.length-1].substr(0,3);
    else return;
    minid = (id< nid) ? id : nid;
    maxid = (id< nid) ? nid : id;
    offset = (id< nid) ? -1 : 1; // 移动方向
    for (i=0; i< stemarray.length; i++) {
    thisid = stemarray[i].substr(0,3);
    if (thisid>=minid && thisid< =maxid) {
    if (thisid == id)
    stemarray[i] = nid + stemarray[i].substr(3);
    else {
    tempid = ” ” +
    (parseint(thisid) + offset).tostring();
    tempid = tempid.substr(tempid.length-3, 3);
    stemarray[i] = tempid + stemarray[i].substr(3);
    }
    }
    }
    stemarray.sort();
    for (i=0; i< ansarray.length; i++) {
    thisid = ansarray[i].substr(0,3);
    if (thisid>=minid && thisid< =maxid) {
    if (thisid == id)
    ansarray[i] = nid + ansarray[i].substr(3);
    else {
    tempid = ” ” +
    (parseint(thisid) + offset).tostring();
    tempid = tempid.substr(tempid.length-3, 3);
    ansarray[i] = tempid + ansarray[i].substr(3);
    }
    }
    }
    ansarray.sort();
    document.itemtype.inumber.value = nid;
    donav(“go->”); // 显示移动后的问题
   } // domove()
   
  
     dodelete()函数通过重新编号并压缩这两个数组实现问题的删除(将最后几行去掉):
  
  
   // 确认删除,然后在stemarray[]和ansarray[]中执行删除操作
   function dodelete() {
    if (confirm(“是否删除当前显示的问题?”)) {
    if (stemarray.length > 0) {
    id = stemarray[stemix].substr(0,3); // 被删除问题的id
    for (i=stemix; i< stemarray.length-1; i++)
    stemarray[i] = stemarray[i].substr(0,3) +
    stemarray[i+1].substr(3); // 调整删除后的数组内容
    stemarray.length–;
    }
    if (ansarray.length > 0) {
    delcount = 0;
    for (i=0; i< ansarray.length; i++) {
    if (ansarray[i].substr(0,3) == id) {
    ansarray[i] = “zzz”; // 删除该项(排到最后面)
    delcount++;
    } else if (ansarray[i].substr(0,3) > id) {
    tempid = ” ” +
    (parseint(ansarray[i].substr(0,3)) – 1).tostring();
    tempid = tempid.substr(tempid.length-3, 3);
    ansarray[i] = tempid + ansarray[i].substr(3);
    }
    }
    ansarray.sort();
    ansarray.length-=delcount;
    }
    donav(“< “); // 尝试退回前一问题
    }
   } // dodelete()
   
  
     donav()函数支持问题的导航,实现方法是改变需要显示问题的索引号,然后调用writeitem完成输出,代码略。
  
     writeitem是这里最为复杂的函数。它按照问题类型的不同,将html代码以字符串的形式输出,这个字符串即为显示与编辑该问题的表单。表单为问题的每个可编辑部件提供了onchange()函数定义。当这个表单被写入页面中间的帧(itemframe),用户的编辑操作就会引起对savestem()或saveanswer()函数的调用,这些函数负责修改当前调查项目的stemarray[]或ansarray[]数组。
  
  
   // 在浏览器中显示指定的问题
   function writeitem(stemix) {
    var itype = parseint(stemarray[stemix].substr(3,1)); // 问题类型
    var noopinion = stemarray[stemix].substr(4,1); // 是否允许不回答
    var id = stemarray[stemix].substr(0,3); // 问题的id
   
    for (ansix=0; ansix< ansarray.length; ansix++) {
    if (ansarray[ansix].substr(0,3) == id) break; // 问题的回答
    }
    if (ansix >= ansarray.length) ansix = -1; // 当前问题没有回答结果
    outstr = < html>< body bgcolor=”#c0c0c0″> +
    < form name=”item”> +
    【当前问题编号】 + (stemix + 1) + 【总问题数】 + stemarray.length +
    【调查项目名字】 < %=pollname%>< /b>< br>< /table>< textarea name=”stem” rows=2 cols=85 +
    onblur=”parent.controlframe.savestem()”> +
    stemarray[stemix].substr(5) + < /textarea>< br>;
   
    if (noopinion == “y” && itype != 5) outstr+=
    < input type=radio name=”choice”>暂不回答 ;
    switch (itype) {
    case 1: // 是/否
    outstr+= < input type=radio name=”choice”>是 +
    < input type=radio name=”choice”>否 ;
    break;
    case 2: // 赞同程度
    …略…
    break;
    case 3: // 语义区别
    …略…
    break;
    case 4: // 多个选择项
    …略…
    break;
    case 5: // 允许复选
    …略…
    break;
    default:
    outstr+= 错误: + itype + ” ”
    }
    outstr+= < /form>;
    writeitemframe(outstr);
   } // writeitem()
   
  
     最后,当用户单击“保存”按钮时执行的是dosave()函数。该函数先创建一个表单(表单中包含的隐藏变量描述了stemarray[]和ansarray[]数组的内容),然后把这个表单提交给pollmaker.asp,在这里完成数据库的更新:
  
  
   // 将问题保存到数据库
   function dosave() {
    if (stemarray.length < = 0) return;
    outstr = < html>< body bgcolor=”#c0c0c0″>< center>正在保存 +
    “< %=pollname%>”< /center> +
    < form name=”save” method=post action=”pollmaker.asp”> +
    < input type=hidden name=”optype” value=”savepoll”> +
    < input type=hidden name=”pollname” value=”< %=pollname%>”>
    for (i=0; i< stemarray.length; i++)
    outstr+=< input type=hidden name=”stem” value=” +
    escape(stemarray[i]) + “>;
    for (i=0; i< ansarray.length; i++)
    outstr+=< input type=hidden name=”answer” value=” +
    escape(ansarray[i]) + “>;
    outstr+= < /form>;
    with (parent.msgframe.document) {
    open(“text/html”);
    writeln(outstr);
    close();
    }
    parent.msgframe.document.save.submit();
   } // dosave()
   

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 用ASP技术开发WEB调查(投票)系统 (2)-ASP教程,ASP应用
分享到: 更多 (0)