这次我和大家分享一下如何用小程序做一个问卷调查小程序,可以是行业问卷,或者是测试题的。该问卷调查主要介绍题目多且题型多,题目数在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的提交按钮,对其样式做三目运算来判断该显示是下一页还是显示提交。也就是罗列题目是,题目数全部跳完则显示提交按钮。
最后提醒下:
防止数据丢失,或者授权信息丢失,可以在每次跳转下一页的时候都打印一次。确保最后全部数据可以传输。

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

答题小程序之调查问卷模板开发相关推荐

  1. 微信小程序 满意度调查问卷答题类小程序实现

    最近暂时不用忍受学业压力,可以干一些自己想干的事情,由于接的小程序的锅太多,决定好好学习一下小程序,本次主要学习了答题问卷小程序的制作,涉及到题目切换.答案上传以及简单的完成情况判断等场景,本次设计特 ...

  2. 微信小程序实现调查问卷表单

    微信小程序问卷调查表单 功能演示: 20220408_202155 index.wxml <view id="container-top"> <view id=& ...

  3. 微信小程序学习之Template模板开发

    WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用.使用 name 属性,作为模板的名字.然后在 <template/> 内定义代码片段,使用 is 属性 ...

  4. 成语答题小程序手机版后台开发

    成语答题小程序手机版后台页面开发 成语答题小程序后台设置页面 成语答题小程序固定红包页面 成语答题小程序添加固定红包页面 成语答题小程序添加奖品页面 成语答题小程序删除内容提示页面 成语答题小程序添加 ...

  5. 百里挑一的试题库管理系统以及考试答题小程序

    目前活动答题小程序集成微信原生模板广告.插屏广告.激励视频广告等功能.应用场景:员工考核,招聘考试,大型校招,晋升考核,经销商考核,党政类知识竞赛,技能知识竞赛,校内知识竞赛等等. V2.0版已完成功 ...

  6. 用云开发搭建的微信答题小程序v1.0

    近来百无聊赖,遂抽空做了一个答题小程序的系列教程,以及分享源码,是用云开发搭建的微信答题小程序v1.0. 界面截图 该答题小程序大致如下图: 结构层级 主要程序由3个界面组成,分别是index,tes ...

  7. 微信答题小程序开发功能概述

    微信答题小程序仿头脑王者源码是一款专业性的答题小程序,(软著登记号:4078210号)主要功能有:每日签到.排位赛.好友PK.每日答题.大奖赛,群比赛3V3 5V5以及道具商店等.完整题型库.100多 ...

  8. 微信答题小程序开发遇到过的坑

    我在开发答题小程序.考研题库小程序过程中,遇到过的坑以及其解决办法,在此做个笔记. 小程序页面栈最多十层 问题:假设小程序内有20个问题页面,答完上一个问题后wx.navigateTo到下一个问题页面 ...

  9. 微信答题小程序开发,怎么制作用于考试的小程序,微信小程序军人条令考试,微信小程序里给员工学习考试

    很多单位都有定期或者不定期的知识测试或者技能考核的要求,用来考量员工的学习效果或者技能掌握程度. 以前大都是在纸面或者电脑上进行,不是太方便. 现在随着智能手机和微信的普及,越来越多的企业开始在微信上 ...

  10. 【微信小程序】【云开发】微笑考试答题小程序1.0.0版本 —— 小小成果

    部分相关页面模板.功能模板地址:https://gitee.com/nanfangzhe/Wechat_Assistant 微笑考试答题小程序1.0.0版本 [展示图] [体验方式] [更多小程序] ...

最新文章

  1. 支持向量机(support vector machine)(SVM)(1)
  2. Python学习教程实用技法:通过公共键对字典列表排序—itemgetter
  3. [零基础学JAVA]Java SE面向对象部分-08.面向对象基础(03)
  4. 糟糕程序员的20个坏习惯
  5. AjaxPro新发现-错误处理
  6. Java中的weak reference 和 soft reference
  7. string empty java,在C#中,我应该使用string.Empty还是String.Empty或“”来初始化字符串?...
  8. mysql求和 子查询_MYSQL 查询方法 统计查询 链接查询 子查询
  9. 中国量子计算机 是纠缠,量子纠缠获得突破,中国量子计算机问世,民营企业立下显著功勋...
  10. JAVA读写Properties属性文件
  11. mysql多条件顺序_mysql顺序由多个条件
  12. 未能配置 workstation server 的两种错误解决
  13. 如何使用电脑将png转ico格式?赶快跟着小编学起来
  14. 笔记——c51的led点阵流动字幕
  15. bugku misc 11-15 解题报告
  16. [构造] Codeforces Gym 101173 CERC 16 K BZOJ 4796 Key Knocking
  17. 韦伯望远镜拍摄图片震撼来袭!!
  18. linux 7.0 域名,RHEL 7.0已发布 CentOS 7 即将到来
  19. Android7.0 Notification Show silently 阻止通知 定制
  20. 什么是class-agnostic,class-agnostic是什么意思

热门文章

  1. (二十)STM32——电容触摸按键?建议改名为卫生纸按键
  2. 基于android的健康管理系统客户端的设计与实现,基于Android的健康管理系统客户端的设计与实现...
  3. Zotero文献题录和附件如何导入到NoteExpress?
  4. matlab拉格朗日kkt,深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT条件
  5. c语言 步进电机 程序,两相5、6线步进电机C语言程序
  6. oracle的order by排序优化,oracle order by 排序优化
  7. python项目打包成whl文件
  8. web optimize_image / Jpegoptim / ImageOptim / google webP
  9. 空间解析几何 | 空间曲线的切向量与曲面的法向量
  10. matlab常用插值函数