かんがるーさんの日記

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

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

概要

記事一覧はこちらです。

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

  • 今回の手順で確認できるのは以下の内容です。
    • 入力画面1の作成
    • 前回からの続きで、今回も Javascript の処理を実装します。

参照したサイト・書籍

  1. JQUERY】自動的にカナ入力してくれるAUTOKANA.JSプラグインはいまや必須!
    http://plugmin.co/472/

  2. autokana
    https://github.com/harisenbon/autokana

  3. How to use jQuery-Plugins w/Webpack?
    https://laracasts.com/discuss/channels/elixir/how-to-use-jquery-plugins-wwebpack

  4. Webpackを使い倒す
    http://thujikun.github.io/blog/2014/12/07/webpack/

  5. ProvidePlugin
    https://webpack.js.org/plugins/provide-plugin/

目次

  1. autokana で「お名前(漢字)」が入力されたら「お名前(かな)」を自動入力させる
  2. ProvidePlugin を利用して jQuery を各ファイルで require 不要にする
  3. 「お名前(漢字)」「お名前(かな)」をどちらも入力チェックエラーにしてから、「お名前(漢字)」を入力して「お名前(かな)」に autokana で自動入力されても「お名前(かな)」の入力チェックエラー状態が解除されないのを修正する
  4. メモ書き
    1. input01.js で関数を var xxx = function() { ... } で記述しているのは IntelliJ IDEA が見やすく表示してくれるからである

手順

autokana で「お名前(漢字)」が入力されたら「お名前(かな)」を自動入力させる

日本語入力に対するふりがな/フリガナを自動的に別フィールドに入力する autokana という jQueryプラグインがあることを知りましたので、インストールして「お名前(漢字)」に入力された文字のかな文字列を「お名前(かな)」に自動入力されるようにしてみます。

autokana は npm ではインストールできませんので、autokanaGitHub のページから jquery.autoKana.js をダウンロードします。

src/main/assets/js/lib の下に vendor/autokana ディレクトリを新規作成した後、その下に jquery.autoKana.js を配置します。

src/main/assets/js/inquiry/input01.js の以下の点を変更します。

window.$ = window.jQuery = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js");
var Form = require("lib/class/Form.js");
var converter = require("lib/util/converter.js");
var validator = require("lib/util/validator.js");
require("vendor/autokana/jquery.autoKana.js");

..........

$(document).ready(function () {
    // 「お名前(漢字)」が入力された時に、かな文字列を「お名前(かな)」に自動入力されるようにする
    $.fn.autoKana('#lastname', '#lastkana');
    $.fn.autoKana('#firstname', '#firstkana');

    // 入力チェック用の validator 関数をセットする
    $("#lastname").on("blur", nameValidator);
    $("#firstname").on("blur", nameValidator);
    $("#lastkana").on("blur", kanaValidator);
    $("#firstkana").on("blur", kanaValidator);
    $("input:radio[name='sex']").on("blur", sexValidator);
    $("#age").on("blur", ageValidator);
    $("#job").on("blur", jobValidator);

    // 「次へ」ボタンクリック時の処理をセットする
    $(".js-btn-next").on("click", btnNextClickHandler)
});
  • jQuery を require する変数を var $ =window.$ = window.jQuery = に変更します。
  • require("vendor/autokana/jquery.autoKana.js"); を追加します。
  • $(document).ready(function () { ... } の中に以下の2行を追加します。
    • $.fn.autoKana('#lastname', '#lastkana');
    • $.fn.autoKana('#firstname', '#firstkana');

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

「お名前(漢字)」に入力すると「お名前(かな)」にかな文字列が入力されました。これは便利ですね。

f:id:ksby:20170902071806p:plain

ProvidePlugin を利用して jQuery を各ファイルで require 不要にする

jQuery を利用する時には各 js ファイルで var $ = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js"); を記述していましたが、ProvidePlugin を利用すると省略できるそうなので設定してみます。

webpack.config.js を以下のように変更します。

var webpack = require('webpack');

module.exports = {
    entry: {
        "js/app": ["./src/main/assets/js/app.js"],
        "js/inquiry/input01": ["./src/main/assets/js/inquiry/input01.js"],
        "js/inquiry/input02": ["./src/main/assets/js/inquiry/input02.js"],
        "js/inquiry/input03": ["./src/main/assets/js/inquiry/input03.js"],
        "js/inquiry/confirm": ["./src/main/assets/js/inquiry/confirm.js"]
    },
    output: {
        path: __dirname + "/src/main/resources/static",
        publicPath: "/",
        filename: "[name].js"
    },
    resolve: {
        modules: [
            "node_modules",
            "src/main/assets/js"
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "admin-lte/plugins/jQuery/jquery-2.2.3.min.js",
            jQuery: "admin-lte/plugins/jQuery/jquery-2.2.3.min.js"
        })
    ]
};
  • var webpack = require('webpack'); を追加します。
  • plugins: [ new webpack.ProvidePlugin({ ... }) ] を追加します。

src/main/assets/js の下の全ての js ファイルから require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js"); の行を削除します。

npm run springboot コマンドを停止して起動し直すとエラーが出ずに起動し、入力チェックの処理や autokana も問題なく動作しました。

「お名前(漢字)」「お名前(かな)」をどちらも入力チェックエラーにしてから、「お名前(漢字)」を入力して「お名前(かな)」に autokana で自動入力されても「お名前(かな)」の入力チェックエラー状態が解除されないのを修正する

autokana で「お名前(かな)」に自動入力されるようにしたのですが、今の実装だと「お名前(漢字)」「お名前(かな)」をどちらも入力チェックエラーにしてから、

f:id:ksby:20170902080436p:plain

「お名前(漢字)」にカーソルを移動して漢字を入力し「お名前(かな)」にかな文字列が反映されても、「お名前(漢字)」の「名」から「お名前(かな)」の「姓」にカーソルが移動したタイミングでは「お名前(かな)」の入力チェックエラー状態が解除されません。

f:id:ksby:20170902081421p:plain

解除されるようにしてみます。

src/main/assets/js/lib/class/Form.js の以下の点を変更します。

..........

/**
 * 渡された id を form.focused にセットして
 * focused イベントが発生したことにする
 * @param {Form} form - Form オブジェクト
 * @param {string} id - focused イベントを発生したことにする要素の id
 */
Form.prototype.setFocused = function (form, id) {
    form.focused[id] = true;
};

/**
 * 渡された idList にセットされている id を form.focused にセットして
 * focused イベントが発生したことにする
 * @param {Form} form - Form オブジェクト
 * @param {Array} idList - focused イベントが発生したことにする要素の id の配列
 */
Form.prototype.setFocusedFromList = function (form, idList) {
    idList.forEach(function (id) {
        form.setFocused(form, id);
    })
};

/**
 * form.idList にセットされている id を全て form.focused にセットして
 * focused イベントが発生したことにする
 * @param {Form} form - Form オブジェクト
 */
Form.prototype.forceAllFocused = function (form) {
    form.setFocusedFromList(form, form.idList);
};

/**
 * Form オブジェクトの idList に列挙された id の要素の focus イベントハンドラに
 * Form.focused 配列に id をセットする関数をセットする
 * @param {Form} form - Form オブジェクト
 */
function addFocusEventListener(form) {
    form.idList.forEach(function (id) {
        $(id).on("focus", function (event) {
            form.setFocused(form, id);
        })
    })
}
  • Form.prototype.setFocused メソッドを追加します。
  • Form.prototype.setFocusedFromList メソッドを追加します。
  • Form.prototype.forceAllFocused メソッド内の処理を form.idList.forEach(function (id) { ... }form.setFocusedFromList(form, form.idList); に変更します。
  • addFocusEventListener 関数内の処理を form.focused[id] = true;form.setFocused(form, id); に変更します。

src/main/assets/js/inquiry/input01.js の以下の点を変更します。

var kanaAutoInputValidator = function (event) {
    var idList = ["#lastkana", "#firstkana"];
    // 「お名前(漢字)」を入力して「お名前(かな)」が自動入力された時に、
    // 「お名前(かな)」の入力チェックが実行されるようにする
    if (!form.isAnyEmpty(idList)) {
        form.setFocusedFromList(form, idList);
        kanaValidator(event);
    }
};

..........

$(document).ready(function () {
    // 「お名前(漢字)」が入力された時に、かな文字列を「お名前(かな)」に自動入力されるようにする
    $.fn.autoKana('#lastname', '#lastkana');
    $.fn.autoKana('#firstname', '#firstkana');

    // 入力チェック用の validator 関数をセットする
    $("#lastname")
        .on("blur", nameValidator)
        .on("blur", kanaAutoInputValidator);
    $("#firstname")
        .on("blur", nameValidator)
        .on("blur", kanaAutoInputValidator);
    $("#lastkana").on("blur", kanaValidator);
    $("#firstkana").on("blur", kanaValidator);
    $("input:radio[name='sex']").on("blur", sexValidator);
    $("#age").on("blur", ageValidator);
    $("#job").on("blur", jobValidator);

    // 「次へ」ボタンクリック時の処理をセットする
    $(".js-btn-next").on("click", btnNextClickHandler)
});
  • kanaAutoInputValidator メソッドを追加します。
  • $(document).ready(function () { ... } 内の以下の点を変更します。
    • $("#lastname")$("#firstname").on("blur", kanaAutoInputValidator) を追加します。

動作確認します。

http://localhost:9080/inquiry/input/01/ にアクセスして「お名前(漢字)」「お名前(かな)」を入力チェックエラー状態にした後、

f:id:ksby:20170902094531p:plain

マウスで「お名前(漢字)」の「姓」にカーソルを移動してから「姓」「名」を入力すると「お名前(かな)」にかな文字列が自動入力されて、かつ「お名前(漢字)」の「名」から「お名前(かな)」の「姓」にカーソルが移動した時に「お名前(かな)」も入力チェック OK の状態になります。

f:id:ksby:20170902094840p:plain

Ctrl+F5 を押してリロードした後、普通に「お名前(漢字)」を入力しても「お名前(かな)」が入力チェック OK の状態になります。

f:id:ksby:20170902095024p:plain

Ctrl+F5 を押してリロードした後、「お名前(漢字)」にかな文字列にできない英字を入力した場合には「お名前(かな)」の入力チェックは動作せず何も変わりません。

f:id:ksby:20170902095215p:plain

Ctrl+F5 を押してリロードした後、「お名前(漢字)」の「姓」だけ入力した場合には「お名前(漢字)」は入力チェックエラー状態になりますが「お名前(かな)」の入力チェックは動作せず何も変わりません。

f:id:ksby:20170902095443p:plain

問題なさそうです。次回は Form クラスを作成してセッションに保存する処理を実装します。

メモ書き

input01.js で関数を var xxx = function() { ... } で記述しているのは IntelliJ IDEA が見やすく表示してくれるからである

最初は function xxx() { ... } の形式で書いていたのですが、var xxx = function() { ... } の形式で書くと IntelliJ IDEA が関数名毎に色を変えて表示してくれるので、input01.js では var xxx = function() { ... } の形式で書くことにしました。

function xxx() { ... } の形式で書くと IntelliJ IDEA 上では以下のように関数名は全て同じ色で表示されますが、

f:id:ksby:20170902102427p:plain f:id:ksby:20170902102553p:plain

var xxx = function() { ... } の形式で書くと IntelliJ IDEA の Semantic highlighting の機能で関数名毎に色を変えて表示してくれます(変数名とみなされているため)。

f:id:ksby:20170902102902p:plain f:id:ksby:20170902103005p:plain

ただし var xxx = function() { ... } は上に書いておかないと下の関数では使用できないようなので、その点だけ注意が必要です。

履歴

2017/09/02
初版発行。