• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
	这次我和大家分享一下如何用小程序做一个问卷调查小程序,可以是行业问卷,或者是测试题的。该问卷调查主要介绍题目多且题型多,题目数在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.iv
      var telObj = e.detail.encryptedData
      var codeObj = "";
      var that = this;
      //------执行Login
      wx.login({
        success: res => {
          console.log(\'code转换\', res.code); //用code传给服务器调换session_key

          wx.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的提交按钮,对其样式做三目运算来判断该显示是下一页还是显示提交。也就是罗列题目是,题目数全部跳完则显示提交按钮。
最后提醒下:
防止数据丢失,或者授权信息丢失,可以在每次跳转下一页的时候都打印一次。确保最后全部数据可以传输。

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


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap