@PavelMelnik94

Как подменить тип и велью в нужный момент?

добрый вечер.

нужна помощь с компонентом инпута.
что есть на данный момент
1) есть инпут. по дефолту в пропсе type стоит number. в онченже велью прогоняется через регулярку, которая отсекает знаки, и на выходе не вводится ничего кроме целых чисел.
2) пропс с максимально допустимым числом.
3) есть псевдо кнопки + - которые добавляют\уменшают велью на какое-то n-число.
4) если число большое, вида 1000000, то на onBlur велью конвертируется в стрингу, подставляются запятые и велью становится 1,000,000. на OnFocus, соотвественно, он опять number, и запятые пропадают.

собственно задача - при кликах на + - я попадаю в онблюр и не могу сделать декремент\инкремент потому что он в этот момент стринга.
единстенное до чего додумался, это переключение в фокус и нулевой таймаут на блюр, но это не сработало.

const Input = ({
  onChange,
  disabled,
  numStep = 1,
  min = 0,
  max,
  value,
  placeholder,
  className,
  type = 'number',
  onBlur,
  onFocus,


  isPriceInput
}) => {

  // STATES
  const [isFocused, setIsFocused] = useState(false);
  const [isEditing, setEditing] = useState(false);


  // HANDLES
  const handle = {
    change: (e) => {
      let inputValue = e.target ? onlyNumbers(e.target.value) : e;
      if (inputValue !== '') {
        // inputValue = inputValue.toString().replace(/\D/g, '');
        inputValue = parseFloat(inputValue) || '';
        if (min && +min > +inputValue) {
          inputValue = +min;
        } else if (max && +max < +inputValue) inputValue = +max;
      } 

      onChange(inputValue.toString());
    },
    toggleEdit: () => {
      setEditing(!isEditing);
      onChange('');
    },
    focus: (e) => {
      setIsFocused(true);
      if (isPriceInput) onChange(removeComma(value));

      if (onFocus) onFocus(e);
    },
    blur: (e) => {
        setIsFocused(false);
        setEditing(false);

        if (isPriceInput) onChange(addCommas(value));


      if (onBlur) onBlur(e);
    },

    decrement: () => {
 
      handle.change(+value - +numStep);
    },
    increment: () => {

      handle.change(+value + +numStep);
    }
  };

  useEffect(() => {
    if (isEditing || isFocused) inputRef.current.focus();
  }, [isEditing, isFocused]);

  const uniProps = {
    className: `input ${className}`,
    placeholder,
    value: value || '',
    disabled,
    onChange: handle.change,
    onFocus: handle.focus,
    onBlur: handle.blur,
    onKeyUp: handle.keyUp,
    min,
    max,
    ...(maskChar ? { maskChar } : {}),
    ...(formatChars ? { formatChars } : {})
  };

  return (
    <div className='input__wrap'>
      <input {...uniProps} ref={inputRef} type={type} />

      <div className='input__nums'>
        <button
          onClick={() => handle.decrement()}
          className={cn(`input__num-btn`, { disabled: value <= min })}
        >
          <Minus />
        </button>
        <button
          onClick={() => handle.increment()}
          className={cn(`input__num-btn`, { disabled: value >= max })}
        >
          <Plus />
        </button>
      </div>
    </div>
  );

 

export default Input;


addCommas: (value) => {
      value = value.toString();
      const isFraction = value.includes('.');

      const valueBeforeDot = isFraction
        ? value.slice(0, value.indexOf('.'))
        : value;

      const intPart = valueBeforeDot
        .split('')
        .reverse()
        .reduce(
          (acc, item, idx) =>
            idx % 3 === 0 && idx !== 0 ? [...acc, ',', item] : [...acc, item],
          []
        )
        .reverse()
        .join('');

      return isFraction ? intPart + value.slice(value.indexOf('.')) : intPart;
    },
    removeComma: (value) => {
      return parseFloat(value.replace(/\,/g, ''));
    }
  },
  onlyNumbers: (value, isDot = false) => {
    const val =
      value.slice(0, 1) !== '0' && value.slice(0, 1) !== '.'
        ? value
        : value.slice(1);
    if (isDot) return twoDigitAfterDot(val.replace(/[^0-9.]/g, ''));
    else return +val.toString().replace(/\D/g, '');
  },
  • Вопрос задан
  • 50 просмотров
Пригласить эксперта
Ответы на вопрос 1
Alexandroppolus
@Alexandroppolus
кодир
Внутри increment и decrement используй removeComma, если там строка.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы