かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その25 )( 入力画面2を作成する4 )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その24 )( 入力画面2を作成する3 ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • 入力画面2の作成
    • 郵便番号検索API を利用して、「郵便番号」を入力したら「住所」に都道府県・市区町村・町丁目名がセットされる処理を実装します。

参照したサイト・書籍

  1. Autocomplete | jQuery UI
    https://jqueryui.com/autocomplete/

  2. jquery-ui
    https://www.npmjs.com/package/jquery-ui

  3. [jQuery UI] AutocompleteのソースをAjaxで取得する
    http://www.84kure.com/blog/2015/07/27/jquery-ui-autocompleteのソースをajaxで取得する/

  4. 1分でわかるjQuery $.ajaxによるJSONJSONP読み込み方法
    https://iwb.jp/jquery-ajax-jsonp/

  5. Display jquery ui auto-complete list on focus event
    https://stackoverflow.com/questions/4132058/display-jquery-ui-auto-complete-list-on-focus-event

  6. AJAX通信をするときはタイムアウト処理を必ず入れてほしい(切実)
    https://qiita.com/tonkotsuboy_com/items/d1b3cf45ae5135441f9b

  7. How to include jQuery UI into my project using Webpack?
    https://stackoverflow.com/questions/38796673/how-to-include-jquery-ui-into-my-project-using-webpack

目次

  1. npm で jquery-ui をインストールする
  2. 入力された郵便番号の住所一覧を jQuery-UI の autocomplete で表示・選択する処理を実装する
  3. 動作確認
  4. 次回は。。。

手順

npm で jquery-ui をインストールする

郵便番号を入力したら jQuery-UI の autocomplete で「住所」の入力項目の下にドロップダウンリストを表示して選択できるようにします。

admin-lte パッケージ内の plugins/jQueryUI の下には js ファイルしかないのですが、autocomplete の表示には css ファイルも必要なので npm で jquery-ui パッケージをインストールします。

npm install --save jquery-ui コマンドを実行して jQueryUI をインストールします。

f:id:ksby:20171009195323p:plain

package.jsonjquery-ui の css をコピーする npm-scirpts を追加します。

  "scripts": {
    ..........
    "copy:all": "run-p copy:bootstrap copy:admin-lte copy:font-awesome copy:ionicons copy:jquery-ui-css",
    ..........
    "copy:ionicons": "cpx node_modules/ionicons/dist/{css,fonts}/**/* src/main/resources/static/vendor/ionicons",
    "copy:jquery-ui-css": "cpx node_modules/jquery-ui/themes/base/**/* src/main/resources/static/vendor/jquery-ui/css",
    ..........
  },
  • "copy:jquery-ui-css": "cpx node_modules/jquery-ui/themes/base/**/* src/main/resources/static/vendor/jquery-ui/css" を追加します。
  • copy:all の最後に copy:jquery-ui-css を追加します。

npm run copy:jquery-ui-css コマンドを実行して css ファイルをコピーします。

f:id:ksby:20171009203041p:plain f:id:ksby:20171009203214p:plain

入力された郵便番号の住所一覧を jQuery-UI の autocomplete で表示・選択する処理を実装する

src/main/assets/js/inquiry/input02.js を以下のように変更します。

"use strict";

var Form = require("lib/class/Form.js");
var converter = require("lib/util/converter.js");
var validator = require("lib/util/validator.js");
require("jquery-ui/ui/widgets/autocomplete.js");

..........

var addressList = [];
var findAddressListByZipCode = function (event) {
    // 入力チェックエラーが発生している場合には処理を中断する
    if (event.isPropagationStopped()) {
        return;
    }

    // 郵便番号の入力項目全てにフォーカスがセットされていなければ処理を中断する
    if (!form.isAllFocused(form, ["#zipcode1", "#zipcode2"])) {
        return;
    }

    // 郵便番号検索APIで住所を検索する
    addressList = [];
    $.ajax({
        type: "get",
        url: "http://zipcloud.ibsnet.co.jp/api/search",
        data: {zipcode: $("#zipcode1").val() + $("#zipcode2").val()},
        cache: false,
        dataType: "jsonp",
        jsonpCallback: "callback",
        timeout: 5000
    }).then(
        function (json) {
            if (json.status === 200) {
                if (json.results === null) {
                    form.setError("#form-group-address", "郵便番号に該当する住所はありませんでした");
                    return;
                }

                json.results.forEach(function (result) {
                    addressList.push(result.address1 + result.address2 + result.address3);
                });
                // 「住所」の入力項目の下に autocomplete のドロップダウンリストを表示する
                if ($("#address").is(":focus")) {
                    $("#address").autocomplete("search");
                }
            } else {
                form.setError("#form-group-address", json.message);
            }
        },
        function () {
            form.setError("#form-group-address", "郵便番号APIの呼び出しに失敗しました");
        }
    );
};

..........

$(document).ready(function () {
    // 入力チェック用の validator 関数をセットする
    ..........

    // 入力された郵便番号から住所を取得する処理をセットする
    $("#address").on("focus", findAddressListByZipCode);
    $("#address").autocomplete({
        // source には addressList 変数を直接指定するのではなく、
        // 関数を渡して findAddressListByZipCode 関数で変更された addressList
        // のデータが表示されるようにする
        source: function (request, response) {
            // 「住所」に何も入力されていない時だけドロップダウンリストを表示する
            if ($("#address").val() === "") {
                response(addressList);
            } else {
                response([]);
            }
        },
        // minLength: 0 を指定しないと findAddressListByZipCode 関数内で
        // $("#address").autocomplete("search"); を呼び出した時にドロップダウンリスト
        // が表示されない
        minLength: 0
    });

    ..........
});
  • require("jquery-ui/ui/widgets/autocomplete.js"); を追加します。
  • var addressList = []; を追加します。
  • findAddressListByZipCode 関数を追加します。
  • $(document).ready(function () { ... } の以下の点を変更します。
    • ["#zipcode1", "#zipcode2"].forEach(function (id) { $(id).on("blur", findAddressListByZipCode); }); を追加します。
    • $("#address").autocomplete({ ... }); を追加します。

src/main/resources/templates/web/inquiry/input02.html の以下の点を変更します。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{web/common/fragments :: common_header(~{::title}, ~{::link}, ~{::style})}">
  <title>入力フォーム - 入力画面2</title>

  <link rel="stylesheet" href="/vendor/jquery-ui/css/all.css">
</head>

..........
  • <link rel="stylesheet" href="/vendor/jquery-ui/css/all.css"> を追加します。

ここまでの実装で npm run springboot コマンドを実行すると、Module not found: Error: Can't resolve 'jquery' in ... というエラーメッセージが大量に出力されます。

f:id:ksby:20171009231015p:plain

webpack.config.js で jquery の alias を定義すればこのエラーは出なくなります。以下のように変更します。

    resolve: {
        modules: [
            "node_modules",
            "src/main/assets/js"
        ],
        alias: {
            jquery: "admin-lte/plugins/jQuery/jquery-2.2.3.min.js"
        }
    },
  • alias: { jquery: "admin-lte/plugins/jQuery/jquery-2.2.3.min.js" } を追加します。

再び npm run springboot コマンドを実行すると今度はエラーが出ません。

f:id:ksby:20171009231807p:plain

動作確認

動作確認します。npm run springboot コマンドは実行済なので、Tomcat を起動した後、ブラウザで http://localhost:9080/inquiry/input/01/ にアクセスします。

データを入力してから、「次へ」ボタンをクリックして入力画面2へ遷移します。

f:id:ksby:20171009232944p:plain

「郵便番号」に 079-0177 を入力して「住所」にフォーカスを移動すると、フォーカスが移動した直後はドロップダウンリストは表示されませんが、郵便番号検索APIの検索が終了するとドロップダウンリストが表示されます。

f:id:ksby:20171009233117p:plain

上下矢印キーで選択すると、選択された項目が「住所」の入力項目にセットされます。

f:id:ksby:20171009233516p:plain

選択してから追加で "1丁目" と入力しても特に動作には問題はありません。

f:id:ksby:20171010000114p:plain

存在しない郵便番号を入力すると「住所」の入力項目の下に "郵便番号に該当する住所はありませんでした" のメッセージが表示されます。

f:id:ksby:20171009235701p:plain

次回は。。。

サーバ側のテストを書きます。

履歴

2017/10/10
初版発行。