2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【React】フォーカスアウトするとカンマ区切りで表示される入力欄

Posted at

経緯

  • 数値を入力する項目がある
  • 桁が大きくなると額がわからなくなる
  • だからカンマ区切りで表示したい
  • それを実現可能な要素はHTMLには無い
    • input=text だと数値以外を入力できる
    • input=number だとカンマを表示できない
  • じゃあ作ろう

仕様

  • input=textをベースとする
  • 入力値は右寄せで表示する
  • バリデーション機能を追加する
    • 正の数、および負の数を入力可とする
    • マイナスは先頭のみ入力可とする
    • 小数点は一度のみ入力可とする
    • 小数点の前には必ず数値の入力があるものとする
    • 末尾が小数点で終わる場合を許容する
  • 未入力、及びバリデーション通過時の背景色を #FFF とする
  • バリデーション不通過時の背景色を #FFBEDA とする
  • 入力欄にフォーカス時に入力した文字列をそのまま表示する
  • 入力欄からフォーカスアウト時にバリデーションを通過した場合はカンマ区切りの文字列を表示する
  • 入力欄からフォーカスアウト時にバリデーションが不通過となる場合は入力した文字列をそのまま表示する
import React, { useState } from 'react';

const InputText = ({ ...rest }) => {
  const [value, setValue] = useState('');
  const [isFocus, setFocus] = useState(false);
  const handleFocus = () => setFocus(true);
  const handleBlur = () => setFocus(false);
  const handleChange = e => setValue(e.target.value);
  const isBlank = value === '';
  const isValid = /^[-]?(\d+)[.]?(\d+)?$/.test(value);
  const displayValue = (() => {
    if (isFocus || !isValid) {
      return value;
    }
    if (isValid) {
      return (+value).toLocaleString();
    }
    return '';
  })();
  const displayStyle = {
    textAlign: 'right',
    backgroundColor: isValid || isBlank ? '#FFF' : '#FFBEDA'
  }

  return (
    <input
      {...rest}
      type="text"
      onFocus={handleFocus}
      onBlur={handleBlur}
      onChange={handleChange}
      value={displayValue}
      style={displayStyle}
    />
  );
}

export default InputText;
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?