答题小程序之调查问卷模板开发

	这次我和大家分享一下如何用小程序做一个问卷调查小程序,可以是行业问卷,或者是测试题的。该问卷调查主要介绍题目多且题型多,题目数在15道以上,题型包含单选,非必做、必做题,填空题。当然可以从这些衍生更多的出来。首先理清思路:第一页我们做欢迎语和简介,在答题入口上做跳转题目页和授权按钮功能,然后开始做题,选择题放前,填空题放后,每页2道题,任何一道为空都会提示“请做完本页所有题”,当遇到选做题,则选做题可不做,但剩下那道题则必做才可以继续下一页,当遇到填空题和选择题交叉,则判断填空题的输入域是否为空,选择题是否选做。提交按钮将所有数据以字符串发送服务器。

###第一步、做欢迎页和介绍页。
先上效果图:

在开始答题的按钮上,我们做跳转和授权两个函数。
授权示意图:
这里写图片描述
如果对授权不太了解的可以参考我的置顶博文,有介绍小程序的getPhonenumber组件功能的内容。
代码我也给大家放上
页面内容:

 <button class='index_btn' style='line-height:normal;' wx:if="{{btnShow}}" bindtap=''  open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">开始答题</button>

JS内容,将跳转放在授权里面,授权成功则跳转做题,授权取消,停留当前页面:

//通过绑定手机号登录getPhoneNumber: function (e) {var ivObj = e.detail.ivvar telObj = e.detail.encryptedDatavar codeObj = "";var that = this;//------执行Loginwx.login({success: res => {console.log('code转换', res.code); //用code传给服务器调换session_keywx.request({url: 'https://x.xxxxxxx.com/xiaochengxu/demo.php', //接口地址data: {appid: "小程序appid",secret: "小程序密钥",code: res.code,encryptedData: telObj,iv: ivObj},header: {'content-type': 'application/json' // 默认值},success: function (res) {phoneObj = res.data.phoneNumber;console.log("手机号=", phoneObj)wx.setStorage({   //存储数据并准备发送给下一页使用key: "phoneObj",data: res.data.phoneNumber,})}})//-----------------是否授权决定是否可以做题if (e.detail.errMsg == 'getPhoneNumber:fail user deny') { //用户点击拒绝判断wx.navigateTo({url: '../index/index',})} else { //授权通过执行跳转wx.navigateTo({url: '../test/test',})}}});//---------登录有效期检查wx.checkSession({success: function () {//session_key 未过期,并且在本生命周期一直有效},fail: function () {// session_key 已经失效,需要重新执行登录流程wx.login() //重新登录}});},

###第二步、答题页面
首先我先放上页面题目展示效果:
这里写图片描述
这里是两个题目为一页,选做题和必选题以及填空题也是这样排列。
页面内的布局写法:

<form bindsubmit="formSubmit" bindreset="formReset">
<!-- 两道题联动 --><view class='page {{page ==1?"on":""}}'><import src="radio_my.wxml"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[0],ind:1}}"/><import src="radio_my.wxml"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[1],ind:2}}"/></view>
<!-- 两道题联动 --><view class='page {{page ==2?"on":""}}'><import src="radio_my.wxml"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[2],ind:3}}"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[3],ind:4}}"/></view><view class='page {{page ==3?"on":""}}'><import src="radio_my.wxml"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[4],ind:5}}"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[5],ind:6}}"/></view><view class='page {{page ==4?"on":""}}'><import src="radio_my.wxml"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[6],ind:7}}"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[7],ind:8}}"/></view><view class='page {{page ==5?"on":""}}'><import src="radio_my.wxml"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[8],ind:9}}"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[9],ind:10}}"/></view><view class='page {{page ==6?"on":""}}'><import src="radio_my.wxml"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[10],ind:11}}"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[11],ind:12}}"/></view><view class='page {{page ==7?"on":""}}'><import src="radio_my.wxml"/><template is="radio" data="{{my: my,title:myHospitalQuestionnaireData[12],ind:13}}"/><import src="textarea.wxml"/><template is="textarea" data="{{data:myHospitalQuestionnaireData[13],ind:14,pla:'请填写您最满意的医生、护士'}}"/></view><!-- 最终提交 --><view class='page {{page ==8?"on":""}}'><import src="textarea.wxml"/><template is="textarea" data="{{data:myHospitalQuestionnaireData[14],ind:15,pla:'请填写您的具体建议...'}}" value="{{userInfo.nickName}}"/><!-- <import src="login.wxml"/><template is="login" data="{{data:myHospitalQuestionnaireData[15],ind:16}}" />    --></view><!-- 最终提交 --><!-- 最后一页 --><view class="footer-btn"><button class="btn-tj {{page_prev?'on':''}}" bindtap="prevPage" >上一页</button><button formType="submit" class="btn-tj {{page_next?'on':''}}" bindtap="nextPage" wx:if="{{page!=page_num}}">下一页</button><button  class="btn-tj {{page_next?'on':''}}"   wx:if="{{page==page_num}}" formType="submit"  style='background:#19be6b;'>提交</button><!-- --></view><view class='page_num'>第{{page}}页 共{{page_num}}页</view><import src="modal.wxml"/><template is="modal" data="{{msg:modaltext,show:modalShow}}"/> 
</form>

以form表单来提交数据很简单方便的。对于不同体型,我们做不同的模板调用,这样格式统一样式统一,选择题用一个,填空题用一个。
例如:

<template name="radio"><view class="container"><view class="ask-wrap"><view class="ask-title">{{ind}}、{{title.title}}</view><view class="ask-area"><radio-group class="radio-group" name="group_{{title.id}}" bindchange='radioChange' id="{{title.id}}"><label class="radio" bindchange="radioChange" wx:for="{{my}}" wx:key="" wx:for-index="index" data-index="{{index}}" ><radio value="{{item.value}}" checked="{{item.checked}}"/>{{item.con}}</label></radio-group></view></view></view>
</template>

这是选择题的。题目序号,题目内容和选项都布局好了,在题目页就更好罗列出来。

那么答题页面的JS如何写的呢?
附加代码:

var common = require('../../utils/common.js');
//获取应用实例
var app = getApp();
//存储全局
var phoneObj = '';
Page({data: {show: true,page: 1,one: false,two: false,page_num: 0,phoneObj: '',page_prev: false,page_next: true,result: {},doctor: [],modaltext: "出错了",modalShow: false,doctorValue: "",addMsgs: "",nextShow: "false",my: [{value: "1",con: "满意"}, {value: "2",con: "基本满意"}, {value: "3",con: "不满意"}],zd: [{value: "1",con: "知道"}, {value: "2",con: "不知道"}],zd1: [{value: "1",con: "满意"}, {value: "2",con: "基本满意"}, {value: "3",con: "不满意"}],myHospitalQuestionnaireData: []},onShow() { //清空一部分数据 文本不知道怎么清除this.setData({page: 1,page_prev: false,zd: [{value: "1",con: "知道"}, {value: "2",con: "不知道"}],my: [{value: "1",con: "满意"}, {value: "2",con: "基本满意"}, {value: "3",con: "不满意"}],zd1: [{value: "1",con: "满意"}, {value: "2",con: "基本满意"}, {value: "3",con: "不满意"}]})},onLoad() {var that = this;wx.request({url: 'https://xx.xxxxx.com/js/HospitalQuestionnaire.js',  //将测试题封装在JS中调用里面的题目header: {'content-type': 'json'},success: function(res) {// console.log(res.data)that.setData({myHospitalQuestionnaireData: res.data  //页面题目内容展示的data数据名});that.setData({page_num: Math.ceil(that.data.myHospitalQuestionnaireData.length / 2) //每页题目数});}})},radioChange(e) {var arr = this.data.myHospitalQuestionnaireData;if (e.currentTarget.id == arr[0].id) {if (e.detail.value == "1") {this.setData({one: true});} else {this.setData({one: false});}}if (e.currentTarget.id == arr[2].id) {if (e.detail.value == "1") {this.setData({two: true});} else {this.setData({two: false});}}var oldval = this.data.result;oldval[e.currentTarget.id] = e.detail.value;this.setData({result: oldval});},bindKeyInput(e) {this.setData({doctorValue: e.detail.value});},//--------addDoctor() {if (this.data.doctorValue == "") {this.modalShow({msg: "您还没有填写任何内容"});return;}var oldarr = this.data.doctor;oldarr.push(this.data.doctorValue);this.setData({doctor: oldarr,doctorValue: ""});},//------------//意见建议textBlur: function(e) {if (e.detail && e.detail.value.length > 0) {if (e.detail.value.length < 1 || e.detail.value.length > 500) {//app.func.showToast('内容为12-500个字符','loading',1200);} else {this.setData({addMsgs: e.detail.value});}} else {this.setData({addMsgs: ''});evaData.addMsgs = '';app.func.showToast('请输入投诉内容', 'loading', 1200);}},prevPage() {if (this.data.page > 1) {this.data.page--;this.setData({page: this.data.page--});if (this.data.page == "1") {this.setData({page_prev: false});}} else {this.setData({page_prev: false});this.modalShow({msg: "已经没有上一页了"});return;}},chooseDel(e) {let id = e.currentTarget.id,oldarr = this.data.doctor;oldarr.splice(id, 1);this.setData({doctor: oldarr});},//-----------//下一页 / 表单提交formSubmit: function(e) {// console.log('提交数据', e.detail.value);var that = this;var telPhone = wx.getStorageSync('phoneObj'); //读取登录手机号信息并不断刷新是否丢失console.log('---------', telPhone)//----------var page = this.data.page, //做题页数arr = this.data.myHospitalQuestionnaireData, //题目总数boo = true;if (this.data.page != Math.ceil(arr.length / 2)) {for (var i = 0; i < arr.length; i++) {var index = arr[i].id; //数据编号if (index != "47" && index != "48") { //判断选做题为空if (i < page * 2) {if (e.detail.value["group_" + index] == '') {boo = false;}if (e.detail.value["group_" + index] == '') {console.log(index)}}}}} else {let that = this,obj = e.detail.value,key = Object.keys(obj),len = this.data.myHospitalQuestionnaireData.length;common.extend(arr, {len: len.toString()});let str = "",ind = 0;for (var i = 0; i < key.length; i++) {str += "&" + key[i] + "=" + e.detail.value[key[i]];ind++;}console.log(obj)console.log(telPhone)if (telPhone != "" || telPhone != undefined || telPhone != null) { //再次确认手机号是否携带值wx.showModal({title: '提示',content: '确认要提交吗',success: function(res) {if (res.confirm) {req();} else if (res.cancel) {console.log('用户点击取消')}}});} else {this.modalShow({msg: "请稍后重试"});}function req() {if (telPhone != "" || telPhone != undefined || telPhone != null) { //最终确认手机号有值wx.request({url: 'https://x.xxxxx.com/manage/wenjuan/questionnaire.ashx?project=zz&len=' + len.toString() + str + '&group_56=' + telPhone,   //提交的数据的地址以及格式包括授权过来的手机号method: "POST",data: obj,header: {'content-type': 'application/json'},success: function(res) { //查询提交数据内容console.log(res.data)// console.log("111", obj)// console.log('&group_56=', telPhone)var message = res.data;if (message == "" || message == undefined || message == null) {wx.showModal({title: '提示',content: '操作频繁',success: function (res) {if (res.confirm) {wx.redirectTo({url: '../index/index',});} else if (res.cancel) {console.log('用户点击取消')}}});} else {that.modalShow({msg: res.data});setTimeout(function() {wx.navigateTo({url: "../result/result"})}, 1000);};}})} else {that.modalShow({msg: "提交失败"});wx.navigateTo({url: '../test/test',})}}}//----条件判断if (boo) {if (this.data.page < Math.ceil(arr.length / 2)) {this.data.page++;this.setData({page: this.data.page++,page_prev: true});} else {return;}} else {this.modalShow({msg: "请答完本页内所有题目"});}},//控制弹出层开启modalShow(para) {let deault = {msg: "出错了",time: 1500}common.extend(deault, para);this.setData({modalShow: true,modaltext: deault.msg});let that = this;setTimeout(function() {that.setData({modalShow: false});}, deault.time);},//弹出层关闭modalHide() {this.setData({modalShow: false});},formReset() {console.log('form发生了reset事件')}
})//-----------
var myHospitalQuestionnaireArrMY = [{value: "1",con: "满意",checked: 'true'
}, {value: "2",con: "基本满意"
}, {"value": "3","con": "不满意"
}];
var myHospitalQuestionnaireArrZD = [{value: "1",con: "知道",checked: 'true'
}, {value: "2",con: "不知道"
}];

我是把所有的判断都写在这测试题JS中了,小伙伴可以封装写在util.js中。
页面展示一下不同情况的效果吧:
例如:全做的可以跳转
这里写图片描述
例如:没做的提示请做完并禁止跳转
这里写图片描述
例如:选做题都不做则不给跳转
这里写图片描述
不做选做,但是做了剩下的则跳转
这里写图片描述
反制如果做了选做,不做必做的则也不跳转,判断用的是同一个判断:

//----条件判断if (boo) {if (this.data.page < Math.ceil(arr.length / 2)) {this.data.page++;this.setData({page: this.data.page++,page_prev: true});} else {return;}} else {this.modalShow({msg: "请答完本页内所有题目"});}

还有:如果填空题不做,则也不跳转
这里写图片描述
这样就完成了所有的判断。
最后的提交按钮写法:

 <!-- 最后一页 --><view class="footer-btn"><button class="btn-tj {{page_prev?'on':''}}" bindtap="prevPage" >上一页</button><button formType="submit" class="btn-tj {{page_next?'on':''}}" bindtap="nextPage" wx:if="{{page!=page_num}}">下一页</button><button  class="btn-tj {{page_next?'on':''}}"   wx:if="{{page==page_num}}" formType="submit"  style='background:#19be6b;'>提交</button><!-- --></view>

为什么这样写呢?
因为在做题和提交上我们用的一直是同一个按钮,也就是form的提交按钮,对其样式做三目运算来判断该显示是下一页还是显示提交。也就是罗列题目是,题目数全部跳完则显示提交按钮。
最后提醒下:
防止数据丢失,或者授权信息丢失,可以在每次跳转下一页的时候都打印一次。确保最后全部数据可以传输。

本文只提供思路;商业机密无法提供完整代码,可以在评论区和我探讨这些问题。
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1381153.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【学习记录】SPSS问卷调查表分析法

用excel将收集的问卷数据存储&#xff0c;并用SPSS进行数据分析 文章目录 一、对收集的excel数据进行数据转换二、将调整合适的excel数据导入SPSS&#xff0c;并进行变量调整1.导入excel数据2.在变量视图进行变量设置&#xff0c;测量这一列所分析的数据要选择标度&#xff0c;…

向量的积

向量积&#xff0c;也被称为叉积&#xff08;即交叉乘积&#xff09;&#xff0c;是一种在向量空间中向量的二元运算。与点积不同&#xff0c;它的运算结果是一个伪向量而不是一个标量。并且两个向量的叉积与这两个向量都垂直。定义&#xff1a; 在这里θ表示’a和b之间的角度&…

向量外积及其解释

1.向量的外积定义 向量的外积也叫叉积。 外积的定义也有两个&#xff0c;如下&#xff1a; 假设在三维空间中&#xff08;向量的叉积只能定义在三维空间中&#xff0c;如二维、三维&#xff09;&#xff0c;两个向量,&#xff0c;则 1&#xff09;&#xff0c;其中是垂直与…

数量积与向量积(点积与叉积)

点积 数量积即点积。 定义 在数学中&#xff0c;数量积&#xff08;dot product; scalar product&#xff0c;也称为标量积、点积、点乘&#xff09;是接受在实数R上的两个矢量并返回一个实数值标量的二元运算。它是欧几里得空间的标准内积。 两个矢量a [a1, a2,…, an]和…

向量点乘\叉乘,矩阵向量乘法

向量 点乘 公式&#xff1a;a b |a| * |b| * cosθ 点乘又叫向量的内积、数量积&#xff0c;是一个向量和它在另一个向量上的投影的长度的乘积&#xff1b;是标量。 点乘反映着两个向量的“相似度”&#xff0c;两个向量越“相似”&#xff0c;它们的点乘越大。 例&#xff…

矩阵与向量的乘法

矩阵乘积 矩阵乘法是矩阵运算中最重要的操作之一。两个矩阵 A A A 和 B B B 的 矩阵乘积&#xff08;matrix product&#xff09;是第三个矩阵 C C C。为了使乘法定义良好&#xff0c;矩阵 A A A 的列数必须和矩阵 B B B 的行数相等。如果矩阵 A A A 的形状是 m n m …

python 列表过滤方法 条件表达式

1.使用filter和lambda函数 filter&#xff08;fun, seq&#xff09;函数对seq里的每个元素执行fun&#xff08;&#xff09;&#xff0c;并返回值为true的元素放在一个iterator里 例如在一个列表里找出所有奇数可以这样写&#xff1a; a [1,2,3,4,5,6,7,8] print(list(filt…

jQuery 过滤方法

文章目录 jQuery 过滤方法hasClass() 类名过滤eq() 下标过滤is() 判断过滤not() 反向过滤filter() 表达式过滤has() 表达式过滤后代元素 jQuery 过滤方法 过滤方法说明hasClass()类名过滤eq()下标过滤is()判断过滤not()反向过滤filter()表达式过滤has()表达式过滤后代元素 ha…

过滤器的几种实现方法

过滤器&#xff1a;对要显示的数据进行特定格式化后再显示&#xff0c; 语法&#xff1a;&#xff08;1&#xff09;注册过滤器分为局部注册和全局注册。局部注册new Vue(filter:{}),全局注册&#xff1a;Vue.fmtData_global (2)使用过滤器&#xff1a;{{xxx|过滤器名}}或v-bin…

Nginx负载均衡以及keepalived高可用实验

Vip 10.1.122 Keepalived-master 10.1.1.132Keepalied-backup 10.1.1.133Realserver_1 10.1.1.136Realserver_2 10.1.1.137 四台机器上安装nginx&#xff0c;编译安装的话需要另外安装pcre包支持&#xff0c;安装在/usr/local/nginx Keepalived-master 和backu…

Filter 过滤器的使用

目录 一、Filter简介 二、Filter使用 1、Filter 的初体验 2、Filter 的生命周期 3、FilterConfig类 4、FilterChain过滤器链 5、Filter 的拦截路径 1&#xff09;精确匹配 2&#xff09;目录匹配 3&#xff09;后缀名匹配 一、Filter简介 Filter 过滤器它是 JavaWeb…

(Filter)过滤器的使用

过滤器&#xff08;Filter&#xff09;的简介 过滤器(Filter): 能够完成筛选不需要数据的工具(东西). 类似于生活中的净水器,香烟过滤嘴,滤纸, 收费站等.------->单向的. Web中: 过滤器其实就是服务端的一个程序(程序的最小单元就是类). 在Web开发中,过滤器其实就是一个…

过滤器的使用

过滤器的使用 过滤器介绍过滤器的使用配置过滤器过滤器路径的配置规则前置、后置、环绕过滤器过滤器链过滤器的优先级 过滤器介绍 过滤器(Filter)是位于客户端与服务器资源之间的一道过滤技术&#xff0c;可以在客户端请求到达目标资源之前进行预处理业务。 过滤器作用 执行多…

tcpdump常用与高级过滤方法整理

1.命令格式 tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ][ -i 网络接口 ] [ -r 文件名] [ -s snaplen ] [ -T 类型 ] [ -w 文件名 ] [表达式 ] 2.选项介绍 参数含义-a将网络地址和广播地址转变成名字-d将匹配信息包的代码以人们能够理解的汇编格式给出-dd将匹配信…

特征选择方法概括—过滤法、嵌入法、包装法

一、过滤法&#xff08;Filter&#xff09; 特点&#xff1a;过滤方法通常用作预处理步骤&#xff0c;特征选择完全独立于任何机器学习算法 过程&#xff1a; 目标对象&#xff1a;需要遍历特征或升维的算法。最近邻算法KNN&#xff0c;支持向量机SVM&#xff0c;决策树&#…

2022年湖北省建筑三类人员(项目负责人B证)练习题及答案

一、单选题 1、根据《安全生产培训管理办法》的规定&#xff0c;安全培训机构不具备安全培训条件的&#xff0c;责令限期改正&#xff0c;处1万元以下的罚款。逾期未改正的&#xff0c;给予警告&#xff0c;处&#xff08;B&#xff09;的罚款。 A.1万元以上2万元以下 B.1万…

2022年建筑三类人员A证考试题,三类人员考试搜题app

单选题 1、根据《危险性较大的分部分项工程安全管理规定》&#xff0c;&#xff08;B&#xff09;应当在施工现场显著位置公告危大工程名称、施工时间和具体责任人员&#xff0c;并在危险区域设置安全警示标志。 A.建设单位 B.施工单位 C.设计单位 D.勘察单位 2、依据我国…

2022年江西省建筑三类人员(项目负责人B证)练习题及答案

一、单选题 1、首次取得建筑施工特种作业资格证书的人员&#xff0c;在其正式上岗前&#xff0c;应当由用人单位安排不少于(A)的实习操作。 A.3个月 B.4个月 C.6个月 D.1年 2、结构施工自&#xff08;A&#xff09;层起&#xff0c;凡人员进出的通道口&#xff0c;均应搭…

2022年江苏省建筑三类人员(项目负责人B证)练习题及答案

2022年江苏省建筑三类人员&#xff08;项目负责人B证&#xff09;练习题及答案&#xff0c;根据最新建筑三类人员考试大纲与历年建筑三类人员考试真题汇总编写&#xff0c;包含建筑三类人员考试常考重点题型与知识点&#xff0c;有助于考生复习备考&#xff0c;取得好成绩。 多…

2022年湖北省建筑三类人员(专职安全生产管理人员C3证)练习题及答案

多选题 1、攀登和悬空高处作业人员以及搭设高处作业安全设施的人员必须经过(AC)合格,持证上岗。 A.专业考试合格 B.体格检查 C.专业技术培训 D.思想教育 E.技术教育 2、有下列情形之一的,建设单位应当按照国家有关规定办理申请批准手续(ABCDE)。 A.需要临时占用规划批准…