微信小程序 滿意度調查問卷

    這次我和大家分享一下如何用小程序做一個問卷調查小程序,可以是行業問卷,或者是測試題的。該問卷調查主要介紹題目多且題型多,題目數在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的提交按鈕,對其樣式做三目運算來判斷該顯示是下一頁還是顯示提交。也就是羅列題目是,題目數全部跳完則顯示提交按鈕。
最後提醒下:
防止數據丟失,或者授權信息丟失,可以在每次跳轉下一頁的時候都打印一次。確保最後全部數據可以傳輸。
————————————————
版權聲明:本文爲CSDN博主「沉默的小猴子」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_38194393/article/details/82584751

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章