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


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

实现效果

界面功能

最后实现的界面如下
界面
最右上角的蓝色加号是增加一种新的题型,一共三种题型,单选,多选,问答。
题型
选择一种题型之后,点击确定,会下页面的下面生成一个新的题型。比如选择多选:
一开始是三种题型,单选,多选和问答,现在变成四个题目了。
新加多选
这些textarea里面的值都是默认设置的,所以新加的时候也会带有默认值,这是为了方便调试用的,正式用的时候都置为空就可以。

每个题型有个灰色加号(问答题没有),点击加号会增加该题型选项数量,比如在第二题再添加一项
增加选项
在灰色加号后面还要一个红底白叉,表示删除这一个题型,比如删除第三个,那么第四个就会自动变成第三个
删除第三个
如果选择每个题型的的选项后面的蓝色减号,那么就会删除这一项,比如删除Q2的第一项OK
删除Q2第一项
由于使用的是textarea,所以是支持自动换行以及自适应高度的(虽然模拟器的适配很不好看,但是真机调试的话是没问题的)。

数据功能

因为页面最后是要生成发向服务端的,所以最后要生成一个数据。
设计的数据结构是(其中id是暂时用不到的)

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

最终要实现的目的就是,改变问卷中的值,点击下一步的时候,可以自动生成适配的数据结构。
看一下效果
效果
接着上面的操作,点击下一步,直接打印出questionnaire,可以发现数据是设配的。
也可以改动每一项数据使得界面适配,比如在Q2的C++后面加几个哈哈哈,再点下一步,可以看到效果也是匹配的。
最后实现效果
PS:只是为了展示功能,至于其他的小问题可以自己手动改,比如没有显示是单选还是多选,因为这是发布问卷的时候,而不是做问卷的时候,所以不需要出现radiocheckbox,但是内部数据还是记录着,为了方便,可以手动在wxml上面添加具体的类别,这里SCQ代表单选题,MCQ代表多选题,SAQ代表问答题。

各个组件的实现

右上角的蓝色加号

<picker value="{
  {newIndex}}" range='{
  {typeArray}}' bindchange="bindTypeChange">
    <image class='addNewQuestion' src='{
  {addIconPath}}'></image>
</picker>

picker是微信小程序支持的原生组件,效果就是之前展示的,可以在底部生成选项,然后点击确定。在js里面有对应的代码。
这是数据绑定部分

    typeArray: ['单选', '多选', '问答'],
    newIndex: 0,
    addIconPath: "../../../images/addIcon.png",

这是逻辑部分

bindTypeChange:function(e){
    this.setData({
      newIndex: e.detail.value
    });
    console.log(e.detail.value);
    var tempArray = this.data.questionnaireArray;
    if(this.data.newIndex == 0){
      var temp0 = {
        "type": "SCQ",
        "content": {
          "description": "Which fruit do you like best?",
          "options":
            [
              { "id": 1, "name": "Lua", "isSelected": false },
            ]
        }
      };
      tempArray.push(temp0);
    }
    else if (this.data.newIndex == 1){
      var temp0 = {
        "type": "MCQ",
        "content": {
          "description": "Which fruit do you like best?",
          "options":
            [
              { "id": 1, "name": "Lua", "isSelected": false },
            ]
        }
      };
      tempArray.push(temp0);
    }
    else if (this.data.newIndex == 2){
      var temp0 = {
        "type": "SAQ",
        "content": {
          "description": "Which fruit do you like best?",
        }
      };
      tempArray.push(temp0);
    }
    this.setData({
      questionnaireArray: tempArray,
    });
  },

在点击确定的时候会触发bindchange函数,该函数首先通过e.detail.value改掉newIndex的值,来记录当前选中的是第几个选项,所有的数据修改都在this.setData({})中,这样变化会显示在界面中,还可以用this.data =这样的方式赋值,但是不会影响到界面,反而造成数据不一致性,所以不能这样用。得到newIndex之后通过该值判断,如果是0就生成单选题,如果是1就生成多选题,如果是2就生成问答题。通过var tempArray = this.data.questionnaireArray;取得中间变量,然后对中间变量操作,操作完再赋值回去,该项目的所有的改变数据的逻辑都遵循该逻辑,即先取中间变量,对中间变量操作,将中间变量赋值回去。

问卷结构部分

整体框架如下,其中questionnaireArray,就是整个问卷的数据,生成的页面其实是数据驱动的,通过改变数据自动生成问卷,而不是在js端生成wxml,所以只需要专注于数据即可。通过wx:forwx:if自动循环数据生成.
整体架构
当然我这里是二重循环,所以比一重循环更复杂一点,最后的结构是
二重循环结构

以单选部分举例

由于单选和多选类似,而问答部分只涉及一重循环,所以只说单选部分。单选部分的结果如下:

  <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>
        <textarea auto-height='true' class='SCQDiscription' value='{
  {item.content.description}}' bindblur='bindblurSCQ' data-id='{
  {fatherIndex}}'></textarea>
        <image class='SCQaddIcon1' src='{
  {addIconPath1}}' mode='widthFix' catchtap='addSCQ' data-id='{
  {fatherIndex}}'></image>
        <image class='SCQdeleteIcon1' src='{
  {deletePath1}}' mode='widthFix' catchtap='deleteSCQ' data-id='{
  {fatherIndex}}'></image>
      </view>
      <view class='SCQOption' wx:for="{
  {item.content.options}}" wx:key="SCQID" data-id='{
  {fatherIndex}}' bindtouchstart='getTempFatherIndex'>
        <!-- <image class='SCQselectIcon' src="{
  {item.isSelected?'../../../images/SAQ2.png':'../../../images/SAQ1.png'}}" mode='widthFix'></image> -->
        <textarea auto-height='true' value='{
  {item.name}}' class='SCQText' bindblur='bindblurOneOfSCQ' data-id='{
  {index}}'></textarea>
        <image class='SCQdeleteIcon' src='{
  {deletePath}}' mode='widthFix' data-id='{
  {index}}' catchtap='deleteOneOfSCQ'></image>
      </view>
    </view>
  </block>

其中有行image被注释掉了,那是显示是否被选中的,由于在填问卷的时候会直接使用微信小程序的控件radio-group以及checkbox-group,会自带图标,以及多选和单选的功能,所以这里就不加了,可以展示一下没有被注释的效果:
没有被注释的效果
注意到有这样的语句data-id='{ {fatherIndex}}',这是为该元素设置一个id,方便js找到具体的元素,由于在外层的循环中设置了wx:for-index='fatherIndex',所以下面再用fatherIndex的时候就是该值,如果不设置的话默认是indexwx:for默认的两个属性是index以及item,分别代表默认序号和对应的元素,而这个序号是根据数组中的位置变化的,比如已经有了4个元素编号从0-3,这时候删除第三个那么序号会变成0-2,而不是变成0,1,3。利用这种特性,删除的时候会方便很多。

每个题型的灰色加号

<image class='SCQaddIcon1&
  • 9
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值