微信小程序做问卷——前端部分(回答问卷)

  • Post author:
  • Post category:小程序


生成问卷的部分参考

微信小程序做问卷——前端部分(生成问卷)



实现效果

界面如下,分别展示了三种题型,单选题,多选题,简答题。

界面

单选只可以选择一个,多选可以选择多个,问答题写在

<textarea>

中,点击完成会打印出整个表的数据。

比如下面是默认的数据

默认数据

现在勾选单选和多选,以及改变回答部分再看一下数据

在这里插入图片描述

可以看到数据是匹配的,所以最后只要把生成好的数据提交到后端,那么一份问卷就算是完成了。



实现

因为是先写的

微信小程序做问卷——前端部分(生成问卷)

,所以重复的部分不再赘述了,建议先看生成问卷部分,回答问卷比生成问卷的逻辑简单一些。

数据结构还是一样的,先是生成问卷,然后再填写生成好的问卷,所以两者的数据结构是一致的。

questionnaireArray: [
      {
        "type": "SCQ",
        "content": {
          "description": "Which fruit do you like best?",
          "options":
            [
              { "id": 1, "name": "Lua", "isSelected": false },
              { "id": 2, "name": "Java", "isSelected": false },
              { "id": 3, "name": "C++", "isSelected": false }
            ]
        }
      },
      {
        "type": "MCQ",
        "content": {
          "description": "Which fruit do you like?",
          "options":
            [
              { "id": 1, "name": "OK", "isSelected": false },
              { "id": 2, "name": "Java", "isSelected": false },
              { "id": 3, "name": "C++", "isSelected": false }
            ]
        }
      },
      {
        "type": "SAQ",
        "content": {
          "description": "What's your name?",
          "answer": "i dont know"
        }
      }
    ],



单选部分

<block wx:if="{{item.type === 'SCQ'}}">
    <view class = 'SCQ' data-id='{{fatherIndex}}'>
      <view class='SCQTitle'>
        <view class='SCQQ'>Q</view>
        <view class='SCQindex'>{{fatherIndex+1}}</view>
        <view class='SCQquto'>:</view>
        <text class='SCQDiscription' data-id='{{fatherIndex}}'>{{item.content.description}}</text>
      </view>
      <radio-group class="SCQOption" bindchange="radioChangeSCQ">
        <label class="SCQText" wx:for="{{item.content.options}}" wx:key="SCQID" data-id='{{fatherIndex}}' bindtouchstart='getTempFatherIndex'>
          <radio value="{{item.name}}" checked="{{item.isSelected}}"/>{{item.name}}
        </label>
      </radio-group>
    </view>
  </block>

用的结构还是和之前的一样,不一样的是用的

<radio-group>

,在这个里面申明

<radio>

会自动生成单选按钮,以及实现逻辑,即在众多选项中只可以有一个处于被勾选的状态。

但是他并不能改变js中的数据,所以还是要在

radioChangeSCQ

里面自己写逻辑(这部分可能有API会直接得到,但是由于我是先写生成部分,所以逻辑可以直接拿来用)

  radioChangeSCQ:function(input){
    var tempFatherIndex = this.data.currentFatherIndex;
    var tempArray = this.data.questionnaireArray;
    for (var i in tempArray[tempFatherIndex].content.options){
      if (tempArray[tempFatherIndex].content.options[i].name == input.detail.value){
        tempArray[tempFatherIndex].content.options[i].isSelected = true;
      }
      else{
        tempArray[tempFatherIndex].content.options[i].isSelected = false;
      }
    }
    this.setData({
      questionnaireArray: tempArray,
    });
  },

其中

input.detail.value

就是

一个


object

,比如上图展示的第一题点击

Java

的时候,

Java

被勾选,那么该值就是

Java


这部分主要是在页面变更的时候,也可以改变js中的数据。首先拿到父节点的索引,再取得子节点的索引,然后再选项中遍历一遍,所以选项是和自己点击的

input.detail.value

一致的话,就把数据的选择改成选中状态,那么其他的选项都可以设置为没有被选中的状态。



多选部分

<block wx:if="{{item.type === 'MCQ'}}">
    <view class = 'MCQ' data-id='{{fatherIndex}}'>
      <view class='MCQTitle'>
        <view class='MCQQ'>Q</view>
        <view class='MCQindex'>{{fatherIndex+1}}</view>
        <view class='MCQquto'>:</view>
        <text class='MCQDiscription' data-id='{{fatherIndex}}'>{{item.content.description}}</text>
      </view>

      <checkbox-group class="MCQOption" bindchange="checkboxChangeMCQ">
        <label class="MCQText" wx:for="{{item.content.options}}" wx:key="MCQID" data-id='{{fatherIndex}}' bindtouchstart='getTempFatherIndex'>
          <checkbox value="{{item.name}}" checked="{{item.isSelected}}" data-id='{{index}}'/>{{item.name}}
        </label>
      </checkbox-group>
    </view>
  </block>

这里的

input.detail.value



多个

值,比如第二题

OK



C++

,那么该值是

[OK,C++]

这是和单选有区别的地方

这里用的是

<checkbox-group>

,在里面使用

<checkbox>

属性会自动生成多选界面以及逻辑,同样数据的改变还是需要在

checkboxChangeMCQ

checkboxChangeMCQ:function(input){
    // console.log(input.detail.value);
    var flag = false;
    var tempFatherIndex = this.data.currentFatherIndex;
    var tempArray = this.data.questionnaireArray;
    for (var i in tempArray[tempFatherIndex].content.options) {
      flag = false;
      for(var j in input.detail.value){
        if (tempArray[tempFatherIndex].content.options[i].name == input.detail.value[j]){
          flag = true;
        }
      }
      if(flag == true){
        tempArray[tempFatherIndex].content.options[i].isSelected = true;
      }
      else{
        tempArray[tempFatherIndex].content.options[i].isSelected = false;
      }
    }
    this.setData({
      questionnaireArray: tempArray,
    });
  },

这里的逻辑就是对每个选项进行判断,判断是否处在被选中的选项之后,是就勾选,设置了

flag

,是只要满足有一个相同就可以了。



问答部分

<block wx:if="{{item.type === 'SAQ'}}">
    <view class = 'SAQ' data-id='{{fatherIndex}}'>
      <view class='SAQTitle'>
        <view class='SAQQ'>Q</view>
        <view class='SAQindex'>{{fatherIndex+1}}</view>
        <view class='SAQquto'>:</view>
        <text class='SAQDiscription' data-id='{{fatherIndex}}'>{{item.content.description}}</text>
      </view>
      <textarea auto-height='true' class = "SAQAnswer" value='{{item.content.answer}}' bindblur='bindblurAnswerOfSAQ' data-id='{{fatherIndex}}'></textarea>
    </view>
  </block>

和生成问卷的时候一致,为了完整性写在这里,但是不再解释了。

  bindblurAnswerOfSAQ: function (input) {
    var tempIndex = input.currentTarget.dataset.id;
    var tempArray = this.data.questionnaireArray;
    tempArray[tempIndex].content.answer = input.detail.value;
    // console.log(tempArray[tempIndex].content);
    this.setData({
      questionnaireArray: tempArray,
    });
  },



全部代码



item.wxml

<view id="title">
  <view class='titleContent'>问卷</view>
  <image class='titlePriceIcon' src='{{priceIcon}}' mode='widthFix'></image>
  <view class='priceContent'>25</view>
  <view class='priceUnit'>元</view>
</view>

<view id = 'body' wx:for="{{questionnaireArray}}" wx:key="id" wx:for-index='fatherIndex'>
  <block wx:if="{{item.type === 'SCQ'}}">
    <view class = 'SCQ' data-id='{{fatherIndex}}'>
      <view class='SCQTitle'>
        <view class='SCQQ'>Q</view>
        <view class='SCQindex'>{{fatherIndex+1}}</view>
        <view class='SCQquto'>:</view>
        <text class='SCQDiscription' data-id='{{fatherIndex}}'>{{item.content.description}}</text>
      </view>
      <radio-group class="SCQOption" bindchange="radioChangeSCQ">
        <label class="SCQText" wx:for="{{item.content.options}}" wx:key="SCQID" data-id='{{fatherIndex}}' bindtouchstart='getTempFatherIndex'>
          <radio value="{{item.name}}" checked="{{item.isSelected}}"/>{{item.name}}
        </label>
      </radio-group>
    </view>
  </block>
  <block wx:if="{{item.type === 'MCQ'}}">
    <view class = 'MCQ' data-id='{{fatherIndex}}'>
      <view class='MCQTitle'>
        <view class='MCQQ'>Q</view>
        <view class='MCQindex'>{{fatherIndex+1}}</view>
        <view class='MCQquto'>:</view>
        <text class='MCQDiscription' data-id='{{fatherIndex}}'>{{item.content.description}}</text>
      </view>

      <checkbox-group class="MCQOption" bindchange="checkboxChangeMCQ">
        <label class="MCQText" wx:for="{{item.content.options}}" wx:key="MCQID" data-id='{{fatherIndex}}' bindtouchstart='getTempFatherIndex'>
          <checkbox value="{{item.name}}" checked="{{item.isSelected}}" data-id='{{index}}'/>{{item.name}}
        </label>
      </checkbox-group>
    </view>
  </block>
  <block wx:if="{{item.type === 'SAQ'}}">
    <view class = 'SAQ' data-id='{{fatherIndex}}'>
      <view class='SAQTitle'>
        <view class='SAQQ'>Q</view>
        <view class='SAQindex'>{{fatherIndex+1}}</view>
        <view class='SAQquto'>:</view>
        <text class='SAQDiscription' data-id='{{fatherIndex}}'>{{item.content.description}}</text>
      </view>
      <textarea auto-height='true' class = "SAQAnswer" value='{{item.content.answer}}' bindblur='bindblurAnswerOfSAQ' data-id='{{fatherIndex}}'></textarea>
    </view>
  </block>
</view>

<button class="weui-btn" type="primary" bindtap='complete'>完成</button>



item.wxss

.arrow{
width: 10px;
height: 10px;
border-top: 2px solid #999;
border-right: 2px solid #999;
transform: rotate(-135deg);
margin-top:60rpx;
margin-left: 60rpx;
}

.backContent{
  margin-top:40rpx;
  margin-bottom: 20rpx;
}

#back{
  display: flex;
  flex-direction: row;
  border: 2px solid #999;
}

#title{
  display: flex;
  flex-direction: row;
  background-color: #E3E3E3;
  padding: 30rpx;
}

.titlePriceIcon{
  width: 60rpx;
  position: absolute;
  right: 120rpx;
}

.titleContent{
  margin-left: 50rpx;
}

.priceContent{
  position: absolute;
  right: 70rpx;
}

.priceUnit{
  position: absolute;
  right: 20rpx;
}

.SCQselectIcon{
  width: 60rpx;
}

.SCQOption{
  display: flex;
  flex-direction:column;
  margin-top: 20rpx;
}

.MCQselectIcon{
  width: 60rpx;
}
.SCQ{
  padding: 20rpx;
  border: 2rpx solid #999;
}
.SCQText{
  margin-left: 20rpx;
  /* color: #E3E3E3; */
  /* border: 2rpx solid #999; */
  width: 90%;
  word-break: keep-all;
  word-wrap: break-word;
}
.MCQ{
  padding: 20rpx;
  border: 2rpx solid #999;
}

.MCQText{
  margin-left: 20rpx;
  /* color: #E3E3E3; */
  /* border: 2rpx solid #999; */
  width: 90%;
  word-break: keep-all;
  word-wrap: break-word;
}

.SAQ{
  padding: 20rpx;
    border: 2rpx solid #999;
}

.SCQTitle{
  display: flex;
  flex-direction: row;
}

.MCQTitle{
  display: flex;
  flex-direction: row;
}

.SAQTitle{
  display: flex;
  flex-direction: row;
}

.MCQOption{
  display: flex;
  flex-direction: column;
  margin-top: 20rpx;
}

.SAQAnswer{
  border: 2px solid #999;
}

.SCQDiscription{
  /* border: 2rpx solid #999; */
  width: 90%;
  word-break: keep-all;
  word-wrap: break-word;
}

.MCQDiscription{
  /* border: 2rpx solid #999; */
  width: 90%;
  word-break: keep-all;
  word-wrap: break-word;
}

.SAQDiscription{
  /* border: 2rpx solid #999; */
  width: 90%;
  word-break: keep-all;
  word-wrap: break-word;
}

.SCQdeleteIcon{
  width: 80rpx;
  margin-left: 20rpx;
}

.MCQdeleteIcon{
  width: 80rpx;
  margin-left: 20rpx;
}

.SCQdeleteIcon1{
  width: 60rpx;
  margin-left: 20rpx;
}

.MCQdeleteIcon1{
  width: 60rpx;
  margin-left: 20rpx;
}

.SAQdeleteIcon{
  width: 60rpx;
  margin-left: 50rpx;
}

.SCQaddIcon1{
  width:60rpx;
  margin-left: 20rpx;
}

.MCQaddIcon1{
  width:60rpx;
  margin-left: 20rpx;
}

#body{
  margin-top: 100rpx;
}

.weui-btn{
  width: 50%;
  margin-bottom: 20rpx;
}



item.js

// pages/yaoxh6/item/item.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    priceIcon: "../../../images/price.png",
    currentFatherIndex: 0,
    questionnaireArray: [
      {
        "type": "SCQ",
        "content": {
          "description": "Which fruit do you like best?",
          "options":
            [
              { "id": 1, "name": "Lua", "isSelected": false },
              { "id": 2, "name": "Java", "isSelected": false },
              { "id": 3, "name": "C++", "isSelected": false }
            ]
        }
      },
      {
        "type": "MCQ",
        "content": {
          "description": "Which fruit do you like?",
          "options":
            [
              { "id": 1, "name": "OK", "isSelected": false },
              { "id": 2, "name": "Java", "isSelected": false },
              { "id": 3, "name": "C++", "isSelected": false }
            ]
        }
      },
      {
        "type": "SAQ",
        "content": {
          "description": "What's your name?",
          "answer": "i dont know"
        }
      }
    ],
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log(options.id)
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  // fun : function(){
  //   var q = {
  //     test: this.data.test,
  //     test2: this.data.test2
  //   }
  //   wx.cloud.callFunction({
  //     name: 'release_questionnaire',
  //     data: {
  //       content: JSON.stringify(q)
  //     },
  //     success: res => {
  //       // test = JSON.stringify(res)
  //       // this.setData({
  //       //   test : JSON.stringify(res.result.results.data[0].description)
  //       // })
  //       console.log('success')
  //     }
  //   })
  // },

  // fun2 : function(){
  //   wx.cloud.callFunction({
  //     name: 'get_all_questionnaire',
  //     success: res => {
  //       console.log(res)
  //       var last = res.result.results.data[8].content
  //       this.setData({
  //         test: JSON.parse(last).test
  //       })
  //       console.log('success')
  //     }
  //   })
  // }
  goBack : function(){
    console.log('to task page')
    wx.switchTab({
      url: '../task/task',
    })
  },

  getTempFatherIndex: function (input) {
    var tempFatherIndex = input.currentTarget.dataset.id;
    //console.log('currentFatherIndex: ' + tempFatherIndex);
    this.setData({
      currentFatherIndex: tempFatherIndex,
    });
  },
  
  radioChangeSCQ:function(input){
    var tempFatherIndex = this.data.currentFatherIndex;
    var tempArray = this.data.questionnaireArray;
    for (var i in tempArray[tempFatherIndex].content.options){
      if (tempArray[tempFatherIndex].content.options[i].name == input.detail.value){
        tempArray[tempFatherIndex].content.options[i].isSelected = true;
      }
      else{
        tempArray[tempFatherIndex].content.options[i].isSelected = false;
      }
    }
    this.setData({
      questionnaireArray: tempArray,
    });
  },

  checkboxChangeMCQ:function(input){
    // console.log(input.detail.value);
    var flag = false;
    var tempFatherIndex = this.data.currentFatherIndex;
    var tempArray = this.data.questionnaireArray;
    for (var i in tempArray[tempFatherIndex].content.options) {
      flag = false;
      for(var j in input.detail.value){
        if (tempArray[tempFatherIndex].content.options[i].name == input.detail.value[j]){
          flag = true;
        }
      }
      if(flag == true){
        tempArray[tempFatherIndex].content.options[i].isSelected = true;
      }
      else{
        tempArray[tempFatherIndex].content.options[i].isSelected = false;
      }
    }
    this.setData({
      questionnaireArray: tempArray,
    });
  },

  bindblurAnswerOfSAQ: function (input) {
    var tempIndex = input.currentTarget.dataset.id;
    var tempArray = this.data.questionnaireArray;
    tempArray[tempIndex].content.answer = input.detail.value;
    // console.log(tempArray[tempIndex].content);
    this.setData({
      questionnaireArray: tempArray,
    });
  },

  complete :function(){
    console.log(this.data.questionnaireArray);
  },
})



版权声明:本文为yaoxh6原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。