我們之前三篇文章實作了模闆+題目+選項的增删,現在我們要完成答題管理系統的答題子產品啦。
一.UI及功能設計
既然是使用者答題,就要有一張表專門用來存放使用者答題的答案。我的設想是這樣的,我們點選答題按鈕的時候,就顯示出第一題,判斷是否是模闆下最後一題,來顯示名為next按鈕的字型樣式為下一題還是完成。并且,對背景傳過來的qsn_type進行區分,type=0的單選顯示單選框,type=1的多選顯示複選框,type=2的問答顯示文本域,大概是如下效果。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuImN4YTM3ADN4kjN0YGZmJ2NxQGMlVTM5ATM3MjNmVGMfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
單選.PNG
多選.PNG
問答.PNG
為此,next按鈕要傳回的json格式資料如下。
建構json.PNG
用PHP構造一個二維關聯數組,其中二維數組中,還有一個二維數組,第一索引表示題目的order_num排序,第二索引表示option_num選項内容以及order_num選項排序号,最後将這個内層二維數組與别的參數使用PHP的array_merge函數進行數組合并,傳回給html頁面。
二.資料庫表設計(psg_qsn_r表)
psg_qsn_r表.PNG
主要的就是choose對應使用者選擇的選項,1,2,3...對應A,B,C,如果是問答,存的就是一串字元串。
三.代碼實作
首先是answer答題按鈕的點選監聽:
$('#btn-answer').click(function() {
// alert(id_array);
layer.msg('加載中', {
icon: 16,
shade: 0.01,
time: '9999999'
});
var url = "{:url('survey/answer_list')}";
var data = {
model_id: id_array //這裡将目前的model_id數組傳到後端
}
$.post(url, data, function(data) {
layer.close(layer.index); //關閉正在加載中彈出層
console.log(id_array);
if (data.code == 1) {
// alert(data.data[0].option_num);
if (data.data.bool_num == true) {
$('#next').text("完成");
}
$('#set-answer label[name="qsn_content1"]').css("width", "200px");
$('#set-answer label[name="qsn_content1"]').text(data.data.content);
if (data.data.qsn_type == 1) {
$.each(data.data, function(i, item) {
if (item.order_num == null) return false; //function中無法用break跳出 我們用return
//這邊要将type也傳過來 然後根據type來往anser_list中添加值
$('#answer_list').append(
// ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
'<div class ="layui-input-block"><input type="checkbox" lay-skin="primary" name="checkbox[]" value="' + item.order_num + '" title="' + letter[item.order_num - 1] + ' : ' + item.option_num + '"></div>'
)
});
form.render('checkbox');
} else if (data.data.qsn_type == 0) {
$.each(data.data, function(i, item) {
if (item.order_num == null) return false; //function中無法用break跳出 我們用return
//這邊要将type也傳過來 然後根據type來往anser_list中添加值
$('#answer_list').append(
// ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
'<div class ="layui-input-block"><input type="radio" lay-skin="primary" name="checkbox[]" value="' + item.order_num + '" title="' + letter[item.order_num - 1] + ' : ' + item.option_num + '"></div>'
)
});
form.render('radio');
} else if (data.data.qsn_type == 2) {
// if (item.order_num == null) return false; //function中無法用break跳出 我們用return
//這邊要将type也傳過來 然後根據type來往anser_list中添加值
$('#answer_list').append(
// ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
' <div class ="layui-input-block"><textarea name="text" id="text" required lay-verify="required" placeholder="請輸入" class="layui-textarea"></textarea>'
)
form.render();
}
// alert(data.data.order_num);
getqsn_type(data.data.qsn_type);
getmodel_id(data.data.model_id);
getorder_num(data.data.order_num);
layer.open({
type: 1,
skin: 'layui-layer-rim', //加上邊框
area: ['660px', '350px'], //寬高
content: $('#set-answer'),
cancel: function(index, layero) {
$('#answer_list').empty();
$('#next').text("下一題");
layer.close(index)
return false;
},
end: function() {
$('#answer_list').empty();
$('#next').text("下一題");
layer.closeAll();
}
});
} else {
layer.msg(data.msg, {
icon: 5
});
}
}, "json");
});
其中有對問題類型進行判别,并且對next樣式作更改,然後是其對應的Controller層:
public function answer_list()
{//答題的首次加載
$model_id = input('post.model_id/a'); //tp5送出數組用/a來實作
if (empty($model_id)) {
returnjson([3, '請選擇模闆答題', '']);
}
$str_device_id = implode(',', $model_id); //數組拆分
$where['model_id'] = array('in', $str_device_id);
$qsn_list = db('qsn')->where($where)->order('order_num')->field('content,qsn_id,order_num,model_id,qsn_type')->select(); //擷取問題内容
if (empty($qsn_list)) {
returnjson([2, '暫無題目,無法答題', '']);
}
$bool_num = false;
$max_order_num = db('qsn')->where($where)->max('order_num');
if ($qsn_list[0]['order_num'] == $max_order_num) {
$bool_num = true;
}
// $where1['qsn_id']=$qsn_list[0]['qsn_id'];
// // $qsn_list[0]['qsn_id存在
$option_list = db('qsn_detail')->where('qsn_id', $qsn_list[0]['qsn_id'])->field('option_num,order_num')->select(); //擷取選項以及選項排序
//array_merge()合成兩個數組
if ($option_list) {
$return_list = array_merge($qsn_list[0], $option_list);
$return_list['bool_num'] = $bool_num;
returnjson([1, 'success', $return_list]);
} else {//那就不是選項了 是問答題
$return_list = $qsn_list[0];
$return_list['bool_num'] = $bool_num;
returnjson([1, '問答題', $return_list]);
}
}
然後是View層next按鈕的監聽事件,跟這個差不多。
$('#next').click(function() {
var qsn_type = t_qsn_type;
var is_answered = false;
if (qsn_type == 1) {
var count = $("#set-answer input[type='checkbox']:checked").length
if (count == 0) {
is_answered = true;
}
$("#set-answer input[type='checkbox']:checked").each(function() {
choice.push($(this).val());
});
} else if (qsn_type == 0) {
var count = $("#set-answer input[type='radio']:checked").length
if (count == 0) {
is_answered = true;
}
$("#set-answer input[type='radio']:checked").each(function() {
choice.push($(this).val());
});
} else if (qsn_type == 2) {
var count = $("#set-answer #text").length
if (count == 0) {
is_answered = true;
}
$("#set-answer #text").each(function() {
choice.push($(this).val());
});
}
if (is_answered == true) {
layer.msg('請選擇答案');
return;
}
alert(choice);
layer.msg('加載中', {
icon: 16,
shade: 0.01,
time: '9999999'
});
alert(choice);
var url = "{:url('survey/next_qsn')}";
var t_choice = choice;
var model_id = t_model_id;
var order_num = t_order_num;
var data = {
model_id: model_id,
order_num: order_num,
choice: t_choice,
qsn_type: qsn_type
}
$.post(url, data, function(data) {
layer.close(layer.index); //關閉正在加載中彈出層
form.render(null, 'answer');
choice = [];
console.log(id_array);
if (data.code == 1) {
if (data.data.bool_num == true) {
$('#next').text("完成");
}
// alert(data.data[0].option_num);
$('#answer_list').empty();
$('#set-answer label[name="qsn_content1"]').text(data.data.content);
// alert(data.data.order_num);
if (data.data.qsn_type == 1) {
$.each(data.data, function(i, item) {
if (item.order_num == null) return false; //function中無法用break跳出 我們用return
$('#answer_list').append(
// ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
'<div class ="layui-input-block"><input type="checkbox" lay-skin="primary" name="sex" value="' + item.order_num + '" title="' + letter[item.order_num - 1] + ' : ' + item.option_num + '"></div>'
)
});
form.render('checkbox');
} else if (data.data.qsn_type == 0) {
$.each(data.data, function(i, item) {
if (item.order_num == null) return false; //function中無法用break跳出 我們用return
//這邊要将type也傳過來 然後根據type來往anser_list中添加值
$('#answer_list').append(
// ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
'<div class ="layui-input-block"><input type="radio" lay-skin="primary" name="checkbox[]" value="' + item.order_num + '" title="' + letter[item.order_num - 1] + ' : ' + item.option_num + '"></div>'
)
});
form.render('radio');
} else if (data.data.qsn_type == 2) {
$('#answer_list').append(
// ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
' <div class ="layui-input-block"><textarea name="text" id="text" lay-verify="required" placeholder="請輸入" class="layui-textarea"></textarea>'
)
form.render();
}
getqsn_type(data.data.qsn_type);
getmodel_id(data.data.model_id);
getorder_num(data.data.order_num);
} else if (data.code == 2) {
layer.msg(data.msg, {
icon: 6
});
setTimeout('layer.closeAll()', 2000);
} else if (data.code == 3) {
layer.msg(data.msg, {
icon: 5
});
}
}, "json");
然後是Controller層代碼。
//找出同一套模闆下的order_num+1的題目
public function next_qsn()
{
$model_id = input('post.model_id');
$order_num = input('post.order_num');
$choice = input('post.choice/a');
$count_choice = count($choice);
$str_choice1 = implode('', $choice);
if (empty($str_choice1)) {
returnjson([3, '請答題', $choice]);
}
$qsn_type = (int) input('post.qsn_type');
$order_num = (int) $order_num;
$qsn_list = db('qsn')->where('model_id', $model_id)->where('order_num', $order_num)->field('content,qsn_id,order_num,model_id,flight_id,qsn_type')->find(); //擷取問題内容
$psg_list['qsn_id'] = $qsn_list['qsn_id'];
$psg_list['model_id'] = $qsn_list['model_id'];
$psg_list['flight_id'] = $qsn_list['flight_id'];
$psg_list['qsn_type'] = $qsn_list['qsn_type'];
//這裡要改,這裡的detailID不是随機生成的 而是讀取出對應題目的detail_id
$option_list = db('qsn_detail')->where('qsn_id', $qsn_list['qsn_id'])->field('detail_id')->select();//這裡是二維數組
//這裡的detail ID和date就随機生成了
//這裡 我們應該count出option_list數組的長度,然後循環賦給psg_list中的detail_id,保證psg_qsn表中的detailID唯一
// returnjson([2, '恭喜您完成了答題', $option_list]);
$str_choice = implode(',', $choice);
for ($x = 0; $x < $count_choice; $x++) {
$psg_list['detail_id'] = $option_list[$x]['detail_id'];
$psg_list['psg_qsn_r_id'] = uniqid('psg_qsn_r_id', true);
$psg_list['choose'] = $choice[$x];
$psg_res = db('psg_qsn_r')->insert($psg_list);
}
//先要将目前問題插入psg_qsn表中 是以我們要先判斷 然後看看能否插入psg_qsn表 否則對應的字段就是下一個的字段
$order_num = $order_num + 1;
//隻查詢一個資料 用find 否則傳回的資料就是二維數組
$qsn_list = db('qsn')->where('model_id', $model_id)->where('order_num', $order_num)->field('content,qsn_id,order_num,model_id,flight_id,qsn_type')->find(); //擷取問題内容
$bool_num = false;
$max_order_num = db('qsn')->where('model_id', $model_id)->max('order_num');
if ($qsn_list['order_num'] == $max_order_num) {
$bool_num = true;
}
if (empty($qsn_list)) {
returnjson([2, '恭喜您完成了答題', $choice]);
}
//qsn_list已經是一個數組了
$option_list = db('qsn_detail')->where('qsn_id', $qsn_list['qsn_id'])->field('option_num,order_num')->select();
//一個bool_num來判單是否是最後一題
//
if ($option_list) {
$return_list = array_merge($qsn_list, $option_list);
$return_list['bool_num'] = $bool_num;
returnjson([1, 'success', $return_list]);
} else {//是文本域
$return_list = $qsn_list;
$return_list['bool_num'] = $bool_num;
returnjson([1, '問答', $return_list]);
}
}
然後我們看看最終的效果。
四.效果一覽
1.gif
OK,完成啦