Spring Boot + npm + Geb で入力フォームを作ってテストする ( その9 )( 各画面の HTML を作成する2 )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その8 )( 各画面の HTML を作成する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- 各画面の HTML を作成します。
- 今回は入力画面2、入力画面3です。
参照したサイト・書籍
目次
手順
入力画面2の HTML を作成する
static/inquiry/input02.html を新規作成します。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>入力フォーム - 入力画面2</title> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <!-- Bootstrap 3.3.6 --> <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css"> <!-- Font Awesome --> <link rel="stylesheet" href="/vendor/font-awesome/css/font-awesome.min.css"> <!-- Ionicons --> <link rel="stylesheet" href="/vendor/ionicons/css/ionicons.min.css"> <!-- Theme style --> <link rel="stylesheet" href="/vendor/admin-lte/css/AdminLTE.min.css"> <link rel="stylesheet" href="/vendor/admin-lte/css/skins/skin-blue.min.css"> <!-- 画面共通で使用する css --> <link rel="stylesheet" href="/css/common.css"> </head> <body class="skin-blue layout-top-nav"> <div class="wrapper"> <!-- Content Wrapper. Contains page content --> <div class="content-wrapper"> <!-- Content Header (Page header) --> <section class="content-header"> <h1> 入力画面2 </h1> </section> <!-- Main content --> <section class="content"> <div class="row"> <div class="col-xs-12"> <form id="input02Form" class="form-horizontal" method="post" action=""> <!-- 郵便番号 --> <div class="form-group" id="form-group-zipcode"> <div class="control-label col-sm-2"> <label class="float-label">郵便番号</label> <div class="label label-required">必須</div> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <p class="form-control-static-inline">〒</p> <input type="text" name="zipcode1" id="zipcode1" class="form-control form-control-inline" style="width: 60px;" value="" placeholder=""/> <p class="form-control-static-inline">-</p> <input type="text" name="zipcode2" id="zipcode2" class="form-control form-control-inline" style="width: 80px;" value="" placeholder=""/> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- 住所 --> <div class="form-group" id="form-group-address"> <div class="control-label col-sm-2"> <label class="float-label">住所</label> <div class="label label-required">必須</div> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="address" id="address" class="form-control" value="" placeholder="例)東京都千代田区飯田橋1-1"/> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- 電話番号 --> <div class="form-group" id="form-group-tel"> <div class="control-label col-sm-2"> <label class="float-label">電話番号</label> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="tel1" id="tel1" class="form-control form-control-inline" style="width: 100px;" value="" placeholder=""/> <p class="form-control-static-inline">-</p> <input type="text" name="tel2" id="tel2" class="form-control form-control-inline" style="width: 100px;" value="" placeholder=""/> <p class="form-control-static-inline">-</p> <input type="text" name="tel3" id="tel3" class="form-control form-control-inline" style="width: 100px;" value="" placeholder=""/> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- メールアドレス --> <div class="form-group" id="form-group-email"> <div class="control-label col-sm-2"> <label class="float-label">メールアドレス</label> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="email" id="email" class="form-control" style="width: 250px;" value="" placeholder="例)taro.tanaka@sample.co.jp"/> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <div class="text-center"> <br/><p class="text-primary text-bold">※電話番号とメールアドレスのいずれか一方は必ず入力してください。</p><br/> <button class="btn bg-blue js-btn-back"><i class="fa fa-arrow-left"></i> 前の画面へ戻る</button> <button class="btn bg-green js-btn-next" disabled><i class="fa fa-arrow-right"></i> 次へ</button> </div> </form> </div> </div> </section> <!-- /.content --> </div> <!-- /.content-wrapper --> </div> <!-- ./wrapper --> <!-- REQUIRED JS SCRIPTS --> <script src="/js/inquiry/input02.js"></script> </body> </html>
画面の初期表示は以下のようになります。
入力画面3の HTML を作成する
static/inquiry/input03.html を新規作成します。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>入力フォーム - 入力画面3</title> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <!-- Bootstrap 3.3.6 --> <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css"> <!-- Font Awesome --> <link rel="stylesheet" href="/vendor/font-awesome/css/font-awesome.min.css"> <!-- Ionicons --> <link rel="stylesheet" href="/vendor/ionicons/css/ionicons.min.css"> <!-- Theme style --> <link rel="stylesheet" href="/vendor/admin-lte/css/AdminLTE.min.css"> <link rel="stylesheet" href="/vendor/admin-lte/css/skins/skin-blue.min.css"> <!-- 画面共通で使用する css --> <link rel="stylesheet" href="/css/common.css"> <style> /* 「チェックボックス複数行」の入力項目のチェックボックスを複数行に書くので、 */ /* 異なる行のチェックボックスの位置を左揃えにする */ @media (min-width: 768px) { #multiline-checkbox .checkbox label { display: block; float: left; width: 180px; } } @media (max-width: 767px) { #multiline-checkbox .checkbox label { display: block; float: left; width: 100%; } } </style> </head> <body class="skin-blue layout-top-nav"> <div class="wrapper"> <!-- Content Wrapper. Contains page content --> <div class="content-wrapper"> <!-- Content Header (Page header) --> <section class="content-header"> <h1> 入力画面3 </h1> </section> <!-- Main content --> <section class="content"> <div class="row"> <div class="col-xs-12"> <form id="input03Form" class="form-horizontal" method="post" action=""> <!-- お問い合わせの種類1 --> <div class="form-group" id="form-group-type1"> <div class="control-label col-sm-2"> <label class="float-label">お問い合わせの種類1</label> <div class="label label-required">必須</div> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <select name="type1" id="type1" class="form-control" style="width: 250px;"> <option value="">選択してください</option> <option value="1">製品に関するお問い合わせ</option> <option value="2">人事・採用情報</option> <option value="3">その他</option> </select> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- お問い合わせの種類2 --> <div class="form-group" id="form-group-type2"> <div class="control-label col-sm-2"> <label class="float-label">お問い合わせの種類2</label> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <div class="checkbox"> <label><input type="checkbox" name="type2">見積が欲しい</label> <label><input type="checkbox" name="type2">資料が欲しい</label> <label><input type="checkbox" name="type2">その他の問い合わせ</label> </div> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- お問い合わせの内容 --> <div class="form-group" id="form-group-inquiry"> <div class="control-label col-sm-2"> <label class="float-label">お問い合わせの内容</label> <div class="label label-required">必須</div> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <textarea rows="5" name="inquiry" id="inquiry" class="form-control" placeholder="お問い合わせ内容を入力して下さい"></textarea> </div></div> <div class="row"><div class="col-sm-10"><p class="form-control-static"><small>※最大500文字</small></p></div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <div class="form-group" id="form-group-survey"> <div class="control-label col-sm-2"> <label class="float-label">アンケート</label> </div> <div class="col-sm-10" id="multiline-checkbox"> <div class="row"><div class="col-sm-12"> <div class="checkbox"> <label><input type="checkbox" name="survey" value="1">選択肢1だけ長くしてみる</label> <label><input type="checkbox" name="survey" value="2">選択肢2</label> <label><input type="checkbox" name="survey" value="3">選択肢3</label> </div> </div></div> <div class="row"><div class="col-sm-12"> <div class="checkbox"> <label><input type="checkbox" name="survey" value="4">選択肢4</label> <label><input type="checkbox" name="survey" value="5">選択肢5が少し長い</label> <label><input type="checkbox" name="survey" value="6">選択肢6</label> </div> </div></div> <div class="row"><div class="col-sm-12"> <div class="checkbox"> <label><input type="checkbox" name="survey" value="7">選択肢7</label> <label><input type="checkbox" name="survey" value="8">選択肢8</label> <label><input type="checkbox" name="survey" value="9">9</label> </div> </div></div> </div> </div> <div class="text-center"> <button class="btn bg-blue js-btn-back"><i class="fa fa-arrow-left"></i> 前の画面へ戻る</button> <button class="btn bg-green js-btn-confirm" disabled><i class="fa fa-arrow-right"></i> 確認画面へ</button> </div> </form> </div> </div> </section> <!-- /.content --> </div> <!-- /.content-wrapper --> </div> <!-- ./wrapper --> <!-- REQUIRED JS SCRIPTS --> <script src="/js/inquiry/input03.js"></script> </body> </html>
画面の初期表示は以下のようになります。
履歴
2017/07/29
初版発行。
2017/08/08
* 入力画面2の form タグの id を input01Form
→ input02Form
へ変更しました。
* 入力画面3の form タグの id を input01Form
→ input03Form
へ変更しました。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その8 )( 各画面の HTML を作成する )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その7 )( webpack + browser-sync をインストールする ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- 各画面の HTML を作成します。
- 今回は入力画面1だけです。2~3回に分ける予定です。
参照したサイト・書籍
Bootstrap3でFormを簡単に作る方法
http://tetra-themes.com/bootstrap3-form-197/Bootstrap3日本語リファレンス - CSS - フォーム - サポートしているフォーム部品
http://bootstrap3.cyberlab.info/css/forms-supportedControls.htmlForm inline inside a form horizontal in twitter bootstrap?
https://stackoverflow.com/questions/12201835/form-inline-inside-a-form-horizontal-in-twitter-bootstrapリキッド・レイアウトでチェックボックスを綺麗に並べる
http://webos-goodies.jp/archives/51275332.htmlnpm-scripts で作るフロントエンド環境の構築
http://ceblog.mediba.jp/post/154522336717/npm-scripts
目次
- 画面の仕様を決める
- starter.html からテンプレートに使用する template.html を作成する
- src/main/assets/css の下で更新された css ファイルを自動で src/main/resources/static/css の下に反映する仕組みを作成する
- 画面共通で使用する css ファイルを作成する
- 入力画面1の HTML を作成する
手順
画面の仕様を決める
「Spring Boot + npm + Geb で入力フォームを作ってテストする」は Geb でのテストのサンプルを作成することが目的なので、いろいろ要素を盛り込みます。
- 入力項目には以下の要素を入れます。
- 画面の入力チェックは Javascript で行います。入力チェックエラー時にはラベルと入力フィールドを赤く表示し、入力項目の下にエラーメッセージが表示されるようにします。
- Ajax でデータを送受信する仕組みも入れます。「郵便番号」を入力したら「住所」に都道府県・市区町村・町丁目名がセットされるようにします。郵便番号検索API を利用する想定です。
starter.html からテンプレートに使用する template.html を作成する
作業開始前にコマンドプロンプトで npm run server
コマンドを実行して browser-sync を起動しておきます。
node_modules/admin-lte/starter.html を static の下にコピーし、ファイル名を template.html に変更した後、以下の点を変更します。
- header タグ内の以下の部分を変更します。
<title>AdminLTE 2 | Starter</title>
→<title>入力フォーム</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
→<link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
→<link rel="stylesheet" href="/vendor/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
→<link rel="stylesheet" href="/vendor/ionicons/css/ionicons.min.css">
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
→<link rel="stylesheet" href="/vendor/admin-lte/css/AdminLTE.min.css">
<link rel="stylesheet" href="dist/css/skins/skin-blue.min.css">
→<link rel="stylesheet" href="/vendor/admin-lte/css/skins/skin-blue.min.css">
- 以下の2行は削除します。
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<body class="skin-blue layout-top-nav">
→<body class="skin-blue layout-top-nav">
に変更します。- body タグ内の以下の部分は削除します。
<!-- Main Header -->
と<header class="main-header"> ... </header>
の部分<!-- Left side column. contains the logo and sidebar -->
と<aside class="main-sidebar"> ... </aside>
の部分<!-- Main Footer -->
と<footer class="main-footer"> ... </footer>
の部分<!-- Control Sidebar -->
と<aside class="control-sidebar control-sidebar-dark"> ... </aside>
の部分<!-- Add the sidebar's background. This div must be placed immediately after the control sidebar -->
と<div class="control-sidebar-bg"></div>
の部分- js ファイルを読み込んでいる以下の3行。
<script src="plugins/jQuery/jquery-2.2.3.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<script src="dist/js/app.min.js"></script>
<section class="content-header"> ... </section>
内の以下の部分を削除します。<small>Optional description</small>
<ol class="breadcrumb"> ... </ol>
の部分
- あとはコメントで残す必要がないものも全て削除します。
ここまでの変更で template.html は以下のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>入力フォーム</title> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <!-- Bootstrap 3.3.6 --> <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css"> <!-- Font Awesome --> <link rel="stylesheet" href="/vendor/font-awesome/css/font-awesome.min.css"> <!-- Ionicons --> <link rel="stylesheet" href="/vendor/ionicons/css/ionicons.min.css"> <!-- Theme style --> <link rel="stylesheet" href="/vendor/admin-lte/css/AdminLTE.min.css"> <link rel="stylesheet" href="/vendor/admin-lte/css/skins/skin-blue.min.css"> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <!-- Content Wrapper. Contains page content --> <div class="content-wrapper"> <!-- Content Header (Page header) --> <section class="content-header"> <h1> Page Header </h1> </section> <!-- Main content --> <section class="content"> <!-- Your Page Content Here --> </section> <!-- /.content --> </div> <!-- /.content-wrapper --> </div> <!-- ./wrapper --> <!-- REQUIRED JS SCRIPTS --> </body> </html>
http://localhost:9080/template.html にアクセスして画面を表示すると以下の画像のようになります。
Ctrl+C を押して npm run server
コマンドを一旦停止します。
src/main/assets/css の下で更新された css ファイルを自動で src/main/resources/static/css の下に反映する仕組みを作成する
src/main/assets/css の下に common.css を新規作成し、変更されたら自動で src/main/resources/static/css の下にコピーする仕組みを作成します。変更の検知は cpx の watch 機能を利用します。
src/main/assets の下に css ディレクトリを新規作成し、その下に common.css を新規作成します。この時点では common.css の中身は空です。
package.json の scripts を以下のように変更します。
"scripts": { .........., "copy:css:watch": "cpx src/main/assets/css/**/* src/main/resources/static/css -w", "server": "run-p copy:css:watch webpack:watch browser-sync:start" },
"copy:css:watch": "cpx src/main/assets/css/**/* src/main/resources/static/css -w"
を追加します。"server"
にcopy:css:watch
を追加します。
static/template.html を以下のように変更します。
<head> .......... <!-- 画面共通で使用する css --> <link rel="stylesheet" href="/css/common.css"> </head>
<link rel="stylesheet" href="/css/common.css">
を追加し、src/main/resources/static/css/common.css を読み込むようにします。
以上で準備は完了です。common.css を変更したら自動でブラウザに反映されるか確認します。
npm run server
コマンドを実行します。
src/main/resources/static の下に css/common.css がコピーされます。
http://localhost:9080/template.html にアクセスすると以下の画面が表示されます。
src/main/assets/css/common.css に背景色を変更する以下の記述を追加します。
/* body 内の背景色を白より少し色がついた色にする */ .content-wrapper { background-color: ivory; }
browser-sync が common.css の変更を検知したことを示すログを出力し、
ブラウザに表示している画面の背景色も手動リロードすることなく変わりました。
画面共通で使用する css ファイルを作成する
src/main/assets/css/common.css に以下の内容を記述します。
- Bootstrap テーマ Honoka と adminLTE で画面を作ってみる から今回必要そうなものを持ってきました。
- 今回は form-horizontal で作成することにします。form-horizontal で作成する際に追加で必要になりそうな定義を追加しました。
/* body 内の背景色を白より少し色がついた色にする */ .content-wrapper { background-color: ivory; } /* フォーカス時の入力フィールドの色合いが adminLTE より Bootstrap のものが好みなので、そちらに定義し直す */ .form-control:focus { border-color: #66afe9; outline: 0; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); } /* form-control-static の文字列を入力項目のすぐ下に隙間をほとんど空けずに表示されるようにする */ .form-control-static { padding-top: 0px; padding-bottom: 0px; margin-bottom: -15px; } /* 入力チェックエラーの入力項目の背景色を薄い赤色にする */ .has-error .form-control { background-color: #fff5ee; } /* form-horizontal 内で form-control, form-control-static-inline の入力フィールドを横並びで表示する */ .form-control-inline { float:left; margin-right: 10px; } .form-control-static-inline { float: left; padding-top: 7px; margin-right: 10px; } /* checkbox の文字列の右側に少し隙間を空ける */ .checkbox label { margin-right: 10px; } /* 必須ラベル */ /* 767px 以下の場合には必須ラベルを右側に移動する */ @media (min-width: 768px) { .label-required { background-color: red; margin-right: 5px; } .form-group .float-label { float: right; } } @media (max-width: 767px) { .label-required { background-color: red; margin-left: 5px; } } /* 画面下のボタンを大きく表示させる */ .btn { width: 150px; }
入力画面1の HTML を作成する
static の下に inquiry ディレクトリを作成した後、static/template.html をコピーして static/inquiry/input01.html を作成します。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>入力フォーム - 入力画面1</title> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <!-- Bootstrap 3.3.6 --> <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css"> <!-- Font Awesome --> <link rel="stylesheet" href="/vendor/font-awesome/css/font-awesome.min.css"> <!-- Ionicons --> <link rel="stylesheet" href="/vendor/ionicons/css/ionicons.min.css"> <!-- Theme style --> <link rel="stylesheet" href="/vendor/admin-lte/css/AdminLTE.min.css"> <link rel="stylesheet" href="/vendor/admin-lte/css/skins/skin-blue.min.css"> <!-- 画面共通で使用する css --> <link rel="stylesheet" href="/css/common.css"> </head> <body class="skin-blue layout-top-nav"> <div class="wrapper"> <!-- Content Wrapper. Contains page content --> <div class="content-wrapper"> <!-- Content Header (Page header) --> <section class="content-header"> <h1> 入力画面1 </h1> </section> <!-- Main content --> <section class="content"> <div class="row"> <div class="col-xs-12"> <form id="input01Form" class="form-horizontal" method="post" action=""> <!-- お名前(漢字) --> <div class="form-group" id="form-group-name"> <div class="control-label col-sm-2"> <label class="float-label">お名前(漢字)</label> <div class="label label-required">必須</div> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="lastname" id="lastname" class="form-control form-control-inline" style="width: 150px;" value="" placeholder="例)田中"/> <input type="text" name="firstname" id="firstname" class="form-control form-control-inline" style="width: 150px;" value="" placeholder="例)太郎"/> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- お名前(かな) --> <div class="form-group" id="form-group-kana"> <div class="control-label col-sm-2"> <label class="float-label">お名前(かな)</label> <div class="label label-required">必須</div> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="lastkana" id="lastkana" class="form-control form-control-inline" style="width: 150px;" value="" placeholder="例)たなか"/> <input type="text" name="firstkana" id="firstkana" class="form-control form-control-inline" style="width: 150px;" value="" placeholder="例)たろう"/> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- 性別 --> <div class="form-group" id="form-group-sex"> <div class="control-label col-sm-2"> <label class="float-label">性別</label> <div class="label label-required">必須</div> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <div class="radio-inline"><label><input type="radio" name="sex" value="1">男性</label></div> <div class="radio-inline"><label><input type="radio" name="sex" value="2">女性</label></div> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- 年齢 --> <div class="form-group" id="form-group-age"> <div class="control-label col-sm-2"> <label class="float-label">年齢</label> <div class="label label-required">必須</div> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="age" id="age" class="form-control form-control-inline" style="width: 150px;" value="" placeholder="例)30"/> <p class="form-control-static-inline">歳</p> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <!-- 職業 --> <div class="form-group" id="form-group-job"> <div class="control-label col-sm-2"> <label class="float-label">職業</label> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <select name="job" id="job" class="form-control" style="width: 250px;"> <option value="">選択してください</option> <option value="1">会社員</option> <option value="2">学生</option> <option value="3">その他</option> </select> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div> <div class="text-center"> <button class="btn bg-green js-btn-next" disabled><i class="fa fa-arrow-right"></i> 次へ</button> </div> </form> </div> </div> </section> <!-- /.content --> </div> <!-- /.content-wrapper --> </div> <!-- ./wrapper --> <!-- REQUIRED JS SCRIPTS --> <script src="/js/inquiry/input01.js"></script> </body> </html>
画面の初期表示は以下のようになります。
画面上の入力項目を全て入力し、入力チェックでエラーが出なかった場合は以下のようになります。
<!-- 職業 --> <div class="form-group has-success" id="form-group-job"> .......... </div> <div class="text-center"> <button class="btn bg-green js-btn-next"><i class="fa fa-arrow-right"></i> 次へ</button> </div>
- form-group に has-success を追加して
<div class="form-group" ...>
→<div class="form-group has-success" ...>
にします。 - disabled を削除して
<button class="btn bg-green js-btn-next" disabled>
→<button class="btn bg-green js-btn-next">
にします。
入力チェックがエラーだった場合は以下のようになります。
<!-- 職業 --> <div class="form-group has-error" id="form-group-job"> .......... <div class="col-sm-10"> .......... <div class="row js-errmsg"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div> </div> </div>
- form-group に has-error を追加して
<div class="form-group" ...>
→<div class="form-group has-error" ...>
にします。 - エラーメッセージの表示部分から hidden を削除して
<div class="row hidden js-errmsg">
→<div class="row js-errmsg">
にします。
今回 HTML を作成して思いましたが browser-sync が本当に便利です。手動でリロードをしなくてよいのがこんなに便利だとは。もっと早く知りたかった。。。
履歴
2017/07/29
初版発行。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その7 )( webpack + browser-sync をインストールする )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その6 )( URL の決定 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- 各画面の HTML を作成する前に、今回は HTML の確認を Tomcat ではなく webpack + browser-sync を使用して行ってみようと思います。
- まずはインストールして試してみます。
- 「Spring Boot + npm + Geb で入力フォームを作ってテストする」では webpack は js ファイルの開発にしか使わないので HTML の確認だけなら browser-sync だけでいいのですが、両方インストールして変更したファイル(html ファイルだけでなく js ファイルも)を watch する仕組みを構築します。
参照したサイト・書籍
最新版で学ぶwebpack 3入門 – JavaScript開発で人気のバンドルツール
https://ics.media/entry/12140Building Static Sites with Webpack
https://blog.binoy.io/building-static-sites-with-webpack-4fc489ceabcaWebPack-Dev-ServerからBrowsersyncに乗り換えた
https://saku.io/move-from-webpack-dev-server-to-browser-sync/webpackで複数のディレクトリへ出力する
http://webdesign-dackel.com/2015/09/10/webpack-multiple-output/window.onloadとjQueryの$(document).ready等の比較
https://rcmdnk.com/blog/2015/07/11/computer-javascript-jquery/
目次
手順
webpack をインストールする
npm install --save-dev webpack
コマンドを実行して webpack をインストールします。
プロジェクトのルートディレクトリ直下に webpack.config.js というファイルを新規作成し、以下の内容を記述します。
module.exports = { entry: { "js/app": ["./src/main/assets/js/app.js"] }, output: { path: __dirname + "/src/main/resources/static", publicPath: "/", filename: "[name].js" } };
- js ファイルは src/main の下に assets/js ディレクトリを作成し、その下に作成します。
- 今回は動作確認のために app.js を作成します。
- webpack により処理・生成された js ファイルは src/main/resources/static/js の下に配置します。
src/main の下に assets/js ディレクトリを作成し、src/main/assets/js の下に app.js を作成します。
app.js には以下の内容を記述します。
var $ = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js");
webpack を起動しやすくするために package.json の scripts に以下の記述を追加します。
"scripts": { .........., "webpack": "webpack" },
動作確認します。まずは npm run webpack -- --version
コマンドを実行してバージョン番号が表示されることを確認します。
3.3.0
と表示されました。
次に npm run webpack
コマンドを実行し、src/main/assets/js/app.js から src/main/resources/static/js/app.js が生成されることを確認します。
コマンドが正常に終了し、src/main/resources/static/js の下に app.js が生成されています。
app.js を開くと以下の内容で始まるファイルでした。
問題なく動作しているようですので、次へ進みます。
browser-sync をインストールする
npm install --save-dev browser-sync
コマンドを実行して browser-sync をインストールします。
package.json の scripts に以下の記述を追加します。
"scripts": { .........., "browser-sync": "browser-sync" },
npm run browser-sync -- init
コマンドを実行して bs-config.js を生成します。
bs-config.js の以下の点を変更します。
"weinre": { "port": 8080 }
→"weinre": { "port": 9081 }
に変更します。"files": false
→"files": [ "./static/**/*", "./src/main/resources/static/**/*" ]
に変更します。"server": false
→"server": { "baseDir": [ "./static", "./src/main/resources/static" ] }
に変更します。"port": 3000
→"port": 9080
に変更します。"notify": true
→"notify": false
に変更します。
/* |-------------------------------------------------------------------------- | Browser-sync config file |-------------------------------------------------------------------------- | | For up-to-date information about the options: | http://www.browsersync.io/docs/options/ | | There are more options than you see here, these are just the ones that are | set internally. See the website for more info. | | */ module.exports = { "ui": { "port": 3001, "weinre": { "port": 9081 } }, "files": [ "./static/**/*", "./src/main/resources/static/**/*" ], "watchEvents": [ "change" ], "watchOptions": { "ignoreInitial": true }, "server": { "baseDir": [ "./static", "./src/main/resources/static" ] }, "proxy": false, "port": 9080, "middleware": false, "serveStatic": [], "ghostMode": { "clicks": true, "scroll": true, "location": true, "forms": { "submit": true, "inputs": true, "toggles": true } }, "logLevel": "info", "logPrefix": "Browsersync", "logConnections": false, "logFileChanges": true, "logSnippet": true, "rewriteRules": [], "open": "local", "browser": "default", "cors": false, "xip": false, "hostnameSuffix": false, "reloadOnRestart": false, "notify": false, "scrollProportionally": true, "scrollThrottle": 0, "scrollRestoreTechnique": "window.name", "scrollElements": [], "scrollElementMapping": [], "reloadDelay": 0, "reloadDebounce": 0, "reloadThrottle": 0, "plugins": [], "injectChanges": true, "startPath": null, "minify": true, "host": null, "localOnly": false, "codeSync": true, "timestamps": true, "clientEvents": [ "scroll", "scroll:element", "input:text", "input:toggles", "form:submit", "form:reset", "click" ], "socket": { "socketIoOptions": { "log": false }, "socketIoClientConfig": { "reconnectionAttempts": 50 }, "path": "/browser-sync/socket.io", "clientPath": "/browser-sync", "namespace": "/browser-sync", "clients": { "heartbeatTimeout": 5000 } }, "tagNames": { "less": "link", "scss": "link", "css": "link", "jpg": "img", "jpeg": "img", "png": "img", "svg": "img", "gif": "img", "js": "script" } };
package.json の scripts に以下の記述を追加します。
"scripts": { .........., "browser-sync:start": "browser-sync start --config bs-config.js" },
プロジェクトのルートディレクトリ直下に static ディレクトリを作成します。今回は Thymeleaf テンプレート前の html ファイルは jar ファイルに入れないようにするために、src/main/resources/static ではなく static の下に作成することにします。
npm run browser-sync:start
コマンドを実行してみます。
特にエラーは出ずに起動しているようです。http://localhost:3001 にアクセスすると browser-sync の ui が表示されました。
npm run browser-sync:start
コマンドを実行したコマンドプロンプトで Ctrl+C を押して終了すると、ブラウザに以下の画面が表示されました。サーバと同期して動いているようです。
問題なさそうですので、次へ進みます。
webpack + browser-sync 起動用の npm-scripts を作成する
package.json の scripts に以下の記述を追加します。
"scripts": { .........., "webpack": "webpack", "webpack:watch": "webpack --watch", "browser-sync": "browser-sync", "browser-sync:start": "browser-sync start --config bs-config.js", "server": "run-p webpack:watch browser-sync:start" },
"webpack:watch": "webpack --watch"
を追加します。"server": "run-p webpack:watch browser-sync:start"
を追加します。
npm run server
コマンドで webpack と browser-sync が起動して、ファイルが変更されるとブラウザに自動反映されるようにします。
動作確認する
static の下に以下の内容の sample.html を作成します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> テスト用ページです。<br/> <span id="sample">xxx</span> <script src="/js/app.js"></script> </body> </html>
src/main/assets/js/app.js を以下の内容に変更します。
var $ = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js"); $(document).ready(function() { $("#sample").text("サンプル"); });
npm run server
コマンドを実行します。
ブラウザが起動しますので、http://localhost:9080/sample.html にアクセスしてみます。
sample.html に記述した文字列が表示されており、また app.js に記述した処理も反映されていました。
sample.html を以下の内容に変更してみます。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> サンプルですよ?<br/> <span id="sample">xxx</span> <script src="/js/app.js"></script> </body> </html>
ブラウザを見るとリロードすることなく反映されています。
今度は app.js を以下の内容に修正してみます。
var $ = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js"); $(document).ready(function() { $("#sample").text("app.js を修正してみました"); });
webpack の処理が実行されて src/main/resources/static/js/app.js が作り直されて、
ブラウザの方に手動でリロードすることなく反映されました。
他にも browser-sync はこんなことができるようです。
複数のブラウザ(下の画像では IE と Chrome)で同じページを見ている時に、ファイルが変更されると全てのブラウザに手動リロードすることなく反映されます。
複数のブラウザで同じフォームを見ている時に、片方のブラウザ(IE)に入力すると、自動で別のブラウザ(Chrome)にも入力されます。
sample2.html を作成します。その後で sample.html には sample.html → sample2.html へ遷移するリンクを、sample2.html には sample2.html → sample.html へ遷移するリンクを記述してから IE と Chrome で sample.html を表示した後
IE の方のリンクをクリックして sample2.html へ遷移すると、Chrome の方でも sample2.html へ遷移します。
browser-sync ってすごい面白い! まさか、こんな便利なソフトがあるとは。
他にも browser-sync には proxy の機能もあるようで、Spring Boot の Tomcat と連携して自動リロードもできるのでしょうか。。。? 入力フォームができたら試してみたいと思います。
Ctrl+C を押して webpack と browser-sync を停止します。今回作成した sample.html, sample2.html は commit せずに削除します。
最後に package.json, webpack.config.js, bs-config.js を記載しておきます。
ソースコード
package.json
{ "name": "boot-npm-geb-sample", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "postinstall": "run-s clean:static-dir copy:all", "clean:static-dir": "rimraf src/main/resources/static/*", "copy:all": "run-p copy:bootstrap copy:admin-lte copy:font-awesome copy:ionicons", "copy:bootstrap": "cpx node_modules/bootstrap/dist/**/* src/main/resources/static/vendor/bootstrap", "copy:admin-lte": "cpx node_modules/admin-lte/dist/**/* src/main/resources/static/vendor/admin-lte", "copy:font-awesome": "cpx node_modules/font-awesome/{css,fonts}/**/* src/main/resources/static/vendor/font-awesome", "copy:ionicons": "cpx node_modules/ionicons/dist/{css,fonts}/**/* src/main/resources/static/vendor/ionicons", "webpack": "webpack", "webpack:watch": "webpack --watch", "browser-sync": "browser-sync", "browser-sync:start": "browser-sync start --config bs-config.js", "server": "run-p webpack:watch browser-sync:start" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "admin-lte": "^2.3.11", "bootstrap": "^3.3.7", "font-awesome": "^4.7.0", "ionicons": "^3.0.0" }, "devDependencies": { "browser-sync": "^2.18.13", "cpx": "^1.5.0", "npm-run-all": "^4.0.2", "rimraf": "^2.6.1", "webpack": "^3.3.0" } }
webpack.config.js
module.exports = { entry: { "js/app": ["./src/main/assets/js/app.js"] }, output: { path: __dirname + "/src/main/resources/static", publicPath: "/", filename: "[name].js" } };
bs-config.js
/* |-------------------------------------------------------------------------- | Browser-sync config file |-------------------------------------------------------------------------- | | For up-to-date information about the options: | http://www.browsersync.io/docs/options/ | | There are more options than you see here, these are just the ones that are | set internally. See the website for more info. | | */ module.exports = { "ui": { "port": 3001, "weinre": { "port": 9081 } }, "files": [ "./static/**/*", "./src/main/resources/static/**/*" ], "watchEvents": [ "change" ], "watchOptions": { "ignoreInitial": true }, "server": { "baseDir": [ "./static", "./src/main/resources/static" ] }, "proxy": false, "port": 9080, "middleware": false, "serveStatic": [], "ghostMode": { "clicks": true, "scroll": true, "location": true, "forms": { "submit": true, "inputs": true, "toggles": true } }, "logLevel": "info", "logPrefix": "Browsersync", "logConnections": false, "logFileChanges": true, "logSnippet": true, "rewriteRules": [], "open": "local", "browser": "default", "cors": false, "xip": false, "hostnameSuffix": false, "reloadOnRestart": false, "notify": false, "scrollProportionally": true, "scrollThrottle": 0, "scrollRestoreTechnique": "window.name", "scrollElements": [], "scrollElementMapping": [], "reloadDelay": 0, "reloadDebounce": 0, "reloadThrottle": 0, "plugins": [], "injectChanges": true, "startPath": null, "minify": true, "host": null, "localOnly": false, "codeSync": true, "timestamps": true, "clientEvents": [ "scroll", "scroll:element", "input:text", "input:toggles", "form:submit", "form:reset", "click" ], "socket": { "socketIoOptions": { "log": false }, "socketIoClientConfig": { "reconnectionAttempts": 50 }, "path": "/browser-sync/socket.io", "clientPath": "/browser-sync", "namespace": "/browser-sync", "clients": { "heartbeatTimeout": 5000 } }, "tagNames": { "less": "link", "scss": "link", "css": "link", "jpg": "img", "jpeg": "img", "png": "img", "svg": "img", "gif": "img", "js": "script" } };
履歴
2017/07/24
初版発行。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その6 )( URL の決定 )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
- 画面の URL を決めます。
参照したサイト・書籍
目次
手順
画面の URL を決める
各画面の URL は以下のようにします。
画面 | アクション | URL |
---|---|---|
入力画面1 | 初期表示 | /inquiry/input/01/ |
「次へ」ボタンクリック時 | /inquiry/input/01/?move=next | |
入力画面2 | 初期表示 | /inquiry/input/02/ |
「前の画面へ戻る」ボタンクリック時 | /inquiry/input/02/?move=back | |
「次へ」ボタンクリック時 | /inquiry/input/02/?move=next | |
入力画面3 | 初期表示 | /inquiry/input/03/ |
「前の画面へ戻る」ボタンクリック時 | /inquiry/input/03/?move=back | |
「確認画面へ」ボタンクリック時 | /inquiry/input/03/?move=next | |
確認画面 | 初期表示 | /inquiry/confirm/ |
入力画面1の項目の「修正する」ボタンクリック時 | /inquiry/input/01/ | |
入力画面2の項目の「修正する」ボタンクリック時 | /inquiry/input/02/ | |
入力画面3の項目の「修正する」ボタンクリック時 | /inquiry/input/03/ | |
「送信する」ボタンクリック時 | /inquiry/confirm/send/ | |
完了画面 | 初期表示 | /inquiry/complete/ |
履歴
2017/07/23
初版発行。
2017/08/06
* 入力画面3のボタン名を「次へ」→「確認画面へ」に変更しました。
2017/08/08
* HTML を作成した時に「前の画面へ戻る」ボタンに記述した CSS のスタイルを js-btn-back
にしていたので URL も move=prev
→ move=back
へ変更しました。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その5 )( Bootstrap, AdminLTE, Font Awesome, Ionicons のインストール )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その4 )( nodist + Node.js のインストール ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- npm を使用して Bootstrap, AdminLTE, Font Awesome, Ionicons をインストールします。
- インストール後 src/main/resources/static へ必要なファイルをコピーする npm-scripts も作成します。
参照したサイト・書籍
Purpose of installing bootstrap through npm?
https://stackoverflow.com/questions/26773767/purpose-of-installing-bootstrap-through-npmnpm でパッケージのバージョン一覧を確認したりバージョンを指定してインストールしたりする方法
http://phiary.me/npm-package-version-info-install/npm scriptsを使おう
http://qiita.com/liply/items/cccc6a7b703c1d3ab04fnpm-scripts で使える便利モジュールたち
http://qiita.com/mysticatea/items/12bb6579b9155fd74586cpx と rimraf を試す
http://akabeko.me/blog/2015/09/cpx-rimraf/npm-run-all
https://www.npmjs.com/package/npm-run-allnpm runコマンドを実行したら警告が出るようになった
http://qiita.com/isamusuzuki/items/738a2736a746b67bd977
目次
- package.json を生成する
- Bootstrap をインストールする
- AdminLTE をインストールする
- Font Awesome をインストールする
- Ionicons をインストールする
- install 後に node_modules → src/main/resources/static へファイルをコピーする npm-scripts を作成する
- AdminLTE の starter.html で確認する
- .gitignore を変更する
- 最後に
手順
package.json を生成する
npm init -y
コマンドを実行して package.json を生成します。今は生成されたままとし、特に変更はしません。
Bootstrap をインストールする
npm info bootstrap versions
コマンドを実行してインストール可能な Bootstrap のバージョン一覧を表示します。npm install --save bootstrap
コマンドを実行して Bootstrap をインストールします。bootstrap@3.3.7
と表示されており、3.3.7 がインストールされました。インストール先の node_modules/bootstrap の下を見ると以下のディレクトリ構成になっていました。単に使用したいのであれば dist ディレクトリの下のファイルを使えば良さそうです。
AdminLTE をインストールする
Google で “npm AdminLTE” で検索すると https://www.npmjs.com/package/admin-lte のページがヒットしました。npm でインストールする時のパッケージ名は
admin-lte
のようです。npm install --save admin-lte
コマンドを実行して Bootstrap をインストールします。インストール先の node_modules/admin-lte の下を見ると以下のディレクトリ構成になっていました。こちらも単に使用したいのであれば dist ディレクトリの下のファイルを使えば良さそうです。
jQuery も node_modules/admin-lte/plugins/jQuery の下に jquery-2.2.3.min.js があります。今回はこのファイルを使用します。
Font Awesome をインストールする
“npm Font Awesome” で検索すると https://www.npmjs.com/package/font-awesome がヒットしました。
npm install --save font-awesome
コマンドを実行して Font Awesome をインストールします。インストール先の node_modules/font-awesome の下を見ると以下のディレクトリ構成になっていました。単に使用したいのであれば css, fonts ディレクトリの下のファイルを使えば良さそうです。
Ionicons をインストールする
“npm Ionicons” で検索すると https://www.npmjs.com/package/ionicons がヒットしました。
npm install --save ionicons
コマンドを実行して Ionicons をインストールします。インストール先の node_modules/font-awesome の下を見ると以下のディレクトリ構成になっていました。単に使用したいのであれば css, fonts ディレクトリの下のファイルを使えば良さそうです(dist に scss 用のファイルとかも入っていて分かりづらいです)。
install 後に node_modules → src/main/resources/static へファイルをコピーする npm-scripts を作成する
以下のコマンドを実行して npm-scripts を作成する上で便利なパッケージをインストールします。
npm install --save-dev cpx
npm install --save-dev rimraf
npm install --save-dev npm-run-all
package.json の scripts にコピー用の script を定義します。パッケージのファイルは src/main/resources/static/vendor/<パッケージ名>/ の下にコピーします。
"scripts": { .......... "postinstall": "run-s clean:static-dir copy:all", "clean:static-dir": "rimraf src/main/resources/static/*", "copy:all": "run-p copy:bootstrap copy:admin-lte copy:font-awesome copy:ionicons", "copy:bootstrap": "cpx node_modules/bootstrap/dist/**/* src/main/resources/static/vendor/bootstrap", "copy:admin-lte": "cpx node_modules/admin-lte/dist/**/* src/main/resources/static/vendor/admin-lte", "copy:font-awesome": "cpx node_modules/font-awesome/{css,fonts}/**/* src/main/resources/static/vendor/font-awesome", "copy:ionicons": "cpx node_modules/ionicons/dist/{css,fonts}/**/* src/main/resources/static/vendor/ionicons" },
postinstall
を追加し、npm install
コマンドが実行された後にファイルのコピーを行う処理を記述します。run-s コマンドで clean:static-dir → copy:all の順に script を実行します。clean:static-dir
は src/main/resources/static の下のディレクトリ、ファイルを削除します。static ディレクトリ自体は削除しません。copy:all
は node_modules の下から必要なファイルを src/main/resources/static の下にコピーします。以下の4つの script を run-p コマンドで並列実行します。copy:bootstrap
は node_modules/bootstrap パッケージの下のファイルをコピーします。copy:admin-lte
は node_modules/admin-lte パッケージの下のファイルをコピーします。copy:font-awesome
は node_modules/font-awesome パッケージの下のファイルをコピーします。copy:ionicons
は node_modules/ionicons パッケージの下のファイルをコピーします。
npm install
コマンドを実行してみます。
The node binary used for scripts is C:\Nodist\bin\node.exe but npm is using C:\Nodist\v-x64\6.11.1\node.exe itself. Use the
–scripts-prepend-node-pathoption to include the path for the node binary npm was executed with.
というメッセージが大量に出力されました(というより npm install
コマンドでパッケージをインストールしている時から出ていて WARN だったので気にしていなかっただけでしたが)。さすがに量が多いので出力されないようにする方法があるか確認します。
Web で調べたところ npm runコマンドを実行したら警告が出るようになった に解決方法が記載されていました。npm config set scripts-prepend-node-path true
コマンドを実行します。
再度 npm install
コマンドを実行します。
まだ npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
というメッセージが出ます。
Web で調べたところ fsevents は Mac でしか使用できないパッケージのためメッセージが出力されていますが、WARN なので気にしなければよいようです。
src/main/resources/static の下を見ると以下の画像のようにディレクトリが作成されていました。
AdminLTE の starter.html で確認する
node_modules/admin-lte の下に starter.html がありますので、それを src/main/resources/static の下にコピーした後、以下の点を変更します。
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
→<link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
→<link rel="stylesheet" href="/vendor/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
→<link rel="stylesheet" href="/vendor/ionicons/css/ionicons.min.css">
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
→<link rel="stylesheet" href="/vendor/admin-lte/css/AdminLTE.min.css">
<link rel="stylesheet" href="dist/css/skins/skin-blue.min.css">
→<link rel="stylesheet" href="/vendor/admin-lte/css/skins/skin-blue.min.css">
- 以下の2行はコメントアウトします。
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
- body タグ内の
<img src="dist/img/...
→<img src="/vendor/admin-lte/img/...
head タグ内は以下のようになります。
<head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>AdminLTE 2 | Starter</title> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <!-- Bootstrap 3.3.6 --> <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css"> <!-- Font Awesome --> <link rel="stylesheet" href="/vendor/font-awesome/css/font-awesome.min.css"> <!-- Ionicons --> <link rel="stylesheet" href="/vendor/ionicons/css/ionicons.min.css"> <!-- Theme style --> <link rel="stylesheet" href="/vendor/admin-lte/css/AdminLTE.min.css"> <!-- AdminLTE Skins. We have chosen the skin-blue for this starter page. However, you can choose any other skin. Make sure you apply the skin class to the body tag so the changes take effect. --> <link rel="stylesheet" href="/vendor/admin-lte/css/skins/skin-blue.min.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/html5shiv/3.7.3/html5shiv.min.js"></script>--> <!--<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>--> <!--<![endif]–>--> </head>
bootRun タスクを実行して Tomcat を起動した後、http://localhost:8080/starter.html にアクセスすると画面が表示されました。
Tomcat を停止します。
.gitignore を変更する
commit する前に .gitignore を以下の方針で変更します。
- node_modules は commit の対象にしません。
- src/main/resources/static も commit の対象にしません。
- npm 実行時にエラーが出ると出力される npm-debug.log も commit の対象にしません。
.gitignore を リンク先の内容 に変更します。
commit すると変更した .gitignore と、生成した package.json だけでした。
npm install
コマンドを実行すれば必要なファイルがインストール + コピーされます。
最後に
npm + npm-scripts が便利ですね。最初 Node.js + npm 関連を調べた時は最近の流行りは grunt, gulp ではなく webpack になったというような記事を見ていたので、npm でインストールした Bootstrap の css ファイル等を src/main/resources/static の下にコピーしたい場合にも webpack でやるのかな、と思って試行錯誤していたのですが(ファイルをコピーするための copy-webpack-plugin は見つけました)、単なるコピーは npm-scripts の方が楽でした。
現時点での感想として、
- npm-scripts と webpack を必要に応じて使い分けるのが良さそう。
- コピーするだけのような簡単な処理だったりコマンド実行するような場合には npm-scripts で。
- 自分で js ファイルを実装して、実行用に1つにまとめるような場合には webpack で。
- SPA で js ファイル以外に css や html のファイルも1つにまとめる場合も webpack で。
- Gulpで始めるwebpack 3入門 という記事も見かけました。どうも大規模開発になったら webpack に gulp を組み合わせるといいらしいですが、今の自分ではその境地には至れず。。。 npm-scripts + webpack で進めて、必要性を感じたら gulp を使う流れかな? 今は無理に手を出さないことにします。
今回の作業で生成・変更した package.json の最終版を リンク先 に記載しておきます。
ソースコード
.gitignore
# built application files *.apk *.ap_ # files for the dex VM *.dex # Java class files *.class # generated files **/bin/ **/gen/ # Local configuration file (sdk path, etc) local.properties # Eclipse project files .classpath .project # Proguard folder generated by Eclipse **/proguard/ # Intellij project files *.iml *.ipr *.iws **/.idea/ **/out/ **/src/main/resources/static #Gradle .gradletasknamecache **/.gradle/ **/build/ **/bin/ #Node.js **/node_modules/ npm-debug.log
**/src/main/resources/static
を追加します。#Node.js
から下の行を追加します。
package.json
{ "name": "boot-npm-geb-sample", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "postinstall": "run-s clean:static-dir copy:all", "clean:static-dir": "rimraf src/main/resources/static/*", "copy:all": "run-p copy:bootstrap copy:admin-lte copy:font-awesome copy:ionicons", "copy:bootstrap": "cpx node_modules/bootstrap/dist/**/* src/main/resources/static/vendor/bootstrap", "copy:admin-lte": "cpx node_modules/admin-lte/dist/**/* src/main/resources/static/vendor/admin-lte", "copy:font-awesome": "cpx node_modules/font-awesome/{css,fonts}/**/* src/main/resources/static/vendor/font-awesome", "copy:ionicons": "cpx node_modules/ionicons/dist/{css,fonts}/**/* src/main/resources/static/vendor/ionicons" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "admin-lte": "^2.3.11", "bootstrap": "^3.3.7", "font-awesome": "^4.7.0", "ionicons": "^3.0.0" }, "devDependencies": { "cpx": "^1.5.0", "npm-run-all": "^4.0.2", "rimraf": "^2.6.1" } }
履歴
2017/07/23
初版発行。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その4 )( nodist + Node.js のインストール )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その3 )( Project の作成2 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Node.js のインストール
- Node.js は https://nodejs.org/ja/ からダウンロードできるインストーラーでインストールせず、Node.js のバージョン管理ツールである nodist を利用してインストールします。
参照したサイト・書籍
Node.js
https://nodejs.org/ja/nodistでNode.jsをバージョン管理
http://qiita.com/satoyan419/items/56e0b5f35912b9374305nodist 〜 Node.jsのバージョンを管理する for Windows 〜
http://tech.pjin.jp/blog/2016/12/12/how_to_use_nodist/
目次
手順
nodist をインストールする
https://github.com/marcelklehr/nodist/releases から NodistSetup-v0.8.8.exe をダウンロードします。
NodistSetup-v0.8.8.exe を実行します。
「Welcome to Nodist Setup」画面が表示されます。「Next >」ボタンをクリックします。
「License Agreement」画面が表示されます。「I Agree」ボタンをクリックします。
「Choose Install Location」画面が表示されます。「Destination Folder」を
C:\Nodist
へ変更した後、「Install」ボタンをクリックします。インストールが実行されます。完了すると「Completing Nodist Setup」画面が表示されますので、「Finish」ボタンをクリックします。
コマンドプロンプトを起動し、
nodist -v
コマンドを実行してバージョン番号が表示されることを確認します。
Node.js をインストールする
nodist dist
コマンドを実行してインストール可能な Node.js のバージョン一覧を表示します。https://nodejs.org/ja/ を見ると現在の推奨版は 6.11.1 ですので、6.11.1 をインストールします。
以下の画像のコマンドを実行して 6.11.1 をインストールした後、Node.js のカレントのバージョンを 6.11.1 へ切り替えます。
npm はアップデートしても 4.0.5 のままでした。
履歴
2017/07/22
初版発行。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その3 )( Project の作成2 )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その2 )( Project の作成 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Project の作成
- 前回長くなったので2回に分けています。今回は前回からの続きです。
参照したサイト・書籍
DBCP - validationQuery for different Databases
https://stackoverflow.com/questions/10684244/dbcp-validationquery-for-different-databases- H2 Database の validationQuery を調べた時に参照しました。H2 Database 以外の validationQuery も記載されています。ほとんどの DB で
select 1
なんですね。
- H2 Database の validationQuery を調べた時に参照しました。H2 Database 以外の validationQuery も記載されています。ほとんどの DB で
目次
- ksbysample-webapp-lending からファイルをコピーする(その2)
- 「Spring Configuration Check」のメッセージが表示されないようにする
- Tomcat が起動することを確認する
手順
ksbysample-webapp-lending からファイルをコピーする(その2)
ksbysample-webapp-lending から以下のファイルをコピーします。
※リンクのあるファイルはリンク先の内容に変更します。
■src/main/resources
- /application.properties
→ /application.properties - /application-develop.properties
→ /application-develop.properties - /application-product.properties
→ /application-product.properties - /application-unittest.properties
→ /application-unittest.properties - /applicationContext-develop.xml
→ /applicationContext-develop.xml - /applicationContext-product.xml
→ /applicationContext-product.xml - /applicationContext-unittest.xml
→ /applicationContext-unittest.xml - /logback-spring.xml
→ /logback-spring.xml - /messages.properties
→ /messages.properties - /messages_ja_JP.properties
→ /messages_ja_JP.properties
- /application.properties
ファイルコピー後は以下のディレクトリ構成になります。
「Spring Configuration Check」のメッセージが表示されないようにする
IntelliJ IDEA を再起動します。
画面右下に「Spring Configuration Check」のメッセージが表示されます。
下矢印ボタンを押してメッセージの全てを表示した後、「boot-npm-geb-sample_main」リンクをクリックします。
「Project Structure」ダイアログが表示されます。「+」ボタンをクリックして下に表示されているファイルを追加します。
「New Application Context」ダイアログが表示されます。以下の画像のファイルをチェックした後、「OK」ボタンをクリックします。
「Project Structure」ダイアログに戻ると以下の画像のように表示されます。下の画像では下半分を表示していませんが、まだこの段階では警告メッセージは消えていません。
再び IntelliJ IDEA を再起動して、画面右下に「Spring Configuration Check」のメッセージが表示されないことを確認します。この後「Project Structure」ダイアログを表示すると警告メッセージは消えていました。
Tomcat が起動することを確認する
Gradle Tool Window から bootRun タスクを実行します。Tomcat が起動して “Started Application in …” のログが出力されることを確認します。
Tomcat を停止します。
ソースコード
application.properties
doma.dialect=org.seasar.doma.jdbc.dialect.H2Dialect spring.datasource.tomcat.url=jdbc:h2:mem:bootnpmgebdb spring.datasource.tomcat.username=sa spring.datasource.tomcat.password= spring.datasource.tomcat.driverClassName=org.h2.Driver spring.datasource.tomcat.initialSize=1 spring.datasource.tomcat.maxActive=1 spring.datasource.tomcat.maxIdle=1 spring.datasource.tomcat.minIdle=1 spring.datasource.tomcat.testOnBorrow=true spring.datasource.tomcat.validationQuery=select 1 spring.datasource.tomcat.validationQueryTimeout=5 spring.datasource.tomcat.removeAbandoned=true spring.datasource.tomcat.removeAbandonedTimeout=30 spring.datasource.tomcat.jdbc-interceptors=SlowQueryReport(threshold=5000) # spring.datasource.jmx-enabled は spring.datasource.tomcat.jmx-enabled と書かないこと。 # spring.datasource.tomcat.jmx-enabled だと機能しない。 spring.datasource.jmx-enabled=true spring.session.store-type=hash_map spring.freemarker.cache=true spring.freemarker.settings.number_format=computer spring.freemarker.charset=UTF-8 spring.freemarker.enabled=false spring.freemarker.prefer-file-system-access=false spring.thymeleaf.mode=HTML logging.level.root=INFO logging.level.org.seasar.doma=ERROR
application-develop.properties
spring.mail.host=localhost spring.mail.port=25 # Spring MVC logging.level.org.springframework.web=DEBUG # log4jdbc-log4j2 logging.level.jdbc.sqlonly=DEBUG logging.level.jdbc.sqltiming=INFO logging.level.jdbc.audit=INFO logging.level.jdbc.resultset=ERROR logging.level.jdbc.resultsettable=ERROR logging.level.jdbc.connection=DEBUG
application-product.properties
server.tomcat.basedir=C:/webapps/boot-npm-geb-sample logging.file=${server.tomcat.basedir}/logs/boot-npm-geb-sample.log slowquery.logging.file=${server.tomcat.basedir}/logs/slow-query.log spring.autoconfigure.exclude=com.integralblue.log4jdbc.spring.Log4jdbcAutoConfiguration spring.datasource.tomcat.initialSize=1 spring.datasource.tomcat.maxActive=1 spring.datasource.tomcat.maxIdle=1 spring.datasource.tomcat.minIdle=1 spring.mail.host=localhost spring.mail.port=25
application-unittest.properties
spring.autoconfigure.exclude=com.integralblue.log4jdbc.spring.Log4jdbcAutoConfiguration spring.mail.host=localhost spring.mail.port=25 logging.level.root=OFF
applicationContext-develop.xml
<aop:config> <aop:pointcut id="pointcutService" expression="execution(* ksbysample.webapp.bootnpmgeb..*Service.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcutService"/> </aop:config>
execution(* ksbysample.webapp.lending..*Service.*(..))
→execution(* ksbysample.webapp.bootnpmgeb..*Service.*(..))
に変更します。
applicationContext-product.xml
<aop:config> <aop:pointcut id="pointcutService" expression="execution(* ksbysample.webapp.bootnpmgeb..*Service.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcutService"/> </aop:config>
execution(* ksbysample.webapp.lending..*Service.*(..))
→execution(* ksbysample.webapp.bootnpmgeb..*Service.*(..))
に変更します。
applicationContext-unittest.xml
<aop:config> <aop:pointcut id="pointcutService" expression="execution(* ksbysample.webapp.bootnpmgeb..*Service.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcutService"/> </aop:config>
execution(* ksbysample.webapp.lending..*Service.*(..))
→execution(* ksbysample.webapp.bootnpmgeb..*Service.*(..))
に変更します。
messages_ja_JP.properties
- 中は空にします。
履歴
2017/07/22
初版発行。