LoginSignup
14
23

More than 5 years have passed since last update.

SpringBoot + BootStrap + DataTablesで選択画面を作成する

Last updated at Posted at 2018-04-21

選択ボタンで検索画面をモーダル表示して検索結果を親画面に反映するケースを検討します。

1.説明
(1) 解説
画面の入力では、マスタを検索して対象を選択するようなケースがあります。このような場合において、BootStrapのモーダルダイアログの機能と、DataTablesの一覧表示機能を使って実装する方法を検討します。

(2)全体イメージ
image.png
フォーム上のボタンを押して、モーダルウィンドウを表示します。一覧から対象のデータを選択するとフォームに選択したデータが入力された状態にします。
BootStrapのモーダルウィンドウを使います。

(3)モーダルダイアログの概念図
image.png

モーダルダイアログはjQuery DataTablesを使います。データは、Ajaxプロパティに、RestControllerからデータの一覧を返すという仕組みにします。ここでは、ユーザマスタ(Account)としています。

2.プロジェクトの構成

sample-modal
│  build.gradle
└─src
    └─main
        ├─java
        │  └─com
        │      └─stone
        │          └─ccc
        │                  Account.java
        │                  AccountRepository.java
        │                  DataTablesRestController.java
        │                  HeloController.java
        │                  SampleModalApplication.java
        │                  ServletInitializer.java
        └─resources
            │  application.properties
            │  hibernate.properties
            ├─static
            │  └─DataTables-1.10.16
            │      │  Japanese.json
            │      │  
            │      ├─css
            │      │      dataTables.bootstrap.min.css
            │      │      dataTables.bootstrap4.min.css
            │      │      dataTables.jqueryui.min.css
            │      │      jquery.dataTables.min.css
            │      └─js
            │              dataTables.bootstrap.min.js
            │              dataTables.bootstrap4.min.js
            │              dataTables.jqueryui.min.js
            │              jquery.dataTables.min.js
            └─templates
                    index.html
                    modalempselect.html

jQuery DataTablesのcss, jsをstaticの下に配置します。
index.htmlが親画面
modalempselectがモーダルになっています。

3.依存関係

build.gradle
dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.apache.commons:commons-lang3:3.7')
    compile('org.webjars:jquery:3.2.1')
    compile('org.webjars:jquery-ui:1.12.1')
    compile('org.webjars:bootstrap:4.0.0')
    compile('com.fasterxml.jackson.datatype:jackson-datatype-jsr310')
    runtime('org.springframework.boot:spring-boot-devtools')
    runtime('org.postgresql:postgresql')
    compileOnly('org.projectlombok:lombok')
    providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

4.DB接続設定

application.properties
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.username=testuser
spring.datasource.password=testuser
spring.jpa.hibernate.ddl-auto=none

DBは、postgresqlを使います。

hibernate.properties
hibernate.jdbc.lob.non_contextual_creation = true

postgresqlを使った場合にエラーが発生するのでこのpropertyを設定しておきます。

5.DB

account.sql
create table account (
  username character varying(64) not null
  , password character varying(255)
  , email character varying(64)
  , authority character varying(64)
  , primary key (username)
);
account_insert.sql
insert into account(username,password,email,authority)
values 
('admin','admin','admin@localhost','ROLE_ADMIN')
,('user','pass','user@localhost','ROLE_USER');

6.Entity

Account.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "account")
public class Account {
    @Id
    @Column(name="username")
    private String username;
    @Column(name="email")
    private String email;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}

7.Repository

AccountRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccountRepository extends JpaRepository<Account, String> {}

7.RestController

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DataTablesRestController {
    @Autowired
    AccountRepository Repo;
    @RequestMapping("/getaccountlist")
    public List<Account> getuserlist() {
        return Repo.findAll();
    }
}

jQuery DataTablesのajaxパラメータに渡すJsonの配列です。

8.Controller

HeloController.java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class HeloController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(Model model) {
        return "index";
    }
}

9.html
(1)フォーム

index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>モーダルダイアログ サンプル</title>
        <meta charset="utf-8" />
        <link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.min.css}" rel="stylesheet" />
        <script type="text/javascript" th:src="@{/webjars/jquery/3.2.1/jquery.min.js}"></script>
        <script type="text/javascript" th:src="@{/webjars/bootstrap/4.0.0/js/bootstrap.min.js}"></script>
        <link rel="stylesheet" th:href="@{/DataTables-1.10.16/css/jquery.dataTables.min.css}"/>
        <link rel="stylesheet" th:href="@{/DataTables-1.10.16/css/dataTables.bootstrap4.min.css}"/>
        <script type="text/javascript" th:src="@{/webjars/jquery-ui/1.12.1/jquery-ui.min.js}"></script>
        <script type="text/javascript" th:src="@{/DataTables-1.10.16/js/jquery.dataTables.min.js}"></script>
        <script type="text/javascript" th:src="@{/DataTables-1.10.16/js/dataTables.bootstrap4.min.js}"></script>
    </head>
    <body>
        <div class="container">
            <h2>モーダルダイアログ サンプル</h2>
            <div class="form-group">
                <label class="col-sm-2">username:</label>
                <input type="text" id="username" size="10"/>
            </div>
            <div class="form-group">
                <label class="col-sm-2">email:</label>
                <input type="text" id="email" size="20"/>
                <a class="form-control-sm bg-primary" id="empchange"
                    data-toggle="modal" data-target="#modal-emp-select">選択</a>
            </div>
        </div>
        <div th:replace="modalempselect::modalempselect"></div>
        <script th:inline="javascript">
        /*<![CDATA[*/
            $(document).on("click","#btn-modalemp-select", function() {
                $('#username').val(modalempdata.username);
                $('#email').val(modalempdata.email);
                $('#modal-emp-select').modal('hide');
            });
        /*]]>*/
        </script>
    </body>
</html>

point

<a class="form-control-sm bg-primary" id="empchange"
                    data-toggle="modal" data-target="#modal-emp-select">選択</a>

data-toggle="modal" data-target="#modal-emp-select"とするだけで、クリックしたらmodalが開きます。

(2)モーダル

modalempselect.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>モーダルダイアログ サンプル</title>
        <meta charset="utf-8" />
    </head>
    <body>
    <div th:fragment="modalempselect">
    <!-- モーダルの設定 -->
    <div class="modal" id="modal-emp-select" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h6 class="modal-title">従業員選択画面</h6>
                    <button type="button" class="close" data-dismiss="modal" aria-label="閉じる">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <table id="modal-emplist-table" class="table table-bordered table-hover table-lg">
                        <thead class="thead-light">
                            <tr>
                                <th>従業員番号</th>
                                <th>氏名</th>
                            </tr>
                        </thead>
                        <tbody>
                        </tbody>
                    </table>
                    <script th:inline="javascript">
                    /*<![CDATA[*/
                        var modalempdata = null;
                        $(function(){
                            // datatableの設定を変更
                            var modalemptable = $("#modal-emplist-table").DataTable({
                                "bPaginate": true,
                                "bLengthChange": false,
                                "bFilter": true,
                                "bSort": false,
                                "bInfo": false,
                                "bAutoWidth": false,
                                "language": {
                                    "url": /*[[@{/DataTables-1.10.16/Japanese.json}]]*/ 'Japanese.json'
                                },
                                "ajax": { url: /*[[@{/getaccountlist}]]*/ 'getaccountlist', dataSrc: '' },
                                "columns": [
                                    { data: "username" },
                                    { data: "email" },
                                ],
                                "columnDefs": [
                                    { targets: 0, width: 60 },
                                    { targets: 1, width: 180 },
                                    {targets:'_all',className : 'dt-head-center'},
                                ]
                            });
                            //一覧をクリックした
                            $('#modal-emplist-table tbody').on("click", "tr", function() {
                                if ($(this).find('.dataTables_empty').length == 0) {
                                    if ( $(this).hasClass('selected') ) {
                                        $(this).removeClass('selected');
                                    } else {
                                        modalemptable.$('tr.selected').removeClass('selected');
                                        $(this).addClass('selected');
                                    }
                                    modalempdata=$('#modal-emplist-table').dataTable().fnGetData(this);
                                }
                            });
                        })
                    /*]]>*/
                    </script>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-primary" id="btn-modalemp-select">選択</button>
            <button type="button" class="btn btn-primary" data-dismiss="modal">キャンセル</button>
          </div><!-- /.modal-footer -->
        </div><!-- /.modal-content -->
      </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->
</div>
    </body>
</html>

thymeleafのfragmentを使ってます

10.実行してみます
image.png
image.png
↓ 選択ボタンを押して
image.png
↓ 行を選択してモーダルの選択ボタンを押します
image.png

できました。

14
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
23