Spring Boot + npm + Geb で入力フォームを作ってテストする ( その58 )( 確認画面を作成する )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
- 確認画面の作成
- 今回は入力されたデータを画面に表示する処理を作成します。保存された入力値を画面に表示する文字列に変換する処理を ModelMapper のデータ変換用クラス内で行います。
参照したサイト・書籍
目次
- Form クラスを作成する
- ModelMapper で使用するデータ変換用クラスを作成する
- InquiryConfirmController クラスを変更する
- confirm.html を変更する
- 動作確認
- 次は。。。
手順
Form クラスを作成する
src/main/java/ksbysample/webapp/bootnpmgeb/web/inquiry/form の下に ConfirmForm.java を新規作成し、以下の内容を記述します。
package ksbysample.webapp.bootnpmgeb.web.inquiry.form; import lombok.Data; /** * 確認画面用 Form クラス */ @Data public class ConfirmForm { /************************ * 入力画面1の入力項目用 ************************/ private String name; private String kana; private String sex; private String age; private String job; /************************ * 入力画面2の入力項目用 ************************/ private String zipcode; private String address; private String tel; private String email; /************************ * 入力画面3の入力項目用 ************************/ private String type1; private String type2; private String inquiry; private List<String> survey; }
ModelMapper で使用するデータ変換用クラスを作成する
データ変換のルールを定義するクラスを配置するパッケージを作成します。src/main/java/ksbysample/webapp/bootnpmgeb の下に mapper パッケージを作成します。
src/main/java/ksbysample/webapp/bootnpmgeb/mapper の下に SessionData2ConfirmFormTypeMap.java を新規作成し、以下の内容を記述します。
package ksbysample.webapp.bootnpmgeb.mapper; import com.github.rozidan.springboot.modelmapper.TypeMapConfigurer; import ksbysample.webapp.bootnpmgeb.helper.db.SurveyOptionsHelper; import ksbysample.webapp.bootnpmgeb.session.SessionData; import ksbysample.webapp.bootnpmgeb.values.*; import ksbysample.webapp.bootnpmgeb.web.inquiry.form.ConfirmForm; import ksbysample.webapp.bootnpmgeb.web.inquiry.form.InquiryInput01Form; import ksbysample.webapp.bootnpmgeb.web.inquiry.form.InquiryInput02Form; import ksbysample.webapp.bootnpmgeb.web.inquiry.form.InquiryInput03Form; import org.apache.commons.lang3.StringUtils; import org.modelmapper.TypeMap; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.Map; import java.util.stream.Collectors; /** * SessionData --> ConfirmForm データ変換用クラス */ @Component public class SessionData2ConfirmFormTypeMap extends TypeMapConfigurer<SessionData, ConfirmForm> { private final ValuesHelper vh; private final SurveyOptionsHelper soh; /** * コンストラクタ * * @param vh {@ValuesHelper} オブジェクト * @param soh {@SurveyOptionsHelper} オブジェクト */ public SessionData2ConfirmFormTypeMap(ValuesHelper vh , SurveyOptionsHelper soh) { super(); this.vh = vh; this.soh = soh; } @Override public void configure(TypeMap<SessionData, ConfirmForm> typeMap) { typeMap.setPreConverter(context -> { SessionData sessionData = context.getSource(); InquiryInput01Form inquiryInput01Form = sessionData.getInquiryInput01Form(); InquiryInput02Form inquiryInput02Form = sessionData.getInquiryInput02Form(); InquiryInput03Form inquiryInput03Form = sessionData.getInquiryInput03Form(); ConfirmForm confirmForm = context.getDestination(); /************************ * 入力画面1の入力項目用 ************************/ confirmForm.setName(join(" " , inquiryInput01Form.getLastname() , inquiryInput01Form.getFirstname())); confirmForm.setKana(join(" " , inquiryInput01Form.getLastkana() , inquiryInput01Form.getFirstkana())); confirmForm.setSex(vh.getText(SexValues.class, inquiryInput01Form.getSex())); confirmForm.setAge(inquiryInput01Form.getAge()); confirmForm.setJob(vh.getText(JobValues.class, inquiryInput01Form.getJob())); /************************ * 入力画面2の入力項目用 ************************/ confirmForm.setZipcode(join("-" , inquiryInput02Form.getZipcode1() , inquiryInput02Form.getZipcode2())); confirmForm.setAddress(inquiryInput02Form.getAddress()); confirmForm.setTel(join("-" , inquiryInput02Form.getTel1() , inquiryInput02Form.getTel2() , inquiryInput02Form.getTel3())); confirmForm.setEmail(inquiryInput02Form.getEmail()); /************************ * 入力画面3の入力項目用 ************************/ confirmForm.setType1(vh.getText(Type1Values.class, inquiryInput03Form.getType1())); confirmForm.setType2(inquiryInput03Form.getType2().stream() .map(type2 -> vh.getText(Type2Values.class, type2)) .collect(Collectors.joining("、"))); confirmForm.setInquiry(inquiryInput03Form.getInquiry()); Map<String, String> surveyOptionsMap = this.soh.selectItemList("survey").stream() .collect(Collectors.toMap(s -> s.getItemValue(), s -> s.getItemName())); confirmForm.setSurvey(inquiryInput03Form.getSurvey().stream() .map(survey -> surveyOptionsMap.get(survey)) .collect(Collectors.toList())); return context.getDestination(); }); typeMap.addMappings(mapping -> mapping.skip(ConfirmForm::setName)) .addMappings(mapping -> mapping.skip(ConfirmForm::setKana)) .addMappings(mapping -> mapping.skip(ConfirmForm::setSex)) .addMappings(mapping -> mapping.skip(ConfirmForm::setAge)) .addMappings(mapping -> mapping.skip(ConfirmForm::setJob)) .addMappings(mapping -> mapping.skip(ConfirmForm::setZipcode)) .addMappings(mapping -> mapping.skip(ConfirmForm::setAddress)) .addMappings(mapping -> mapping.skip(ConfirmForm::setTel)) .addMappings(mapping -> mapping.skip(ConfirmForm::setEmail)) .addMappings(mapping -> mapping.skip(ConfirmForm::setType1)) .addMappings(mapping -> mapping.skip(ConfirmForm::setType2)) .addMappings(mapping -> mapping.skip(ConfirmForm::setInquiry)) .addMappings(mapping -> mapping.skip(ConfirmForm::setSurvey)); } /** * 文字列を指定された区切り文字で結合する。文字列が全て空の場合には空文字列を返す。 * * @param delimiter 区切り文字 * @param arg 結合する文字列の配列 * @return 結合した文字列 */ private String join(String delimiter, String... arg) { boolean isAllEmpty = arg == null || Arrays.asList(arg).stream().allMatch(str -> StringUtils.isEmpty(str)); return isAllEmpty ? StringUtils.EMPTY : Arrays.asList(arg).stream().collect(Collectors.joining(delimiter)); } }
InquiryConfirmController クラスを変更する
src/main/java/ksbysample/webapp/bootnpmgeb/web/inquiry/InquiryConfirmController.java の以下の点を変更します。
@Controller @RequestMapping("/inquiry/confirm") @SessionAttributes("sessionData") public class InquiryConfirmController { private static final String TEMPLATE_BASE = "web/inquiry"; private static final String TEMPLATE_CONFIRM = TEMPLATE_BASE + "/confirm"; private final ModelMapper modelMapper; /** * コンストラクタ * * @param modelMapper {@ModelMapper} オブジェクト */ public InquiryConfirmController(ModelMapper modelMapper) { this.modelMapper = modelMapper; } /** * 確認画面 初期表示処理 * * @param confirmForm {@ConfirmForm} オブジェクト * @param sessionData {@SessionData} オブジェクト * @return 確認画面の Thymeleaf テンプレートファイルのパス */ @GetMapping public String index(ConfirmForm confirmForm , SessionData sessionData) { modelMapper.map(sessionData, confirmForm); return TEMPLATE_CONFIRM; } .......... }
private final ModelMapper modelMapper;
を追加します。- コンストラクタを追加します。
- index メソッドに
ConfirmForm confirmForm
,SessionData sessionData
の引数を追加し、modelMapper.map(sessionData, confirmForm);
を追加します。
confirm.html を変更する
src/main/resources/templates/web/inquiry/confirm.html の以下の点を変更します。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head th:replace="~{web/common/fragments :: common_header(~{::title}, ~{::link}, ~{::style})}"> <title>入力フォーム - 確認画面</title> <style> /* セルの上部の罫線を表示しないようようにし、セル内の余白を詰める */ .table > tbody > tr > th, .table > tbody > tr > td { border-top: none; padding: 5px; } </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> 確認画面 </h1> </section> <!-- Main content --> <section class="content"> <div class="row"> <div class="col-xs-12"> <!--/*@thymesVar id="confirmForm" type="ksbysample.webapp.bootnpmgeb.web.inquiry.form.ConfirmForm"*/--> <form id="confirmForm" method="post" action="" th:action="@{/inquiry/confirm/}" th:object="${confirmForm}"> <table class="table"> <colgroup> <col width="15%"/> <col width="85%"/> </colgroup> <!-- 入力画面1の項目 --> <tr> <th nowrap>お名前(漢字)</th> <td th:text="*{name}">田中 太郎</td> </tr> <tr> <th nowrap>お名前(かな)</th> <td th:text="*{kana}">たなか たろう</td> </tr> <tr> <th nowrap>性別</th> <td th:text="*{sex}">男性</td> </tr> <tr> <th nowrap>年齢</th> <td> <th:block th:text="*{age}">30</th:block> 歳 </td> </tr> <tr> <th nowrap>職業</th> <td th:text="*{job}">会社員</td> </tr> <tr> <td colspan="2"> <button class="btn bg-blue js-btn-input01"><i class="fa fa-arrow-left"></i> 修正する</button> </td> </tr> <!-- 入力画面2の項目 --> <tr> <th nowrap>郵便番号</th> <td>〒 <th:block th:text="*{zipcode}">102-0072</th:block> </td> </tr> <tr> <th nowrap>住所</th> <td th:text="*{address}">東京都千代田区飯田橋1-1</td> </tr> <tr> <th nowrap>電話番号</th> <td th:text="*{tel}">03-1234-5678</td> </tr> <tr> <th nowrap>メールアドレス</th> <td th:text="*{email}">taro.tanaka@sample.co.jp</td> </tr> <tr> <td colspan="2"> <button class="btn bg-blue js-btn-input02"><i class="fa fa-arrow-left"></i> 修正する</button> </td> </tr> <!-- 入力画面3の項目 --> <tr> <th nowrap>お問い合わせの種類1</th> <td th:text="*{type1}">製品に関するお問い合わせ</td> </tr> <tr> <th nowrap>お問い合わせの種類2</th> <td th:text="*{type2}">見積が欲しい</td> </tr> <tr> <th nowrap>お問い合わせの内容</th> <td th:utext="*{inquiry} ? ${#strings.replace(#strings.escapeXml(confirmForm.inquiry), T(java.lang.System).getProperty('line.separator'), '<br />')} : ''"> ここに、<br/> 入力されたお問い合わせの内容が表示されます。 </td> </tr> <tr> <th nowrap>アンケート</th> <td> <ul style="padding-left: 20px" th:each="sv : *{survey}"> <li th:text="${sv}">選択肢1だけ長くしてみる</li> </ul> </td> </tr> <tr> <td colspan="2"> <button class="btn bg-blue js-btn-input03"><i class="fa fa-arrow-left"></i> 修正する</button> </td> </tr> </table> <div class="text-center"> <button class="btn bg-green js-btn-send"><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/confirm.js"></script> </body> </html>
- form タグの上に
<!--/*@thymesVar id="confirmForm" type="ksbysample.webapp.bootnpmgeb.web.inquiry.form.ConfirmForm"*/-->
を追加します。 - form タグの末尾に
th:object="${confirmForm}"
を追加します。 - 各表示項目を以下のように変更します。
- 基本的には td タグに
th:text="*{...}"
(... には入力項目に対応した変数を記述) を追加します。 - textarea の入力項目である「お問い合わせの内容」には
th:utext="*{inquiry} ? ${#strings.replace(#strings.escapeXml(confirmForm.inquiry), T(java.lang.System).getProperty('line.separator'), '<br />')} : ''"
を追加します。改行は<br/>
に変換して出力します。 - 「アンケート」はリストを出力するので ul タグに
th:each="sv : *{survey}"
を、li タグにth:text="${sv}"
を追加します。
- 基本的には td タグに
動作確認
動作確認します。npm run springboot コマンドを実行し Tomcat を起動した後、ブラウザで http://localhost:9080/inquiry/input/01/ にアクセスします。
入力画面1~3に以下の画像のデータを入力します。
確認画面を表示すると入力したデータが表示されます。
- ラジオボタンやドロップダウンリストで選択する項目は、選択された文字列が表示されています。
- 「郵便番号」や「電話番号」は入力した値が "-" で結合して表示されています。
- 「お問い合わせの種類2」は選択した項目が "、" で結合して表示されています。
- 「お問い合わせの内容」は改行した箇所は改行されて表示されています。
- 「アンケート」は選択した項目が列挙されています。
「職業」や「アンケート」を選択しなかったり、「電話番号」を入力しないと、
確認画面の「職業」「電話番号」「アンケート」には何も表示されません。
次は。。。
「修正する」ボタンの処理→「送信する」ボタンの処理の順に実装します。
履歴
2018/06/13
初版発行。