1. 需求
开发一个“调查问卷”的案例来学习常用表单组件的使用,收集用户填写胡表单信息提交给服务器,或者从服务器获取数据后显示在表单中。调查问卷分为单选、多选、单行填空、多行填空,选项为必填时候,提交弹出必填项未提交提示。
2. 完整代码
2.1. questionnaire.wxml
<view class="quest_layout">
<view wx:for="{{quest}}" wx:key="id" wx:for-index="outterIndex">
<!-- 标题 -->
<view class="quest_item_title">
<view class="{{((item.isMust=='Y'))?'quest_item_mark_red':'quest_item_mark_invisible'}}">*</view>
<text>{{outterIndex+1}}.</text>
<text wx:if="{{item.type==1}}">(单选)</text>
<view wx:else="">
<text wx:if="{{item.type==2}}">(多选)</text>
<text wx:else="">(填空)</text>
</view>
<text>{{item.question}}</text>
</view>
<!-- 选项(单选、多选) -->
<view wx:if="{{(item.type==1)||(item.type==2)}}">
<view class="quest_item_option_layout {{item.selected?'quest_item_option_active':''}}" wx:for="{{item.answers}}" wx:key="content" bindtap="answerSelected" data-outidx='{{outterIndex}}' data-idx="{{index}}">
<text>{{item.index}}.</text>
<text> {{item.content}}</text>
</view>
</view>
<!-- 单行填空 -->
<view wx:if="{{item.type==3}}">
<input class="quest_item_inpt_layout" bindinput='inputWatch' data-index='{{outterIndex}}' type='text' placeholder='请填写{{item.question}}'></input>
</view>
<!-- 多行填空 -->
<view wx:if="{{item.type==4}}" class="item_input_area_layout">
<textarea class="item_input_area_content" bindinput="inputWatch" data-index='{{outterIndex}}' rows="5" cols='0' placeholder="请输入{{item.question}}" maxlength="1000">
</textarea>
</view>
</view>
<view class="submit_btn" bindtap="submit">提交</view>
</view>
2.2. questionnaire.wxss
/* pages/questionnaire3/questionnaire3.wxss */
page {
background-color: #eeeeee;
padding: 20rpx 0;
}
.quest_layout {
overflow: hidden;
width: 90%;
margin: 20rpx 2.6%;
padding: 20rpx;
background-color: white;
border-radius: 20rpx;
}
.quest_item_title {
display: flex;
flex-direction: row;
color: #000000;
font-size: 34rpx;
margin-top: 30rpx;
}
.quest_item_mark_red {
color: red;
}
.quest_item_mark_invisible {
color: #00000000;
}
.quest_item_option_layout {
color: #000000;
font-size: 32rpx;
margin-top: 10rpx;
}
.quest_item_option_active {
color: red;
}
.quest_item_inpt_layout {
color: #333;
font-size: 32rpx;
border: solid 1rpx #e1e1e1;
margin-top: 10rpx;
padding: 10rpx 10rpx;
border-radius: 8rpx;
}
.item_input_area_layout {
border: 1rpx solid #e1e1e1;
border-radius: 10rpx;
padding: 8px;
margin-top: 10rpx;
}
.item_input_area_content {
width: 100%;
height: 200rpx;
color: #333;
font-size: 32rpx;
overflow-y: scroll;
}
.submit_btn {
background: #00a050;
color: white;
margin: 50rpx;
padding: 25rpx;
border-radius: 10rpx;
text-align: center;
}
2.3. questionnaire.js
import questionnaireJson from '../../public/json/questionnaireJson';
Page({
/**
* 页面的初始数据
*/
data: {
quest: questionnaireJson.data.quest
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 点击(单选、多选)问题答案触发事件
*/
answerSelected(e) {
let outidx = e.currentTarget.dataset.outidx;
let idx = e.currentTarget.dataset.idx;
let question = this.data.quest[outidx];
if (question.type == 1) { //单选
for (let item of question.answers) {
item.selected = false;
}
question.answers[idx].selected = true;
this.setData({
quest: this.data.quest
});
} else if (question.type == 2) { //多选
question.answers[idx].selected = !question.answers[idx].selected;
this.setData({
quest: this.data.quest
});
}
},
/**
* 监听输入
*/
inputWatch: function (e) {
var that=this;
var index = e.currentTarget.dataset.index
var value = e.detail.value
that.data.quest[index].answers=value
},
// 点击提交按钮
submit() {
let {
quest
} = this.data;
//用来保存选中的答案
let answerSelected = [];
console.log("=quest=", quest);
for (let questItem of quest) {
if (questItem.type == 1) { //处理单选题
let isSelected = false;
for (let answerItem of questItem.answers) {
if (answerItem.selected) {
//答案被选中
isSelected = true;
var itemObj = {}
itemObj.key = questItem.id
itemObj.value = answerItem.index
answerSelected.push(itemObj);
}
}
if (!isSelected) { //如果一个都没选
if (questItem.isMust == 'Y') {
wx.showToast({
title: questItem.question + '必须选择',
icon: 'none'
})
return
} else {
var itemObj = {}
itemObj.key = questItem.id
itemObj.value = ''
answerSelected.push(itemObj);
}
}
} else if (questItem.type == 2) { //处理多选题
let isSelected = false;
var itemValue = ''
var itemObj = {}
itemObj.key = questItem.id
for (let answerItem of questItem.answers) {
if (answerItem.selected) { //答案被选中
isSelected = true;
if (itemValue) {
itemValue = itemValue + ',' + answerItem.index
} else {
itemValue = itemValue + answerItem.index
}
}
}
itemObj.value = itemValue
answerSelected.push(itemObj);
if (!isSelected) { //如果一个都没选
if (questItem.isMust == 'Y') {
wx.showToast({
title: questItem.question + '必须选择',
icon: 'none'
})
return
}
answerSelected.push(itemObj);
}
} else if (questItem.type == 3) { //处理单行填空题
if (questItem.isMust == 'Y') {
if(!questItem.answers){
wx.showToast({
title: questItem.question + '必须填写',
icon: 'none'
})
return
}
}
var itemObj = {}
itemObj.key = questItem.id
itemObj.value = questItem.answers
answerSelected.push(itemObj);
} else if (questItem.type == 4) { //处理多换填空题
if (questItem.isMust == 'Y') {
if(!questItem.answers){
wx.showToast({
title: questItem.question + '必须输入',
icon: 'none'
})
return
}
}
var itemObj = {}
itemObj.key = questItem.id
itemObj.value = questItem.answers
answerSelected.push(itemObj);
}
}
console.log(answerSelected);
},
})
2.4. questionnaireJson.js
const data = {
quest: [
{
id: 1,
type: 1, //类型,1.单选,2.多选
isMust: 'Y',
question: "你有女朋友吗?",
answers: [{
index: 'A',
content: '有'
}, {
index: 'B',
content: '没有'
}]
},
{
id: 2,
type: 1,
isMust: 'N',
question: "目前薪资在哪个范围?",
answers: [{
index: 'A',
content: '3-6k'
}, {
index: 'B',
content: '6-8k'
}, {
index: 'C',
content: '8-10k'
}, {
index: 'D',
content: '10k以上'
}]
},
{
id: 3,
type: 2,
isMust: 'Y',
question: "你喜欢哪一种编程语言?",
answers: [{
index: 'A',
content: 'Java'
}, {
index: 'B',
content: 'C语言'
}, {
index: 'C',
content: 'PHP'
}, {
index: 'D',
content: 'Python'
}, {
index: 'E',
content: 'JavaScript'
}, {
index: 'F',
content: '其他'
}]
},
{
id: 4,
type: 3,
isMust: 'Y',
question: "身份证号",
answers: ''
},
{
id: 5,
type: 3,
isMust: 'N',
question: "联系等方式",
answers: ''
},
{
id: 6,
type: 4,
isMust: 'Y',
question: "其他建议",
answers: ''
}
]
}
module.exports = {
data: data,
}