業務UI改善!複数コード入力の利便性を向上させてみよう

2024年11月7日木曜日

react

t f B! P L

複数のコードを入力するUIを改善する方法を考えてみたいと思います。
コンシューマ向けのWEBアプリでは見かけることは少ないですが、業務アプリでは、次のような複数のコードをテキストボックスで入力させるシーンが時々あります。

複数コードの入力イメージ

もちろん、専用のコード検索画面を作って複数選択する機能を実装することもあります。しかし、コードの種類がそこまで多くなく、ユーザーがコードを暗記している場合や、開発工数との兼ね合いで画面を作れない場合、コードをユーザーに直接入力させるUIにすることがあります。

この記事では、そんなな複数コードの入力を効率よくするためのUI改善について、Reactを使ったサンプルコードで紹介したいと思います。

スポンサーリンク

複数のコードを入力するUI改善について考える

複数のコードを入力するUIでは、少ない手数で素早くを入力できることが望ましい。

例えば、次のような入力方法の場合、毎回「追加」を押して入力欄を増やさなければならず、入力するコードの数が多いとユーザーにとって負担になります。

追加ボタンを押してコードの入力欄を増やすUIの例
追加ボタンを押してコードの入力欄を増やすUIの例

上記の改善策としては、あらかじめ必要な数の入力欄を用意する方法が考えられます。ただし、入力するコードの上限が決まっていない場合には適用できません。
また、入力欄が複数に分かれているため、Excelのように複数の値をまとめてコピー&ペーストできず、ユーザーがコードを1つずつ入力する手間が増える。

あらかじめ必要な数の入力欄を用意する方法
あらかじめ必要な数の入力欄を用意する方法

スポンサーリンク

UI改善内容

ここまで挙げた問題点を踏まえると、次の3つの改善したUIがあるとよさそうです。

1. コードの追加が容易

コードを入力すると、新しい入力欄が自動的に追加される仕組みにします。これにより、ユーザーが入力ボックスをいちいち追加する手間が省けます。

コードの追加が容易な例

2. 入力したコードの削除が容易

コードを削除する際に、「×」ボタンを押すだけで簡単に消せるようにします。これにより、操作が直感的になり、使いやすさが向上します。

入力したコードの削除が容易な例

スポンサーリンク

3. Excelなどでコピーした値をまとめて貼り付けられる

Excelなどの外部データからコピーした複数のコードを、まとめて貼り付けられるようにします。これにより、大量のコード入力が必要な場合でも、短時間で効率よく処理できます。

Excelなどでコピーした値をまとめて貼り付けられる例

UI改善内容を踏まえた複数コード入力の実装

以下は、Reactを使って上記の改善内容を取り入れたコード入力コンポーネントのサンプルです。

import React, { useEffect, useState } from 'react';

// コンポーネントのプロパティの型を定義
type MultiCodeInputProps = {
  initialCodes?: string[]; // 初期コードの配列(オプション)
  onCodesChange?: (codes: string[]) => void; // コードが変更された際に呼ばれるコールバック関数
};

// 複数のコードを入力できるコンポーネント
const MultiCodeInput: React.FC<MultiCodeInputProps> = ({ initialCodes = [], onCodesChange }) => {
  const [inputValue, setInputValue] = useState(''); // 新しいコードを入力するための状態
  const [codes, setCodes] = useState<string[]>(initialCodes); // 現在のコードの配列

  // コードが有効かどうかをチェックする関数(3桁の数字を有効とする)
  const isValidCode = (code: string) => /^\d{3}$/.test(code);

  // 複数のコードを追加する関数(有効なコードのみを追加)
  const addCodes = (newCodes: string[]) => {
    const validCodes = newCodes.filter(isValidCode); // 入力したコードの中から有効なものだけを抽出
    setCodes((prevCodes) => {
      const updatedCodes = [...prevCodes, ...validCodes]; // 既存のコードと新しいコードを結合
      onCodesChange && onCodesChange(updatedCodes); // コードが変更された場合にコールバック関数を呼ぶ
      return updatedCodes;
    });
  };

  // 入力を確定する関数(フォーカスが外れたときやEnterキーが押されたときに実行)
  const handleInputConfirm = () => {
    if (inputValue.trim() && isValidCode(inputValue.trim())) { // 入力が空でなく、かつ有効なコードの場合
      addCodes([inputValue.trim()]); // コードを追加
      setInputValue(''); // 入力フィールドをクリア
    }
  };

  // 入力ボックスの値が変更されたときの処理
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setInputValue(e.target.value); // 入力値を状態に設定
  };

  // Enterキーが押されたときにコードを確定する処理
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      handleInputConfirm(); // 入力を確定
      e.preventDefault(); // Enterキーのデフォルト動作を防止
    }
  };

  // 貼り付けが行われたときに複数のコードを一括追加する処理
  const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {
    e.preventDefault(); // 貼り付けのデフォルト動作を防止
    const pasteData = e.clipboardData.getData('text'); // 貼り付けられたテキストデータを取得
    const newCodes = pasteData.split(/(\r\n)+/).flatMap((x) => x.split(/[\t\n]+/)); // 複数のコードに分割
    addCodes(newCodes); // 新しいコードを追加
  };

  // 指定されたインデックスのコードを削除する処理
  const handleRemoveCode = (index: number) => {
    setCodes((prevCodes) => {
      const updatedCodes = prevCodes.filter((_, i) => index !== i); 
      onCodesChange && onCodesChange(updatedCodes); 
      return updatedCodes;
    });
  };

  // 初期表示時の処理
  useEffect(() => {
    setCodes(initialCodes);
  }, [initialCodes]);

  return (
    <div>
      <div style={{ display: "flex", alignItems: "center", flexWrap: "wrap", gap: '8px' }}>
        {codes.map((code, index) => (
          <div
            key={index}
            style={{
              display: 'inline-flex',
              alignItems: 'center',
              background: '#e0e0e0',
              borderRadius: '16px',
              padding: '4px 12px',
            }}
          >
            <span>{code}</span>
            <button
              type='button'
              onClick={() => handleRemoveCode(index)} // コードを削除
              style={{ marginLeft: '4px', background: 'transparent', border: 'none', cursor: 'pointer' }}
            >
              &times; {/* ×ボタン */}
            </button>
          </div>
        ))}
        <input
          type='text'
          value={inputValue}
          onChange={handleChange} // 入力値が変更されたときに呼ばれる
          onBlur={handleInputConfirm} // フォーカスが外れたときに入力を確定
          onKeyDown={handleKeyDown} // Enterキーが押されたときに入力を確定
          onPaste={handlePaste} // 複数のコードを貼り付けるときに呼ばれる
          style={{ width: '5rem', padding: "0.25rem" }}
        />
      </div>
    </div>
  );
};

export default MultiCodeInput;

このコンポーネントは、以下の機能を実装しています:

  1. コード追加の自動化: コードを入力してEnterキーを押すと、新たなコードを追加できます。
  2. コード削除: 各コードの横にある「×」ボタンで簡単に削除できます。
  3. 複数のコードを一括貼り付け: Excelなどから複数のコードをコピーし、入力欄に貼り付けると、一度に複数のコードが追加されます。

使用方法

上記で作成したMultiCodeInputコンポーネントの使用例です。
useStateで入力された複数コードの値を保持する配列を宣言し、MultiCodeInputにパラメータとして渡します。

import React, { useState } from 'react';
import MultiCodeInput from './MultiCodeInput'; // MultiCodeInputコンポーネントをインポート

const App = () => {
  const [codes, setCodes] = useState<string[]>([]); // 入力されたコードを保存する状態

  // コードが変更されたときに状態を更新する関数
  const handleCodesChange = (newCodes: string[]) => {
    setCodes(newCodes);
  };

  return (
    <div style={{ padding: '20px' }}>
      <h1>コード入力サンプル</h1>
      
      {/* MultiCodeInputコンポーネントを使用 */}
      <MultiCodeInput initialCodes={['123', '456']} onCodesChange={handleCodesChange} />

      {/* 現在のコードのリストを表示 */}
      <h2>入力されたコード:</h2>
      <ul>
        {codes.map((code, index) => (
          <li key={index}>{code}</li>
        ))}
      </ul>
    </div>
  );
};

export default App;

まとめ

複数のコードを入力するUIの改善案について解説してきました。
日々、多くのを入力作業が発生する業務システムでは、ちょっとしたUI改善が業務効率改善につながあります。

スポンサーリンク
スポンサーリンク

このブログを検索

Profile

自分の写真
Webアプリエンジニア。 日々新しい技術を追い求めてブログでアウトプットしています。
プロフィール画像は、猫村ゆゆこ様に書いてもらいました。

仕事募集もしていたり、していなかったり。

QooQ