layui 實現問卷表單【頁面數據渲染+答案提交】【前端完整代碼】

最近有個業務需求,需要做一個問卷表單
格式比較簡單:問題+radio選項,問題需要分組展示,數據需要從數據庫提取渲染。
細節較多

效果圖如下

下面發一下前端完整代碼(由於套用的是公司封裝的layui框架,layui的js請自己引入)

html+js


<body>
<div>
    <h1 id="headline">大標題</h1>
    <br/>
    <div class="fr">
        <button type="button" class="layui-btn" id="reset"><i class="layui-icon">&#xe666;</i>重置</button>
        <button type="submit" class="layui-btn" id="submit" lay-submit=""><i class="layui-icon">&#xe61f;</i>提交
        </button>
    </div>
<!--    用了layui的tpl模板引擎-->
    <div id="view"></div>
</div>
</body>

<script id="questionInfo" type="text/html">
    <div class="layui-row">
        <form class="layui-form">
            <ul>
<!--                對後臺傳過來的json數據進行遍歷-->
                {{# layui.each(d.data, function(index, item){ }}
<!--                問題分類(即二級標題)-->
                <blockquote style=" text-align: left " class="layui-elem-quote"><span
                        style="font-size: 18px;font-weight: bold">{{index+1}}.&nbsp;{{ item.secondTitle}}</span>
                </blockquote>
<!--                遍歷每二級標題下對應的問題-->
                <li class="layui-form-item" style=" text-align: left;margin-left: 20px">
                    {{# layui.each(item.list, function(key, value){ }}
                    <label style="font-size: 18px;font-weight: normal"> <span>{{index+1}}.{{key+1}}&nbsp;&nbsp;{{ value.question}} </span></label>

<!--                問題提示功能,用了bootstrap的popover組件,若不需要可自行刪除-->
                    <button class="layui-btn " type="button" data-toggle="popover" data-container="body"
                            data-placement="right" data-content="{{value.notes}}" οnclick="hide()"
                            style=" height: 18px;line-height: 18px;padding: 0 8px;font-size: 10px">提示
                    </button>

                    <div class="checkList">
<!--                根據我的客戶需求,需要在渲染頁面的時候,如果之前有過問卷提交記錄,則radio自動渲染出上次所選的選項-->
                        <input type="radio" name="{{ value.id}}" lay-verify="required" required
                               {{value.score=="1"?"checked":""}} value="1" title="準備實施"/>
                        <input type="radio" name="{{ value.id}}" lay-verify="required" required
                               {{value.score=="2"?"checked":""}} value="2" title="正在實施"/>
                        <input type="radio" name="{{ value.id}}" lay-verify="required" required
                               {{value.score=="3"?"checked":""}} value="3" title="已經實施"/>
                    </div>
                    {{# }); }}
                </li>
                {{# }); }}
            </ul>
        </form>
    </div>
</script>
<script>
    function hide() {//這個函數用來控制popover插件幾秒後消失,這裏是1500ms
        setTimeout(function () {
            $("[data-toggle='popover']").popover('hide');
        }, 1500);
    }
</script>

<script src="${ctxPath}/static/js/jquery-2.1.3.min.js"></script>
<script src="${ctxPath}/static/js/bootstrap.min.js"></script>
<script>
    layui.use(['form', 'laytpl', 'layer'], function () {
        var  $ = layui.jquery
            , form = layui.form
            , layer = layui.layer
            , laytpl = layui.laytpl;
        form.render();

        //把每項問題的Id和其所選值存入map
        var map1 = new Map();

        //map轉json(map -> object -> json)
        function MapToJson(map) {
            let obj = Object.create(null);
            for (let [k, v] of map) {
                obj[k] = v;
            }
            return obj;
        }

        var questionNumber = 0;

        //獲取後臺數據
        $.ajax({
            url: "/tbQuestionRecord/getQuestion",
            datatype: "json",
            type: "GET",
            async: false,//關閉異步,否則popover組件無法渲染出值
            context: document.body,
            success: function (data) {
                for (var i in data.data) {
                    questionNumber += data.data[i].list.length;
                }
                var getTpl = questionInfo.innerHTML
                    , view = document.getElementById('view');
                laytpl(getTpl).render(data, function (html) {
                    view.innerHTML = html;
                });
                form.render();
            }
        })

        var TbQustionTechnologyInfo = {};
        //按鈕操作
        TbQustionTechnologyInfo.initButton = function () {
                //提交信息
            $("#submit").click(function () {
                $.each($('.checkList').find('input'), function (i, n) {
                    $(n)
                });
                // 在提交之前需要遍歷一遍所有的radio選項,並把所選對應值存入map,如果有漏選的,則提交不成功
                var dataList = $('.checkList').find('input');
                for (var b = 0; b < dataList.length; b++) {
                    if ($(dataList[b]).prop('checked')) {
                        console.log($(dataList[b]).prop('checked'));
                        map1.set($(dataList[b])[0].name, $(dataList[b])[0].defaultValue);
                    }
                }
                if (questionNumber == map1.size) {

                } else {
                    layer.msg("請填寫完所有選項");
                    return false;
                }
                $.ajax({
                    url:"/tbQuestionRecord/saveAnswer",
                    contentType:"application/json",
                    data:{
                        map: MapToJson(map1),
                        treeId: 1,
                    },
                    success:function (data) {
                        if (data.code == "200") {
                            alert(data.message);
                        } else if (data.code == "500") {
                            alert(data.message);
                        }
                    }
                })
            });

            //重置
            $("#reset").click(function () {
                window.location.reload();
            });
        }

        $(function () {
            TbQustionTechnologyInfo.initButton();   //初始化按鈕操作
            form.render();
            $("[data-toggle='popover']").popover();
        });
    });
</script>

下面是前臺調用到的json數據格式

{
  "data": [
    {
      "secondTitle": "問題分類第一組",
      "list": [
        {
            //每個問題所屬於的二級菜單的Id(即secondTitle的Id)
          "belongdemand": "2bf6a3191f5846629957d2974f879a9a",
            //問題Id
          "id": "19f26b2f364649c0958960870c5dcdb7",
            //問題的備註
          "notes": "1",
            //問題
          "question": "問題1.1",
            //問題所得分數
          "score": "1",
            //問題的前後排序
          "showorder": 5
        },
        {
          "belongdemand": "2bf6a3191f5846629957d2974f879a9a",
          "id": "840339d2c64044129553542fab9ceb4b",
          "notes": "2",
          "question": "問題1.2",
          "score": "2",
          "showorder": 7
        },
        {
          "belongdemand": "2bf6a3191f5846629957d2974f879a9a",
          "id": "6e31f891fb5745179897bd8b79b58ee7",
          "notes": "4",
          "question": "問題1.3",
          "score": "2",
          "showorder": 9
        }
      ]
    },
    {
      "secondTitle": "問題分類第二組",
      "list": [
        {
          "belongdemand": "e55cb74dc159437ca35d47461f8efe02",
          "id": "1143d2c1c3914f95b032c92dc27d84d9",
          "notes": "達瓦大挖的",
          "question": "問題2.1",
          "score": "",
          "showorder": 1
        },
        {
          "belongdemand": "e55cb74dc159437ca35d47461f8efe02",
          "id": "d22a6e1d6fbd4bf785b26715c315272f",
          "notes": "達瓦打算達瓦w",
          "question": "問題2.2",
          "score": "",
          "showorder": 2
        }
      ]
    }
  ]
}

由於業務需求不同,後端基本都是增刪改查,就不放代碼了。

如果遇到什麼問題或代碼有不對的地方,煩請指出和留言

 

開發過程中遇到的一些問題:

1.如何通過layui模板引擎循環遍歷顯示題目

2.如何在網頁加載後顯示上次提交的問題答案

3.如何在每次提交時拿到問題的所選答案,(我用的是map存放問題id和所選答案),並要求不能有漏選問題,否則無法提交。

 

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