iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 25
0
Modern Web

30天學習Spring MVC系列 第 25

Day 25 Spring Boot 利用thymeleaf模板引擎與jquery.dataTables.js製作列表頁[View層篇]

前言

這一篇主要介紹有關thymeleaf的配置與標籤,其實不論是jsp或使用thymeleaf我們經常會用到的就是判斷,取值與Iteration的使用其他的就屬於較為客製化的操作,本篇主要用簡單的應用來完成一個列表頁,基本上在網頁上的元素越簡單越好,後台只要清晰的設計讓使用者知道如何操作達到目的就可以了!
dataTables.js是jQuery相關的套件,我們主要是要利用這個套件來幫助我們完成一個Table並簡單介紹常用的屬性

利用thymeleaf取出List內的value

1.第一步:將訪問完數據的List add到model物件中

@GetMapping("/memberList")
    public String memberListPage(Model model){
		memberAccountList = memberRepository.findAll();
		model.addAttribute("memberAccountList", memberAccountList);
        return "member/memberListPage";
    }   

介紹jquery.dataTables.js

dataTables.js他有強大的功能可以將表格轉換成一個有互動性的動態表格,ex:他有排序,搜尋,過濾及支援ajax,還有自動分頁的功能,如果你想更了解jquery.dataTables.js可以到官網參考他們的文件

(https://datatables.net/ )

製作一個會員管理列表頁

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>會員管理</title>

    <!-- Bootstrap Core CSS -->
    <link th:href="@{/vendor/bootstrap/css/bootstrap.min.css}" href="../vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

    <!-- MetisMenu CSS -->
    <link th:href="@{/vendor/metisMenu/metisMenu.min.css}" href="../vendor/metisMenu/metisMenu.min.css" rel="stylesheet">

    <!-- DataTables CSS -->
    <link th:href="@{/vendor/datatables-plugins/dataTables.bootstrap.css}" href="../vendor/datatables-plugins/dataTables.bootstrap.css" rel="stylesheet">

    <!-- DataTables Responsive CSS -->
    <link  th:href="@{/vendor/datatables-responsive/dataTables.responsive.css}" href="../vendor/datatables-responsive/dataTables.responsive.css" rel="stylesheet">

    <!-- Custom CSS -->
    <link th:href="@{/dist/css/sb-admin-2.css}" href="../dist/css/sb-admin-2.css" rel="stylesheet">

    <!-- Custom Fonts -->
    <link th:href="@{/vendor/font-awesome/css/font-awesome.min.css}" href="../vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
	

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>

<body>

    <div id="wrapper">

        <!-- Navigation -->
        <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="index.html">後端管理系統</a>
            </div>

            <!-- /.navbar-static-side -->
            <div class="navbar-default sidebar" role="navigation">
                <div class="sidebar-nav navbar-collapse">
                    <ul class="nav" id="side-menu">
                         <li>
                            <a href="#"><i class="fa fa-wrench fa-fw"></i> 功能列表<span class="fa arrow"></span></a>
                            <ul class="nav nav-second-level">
<!--                                 <li> -->
<!--                                     <a href="http://localhost:8080/menu/menuList">選單管理</a> -->
<!--                                 </li>  -->
                                <li>
                                    <a href="http://localhost:8080/member/memberList">會員管理</a>
                                </li>                              
                            </ul>
                            <!-- /.nav-second-level -->
                        </li>
                   	</ul>
               </div>
            </div>
        </nav>

        <div id="page-wrapper">
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">會員列表管理</h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            	清單
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            <table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-example">
                                <thead>
                                    <tr>
                                        <th>序號</th>
                                        <th>姓名</th>
                                        <th>信箱</th>
                                        <th>行動電話</th>
                                        <th>地址</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr th:each="memberAccount:${memberAccountList}" class="odd gradeX">
                                        <td th:text="${memberAccount.id}"></td>
                                        <td th:text="${memberAccount.Chinese_name}"></td>
                                        <td th:text="${memberAccount.email}"></td>
                                        <td th:text="${memberAccount.cellphone}"></td>
                                        <td th:text="${memberAccount.address}"></td>
                                    </tr>                                                                                               
                                </tbody>
                            </table>
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-12 -->
            </div>            
        </div>
        <!-- /#page-wrapper -->
    </div>
    <!-- /#wrapper -->

    <!-- jQuery -->
    <script  th:src="@{/vendor/jquery/jquery.min.js}" src="../vendor/jquery/jquery.min.js"></script>

    <!-- Bootstrap Core JavaScript -->
    <script  th:src="@{/vendor/bootstrap/js/bootstrap.min.js}" src="../vendor/bootstrap/js/bootstrap.min.js"></script>

    <!-- Metis Menu Plugin JavaScript -->
    <script  th:src="@{/vendor/metisMenu/metisMenu.min.js}" src="../vendor/metisMenu/metisMenu.min.js"></script>

    <!-- DataTables JavaScript -->
    <script  th:src="@{/vendor/datatables/js/jquery.dataTables.min.js}" src="../vendor/datatables/js/jquery.dataTables.min.js"></script>
    <script  th:src="@{/vendor/datatables-plugins/dataTables.bootstrap.min.js}" src="../vendor/datatables-plugins/dataTables.bootstrap.min.js"></script>
    <script  th:src="@{/vendor/datatables-responsive/dataTables.responsive.js}" src="../vendor/datatables-responsive/dataTables.responsive.js"></script>
	<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js">
    <!-- Custom Theme JavaScript -->
    <script th:src="@{/dist/js/sb-admin-2.js}" src="../dist/js/sb-admin-2.js"></script>
	
    <!-- Page-Level Demo Scripts - Tables - Use for reference -->
    <script>
    $(document).ready(function() {
        $('#dataTables-example').DataTable({
        	dom: 'Bfrtip',
        	buttons: [
                {
                    text: '全選',
                    action: function ( e, dt, node, config ) {
                       	checkAll();
                    }
                },
                {
                    text: '新增',
                    action: function ( e, dt, node, config ) {
                        location.href="http://localhost:8080/member/addMemberPage"
                    }
                },
                {
                    text: '刪除',
                    action: function ( e, dt, node, config ) {
                        deleteMember();
                    }
                }
             ],
        	"paging":   false,
            "ordering": false,
            "info":     false,
            "language": {
                "zeroRecords": "目前無資料",
                "info": "會員清單",
                "infoEmpty": "找尋不到相關資料",
                "sSearch": "搜尋: "
            }
            
               
        });
    });
    </script>

</body>

</html>

thymeleaf屬性介紹

1.如果我們不想每次運行Spring Boot應用程式頁面就將我們的搜尋結果快取的話,我們可以application.properties新增

spring.thymeleaf.cache=false

2.我們利用 th:each屬性將object,利用iterator方式將值給取出直到最後一筆為止

<tr th:each="memberAccount:${memberAccountList}" class="odd gradeX">
<td th:text="${memberAccount.id}"></td>

3.thymeleaf 標準表達式(Standard Expression Syntax)
1.一般變數表達式(Variable Expressions) ex:${id}
2.連結表達式(Link URL Expressions): ex:@{/vendor/bootstrap/css/bootstrap.min.css}
3.區域範圍表達式(Selection Variable Expressions): *{} ex:

  <form role="form" id="loginForm" method="post" enctype="multipart/form-data" th:action="@{/doLogin}" th:object="${memberAccountJPA}">
                            <fieldset>
                                <div class="form-group">
                                    <input class="form-control" placeholder="E-mail" id="email" th:field="*{email}" type="email" autofocus=""/>
                                </div>
                                <div class="form-group">
                                    <input class="form-control" placeholder="Password" id="password" th:field="*{password}" type="password" />
                                </div>
<!--                                 <div class="checkbox"> -->
<!--                                     <label> -->
<!--                                         <input name="remember" type="checkbox" value="Remember Me">Remember Me -->
<!--                                     </label> -->
<!--                                 </div> -->
                                <!-- Change this to a button or input when using this as a form -->
                                <a onclick="checkLogin()" class="btn btn-lg btn-success btn-block">登錄</a>
                            </fieldset>
                        </form>

4.訊息表達式(Message Expressions): #{...}
5.判斷表達式(Conditional operators):
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
ex: if id==1 中獎 else 沒中獎 -> th:if="${memberAccount.id}==1">中獎
th:unless="${memberAccount.id}==1">沒中獎
if 是當 value=? 就做... unless則是當 value = ? 就不做

dataTables.js屬性介紹

  • dom: dataTables.js 會依照 dom的配置依序將dataTables的屬性按照順序從上而下的渲染,也可以制定不想要出線的屬性,ex:f代表filter t代表table 'ft' 與'tf'兩個順序不一樣的話他們的位置也會不一樣
    buttons : 我在本範例中自己定義了三個按鈕,關於按鈕你要在去額外的下載button的js才會顯示,在程式碼的
	<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js">
  • button屬性:
    1.text : 按鈕上文字
    2.function : 我們可以自訂觸發此按鈕要執行的function
    3.button還有一些常用的API已經撰寫好的可以使用詳細請參照以下網址(https://datatables.net/extensions/buttons/ )
  • paging:分頁功能 true:啟用 false:關閉
  • ordering :排序功能 true:啟用 false關閉
  • info : 表格的infomation true:啟用 false 關閉
  • language : 相關提示文字 ex:filter前的提示文字,當搜尋資料為空的提示文字等
    1.zeroRecords
    2.info : 預設顯示 Showing page start 筆數 to page end筆數 of 57 entries(共有幾筆資料)
    3.infoEmpty :當資料為0筆要帶入的文字
    4.sSearch : filter前的提示文字

範例Demo

https://ithelp.ithome.com.tw/upload/images/20180113/20107812F4yTukU3o5.png

重點與心得

1.製作頁面我們可以尋找適合的js來幫助我們開發一些功能,但是這些到最後都是沒辦法客製化,會比較沒彈性,建議還是以react或其他的前端框架去撰寫js來控制我們的前台屬性顯示,但是有些時候我們並沒有辦法有太多時間開發前台與後台,要你兩邊併行雙修都做的話根本在企業上要開發的時程會非常的長,不太能允許這種事情發生
2.如果你會jsp的jstl相關標籤使用我建議你也可以使用jsp去做view層的顯示,thymeleaf雖然對Spring Boot的支援性很好但是有時我們也會需要使用動態語言來完成我們的需求


上一篇
Day24 Spring MVC例外處理篇(Exception Handling in Spring MVC)[下]
下一篇
Day26 Spring Boot WebSocket 製作一個簡單的聊天室(上)
系列文
30天學習Spring MVC30

尚未有邦友留言

立即登入留言