Firebaseの技術情報サイト

Firebaseの技術情報サイト

Firebase活用の為の技術情報サイトです

誤った入力を防ぐインターフェース

誤った入力を防ぐインターフェース

ユーザーインターフェースをきちんと設計することで、誤ったデータの入力を防ぐ事が可能です。今回は、整数の値を入力するためのユーザーインターフェースの例を紹介します。

目次
ユーザーインターフェースの設計
フォームを HTML で記述
入力を1文字づつチェックする
誤った入力を防ぐ!
まとめ

ユーザーインターフェースの設計

今回は、プログラムに渡すための、整数を入力するユーザーインターフェースを設計します。

ユーザーインターフェースの設計の例なので、この例では、計算は行わず、入力された整数の値のみを表示します。

  • 整数を入力するためのフィールド
  • 入力された整数の値を表示するためのフィールド

の二つを用意します。

整数を入力するためのフィールドには、「Input data」というラベルをつけます。また、現在の入力された整数の値を表示するためのフィールには、「Current Value」というラベルをつけます。

現在の入力された整数の値を表示するフィールドには、誤って利用者が入力できないように、入力できないように設定します。

整数を入力するためのフィールドには、整数の入力を促すため、値が未入力の場合には「Please input integer value!」を、また、現在の入力された整数の値を表示するためのフィールドは、値が未入力の場合には「No input value」を表示します。入力された値が整数でない場合には、「Not an integer value」を表示するような仕様にします。

整数を入力するためのフィールは、整数以外の文字を入力できないようにして、整数以外が入力された場合には、表示しないようにして、入力されたデータが整数でない場合には、「Please input integer value!」を表示するようにします。

以上が例として紹介する、ユーザーインターフェースの仕様です。

フォームを HTML で記述

今回紹介する、ユーザーインターフェースのフォームを HTML で記述します。

ラベルは、「label」のタグをつけて記述して、整数を入力するフィールドと、現在の整数値を表示するフィールドには、「input」タグの「部品(DOM;Dodument Object Model)」を使います。

フィールの中身が空「""」の場合には、「placeholder」で指定した文字を表示できるので、初期状態や入力がない場合の表示に利用できます。 また、現在の整数値を表示するフィールドには利用者が誤って入力できないように、「readonly」を指定して入力を禁止します。

また、フィールドを特定するための「名前(id)」を指定しています。(integer_field / current_value)

<!DOCTYPE html>
<html>
  <head>
    <title>06: Integer input UI</title>
  </head>
  <body>
    <div>
      <label>Input data:</label>
      <input
        id="integer_field"
        type="text"
        placeholder="Please input integer value!"
      />
    </div>
    <div>
      <label>Current Value:</label>
      <input
        id="current_value"
        type="text"
        placeholder="No input value"
        readonly
      />
    </div>
  </body>
</html>

入力を1文字づつチェックする

数値以外のデータの入力ができないように、フィールドにデータをタイプする際に一文字づつデータをチェックするようにします。

入力フィールドは、フィールド上でキーボードのキーが離された状態(keyup)を検出して、処理を行う事ができます。 「addEventListener()」で、キーボードのキーが離された状態(=1文字の入力が完了した状態)イベントを検出して処理が呼び出せるようにします。

inputField.addEventListener("keyup", (event) => keyupEvent(event));

「keyup」がキーが離されたイベントで、このイベントを検出すると「keyupEvent()」の関数を呼び出すようにします。 あとは、表示する文字と、現在の整数の値を、それぞれ「currentString」と「currentValue」で覚えておくようにします。 最初の状態は、「currentString = ""」(何も入力されていない状態)で、この時の値は「」currentValue = NaN」で数値でない状態になるので、この値で初期化します。

「keyupEvent(e)」では、イベントのオブジェクトから、現在のフィールドの中身(入力された文字)と、最後に入力された文字(実際に離した文字のキー)を取得できます。 「e」がイベントのオブジェクトで、現在のフィールドの中身は「e.target.value」で取得できて、最後に入力された文字は、「e.keyCode」で取得できます。これは、文字のコード(ASCII コード)なので、「String.fromCharCode()」で文字型(string)に変換して利用します。

プログラム(javascript の例です)

/** Current field value (string) */
let currentString = "";
/** Current field value (number) */
let currentValue = NaN;
/** Input field DOM */
const inputField = document.getElementById("integer_field");
/** Current value field DOM */
const currentValueField = document.getElementById("current_value");
/* Adds key-up event for the input field */
inputField.addEventListener("keyup", (event) => keyupEvent(event));
/** Key-up event handler
 * @param e Key-up event object
 * */
function keyupEvent(e) {
  /** Actual input value */
  const value = e.target.value;
  /** The last input character */
  const lastChar = String.fromCharCode(e.keyCode);
  if (isNaN(parseInt(lastChar)) && lastChar !== "\b") {
    // Illegal input value
    inputField.value = currentString;
  } else {
    // Legal input value
    currentString = value;
  }
  // Updates the input field
  inputField.value = currentString;
  // Sets the current integer value
  currentValue = parseInt(currentString);
  // Update the current value feild
  if (isNaN(currentValue)) {
    // The current value is not a number
    currentValueField.value = "Not an integer value";
  } else {
    // The current value is an integer value
    currentValueField.value = currentValue;
  }
}

最後の文字が「\b(バックスペース)」以外で、数値でない場合には、入力される前の文字の値を入力フィールドにセットします。 つまり、最後の入力が、バックスペース以外の数値でない文字の場合は入力を「無視する」という処理をします。

入力された値がバックスペースか数値の場合には、現在の入力フィールドの値を使います。

現在の入力フィールの値を「currentValue」に数値に変換してセットします。更新した、文字列を入力フィールドにセットして、数値以外の入力を取り除きます。

こうすることで、入力フィールドに数字以外の文字列が入力されるのを防ぐことができます。

入力された整数の値を表示するフィードには、数字以外の文字を取り除いた文字を数値に変換した値をセットします。 この値は、最初は何もない状態「""」なので、「NaN」になります。「NaN」の場合には、「Not an integer value」を表示するようにします。 入力フィールの値が数値の場合はその数値が表示されます。

こうすることで、有効な数値が入力されたいない状態(=データがない状態)以外は、数値のデータという事になります。

誤った入力を防ぐ!

このようなユーザーインターフェースを設計・実装すると、ユーザーインターフェース上の入力データは、二つのケースに限定されることになります。

  • データがない状態(誤入力で数値以外のデータが無視された状態も含みます)
  • 数値

したがって、データが存在する場合には、その値は必ず数値になります。

入力されるデータを一文字づつチェックすることで、数字以外の文字の入力が禁止された状態になります。したがって、利用者の誤入力を最小限にすることが可能になります。

数値を足し算などの、計算に利用する際は、データがある場合は、数値を渡してデータ処理の関数を呼び出せば、データ処理側ではデータのチェックをする手間が省けます。もちろん、処理する側でチェックすればより安全になりますが、ユーザーインターフェースで入力の誤りを入力の際にチェックするので、利用者は、実際の処理を呼び出す前の段階で入力の修正が可能になるので、より使いやすく便利なプログラムにする事ができます。

まとめ

プログラムを作成する上で大切なポイントは幾つかあります。

その中で重要な例は、想定外の入力に対する処理と想定外の入力を防ぐ処理があります。 想定外の入力に対する処理を実装すれば、プログラムが想定外の動作をする可能性を低くする事ができます。こうした状態は、プログラムの暴走やフリーズ(プログラムが固まってしまった状態)につながるので、信頼性の高いプログラムを設計する上で重要です。 一方で、想定外の入力を防ぐ処理は、想定内の入力に限定することで、想定外のデータが処理される事を未然に防ぐ事が可能になります。当然、想定外の処理の発生を抑えられるので、プログラムが想定外の動作をすることも抑えることができます。しかし、それ以上に利用者にとってより使いやすいプログラムになります。プログラムの利用者は、プログラムの中身は通常は知らないのが普通です。また、人間なので意図的でなくても、誤った入力をしてしまうことは避けられません。そうした、誤入力などを未然に防ぐことで、プログラムの誤動作や後戻り作業を減らす事ができます。

そうした意味で、より良いユーザーインターフェースの設計と実装はプログラムを開発する上でとても重要です!