Реагировать на позицию ввода в цифровом формате - PullRequest
0 голосов
/ 27 апреля 2018

Я использую цифры для форматирования чисел от 4500000 до 4 500 000. Проблема возникает с позицией курсора - она ​​ошибается при изменении количества пробелов. Я пытался сохранить положение курсора при изменении ввода, но с ним что-то не так.

import React from "react";
import { render } from "react-dom";
import numeral from "numeral";

class App extends React.Component {
    pricePosition = 0;
    priceInput = React.createRef();

    constructor(props) {
        super(props);

        numeral.localeData().delimiters.thousands = " ";

        this.state = {
            price: 4500000 // comes from props
        };
    }

    componentDidUpdate() {
        this.priceInput.current.selectionStart = 
        this.priceInput.current.selectionEnd = this.pricePosition; //tried like this
    }

    handleInputChange = field => ev => {
        this[`${field}Position`] = Number(ev.target.selectionEnd);
        this.setState({
            [field]: Number(ev.target.value.replace(/\D/g, ""))
        });
    };

    render() {
        return (
            <div>
                Price here:
                    <input
                        ref={this.priceInput}
                        value={numeral(this.state.price).format("0,0")}
                        onChange={this.handleInputChange("price")}
                    />
            </div>
        );
    }
}

render(<App />, document.getElementById("root"));

Также вы можете проверить это: codesandbox

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Я получил такое хакерское решение:

import React from "react";
import { render } from "react-dom";
import numeral from "numeral";

class App extends React.Component {
  constructor(props) {
    super(props);

    numeral.localeData().delimiters.thousands = " ";

    this.state = {
      inFocus: false,
      price: 4500000 // comes from props
    };
  }

  changeFocus = () => {
    this.setState(prevState => ({
      inFocus: !prevState.inFocus
    }));
  };

  handleInputChange = field => ev => {
    this.setState({
      [field]: Number(ev.target.value.replace(/\D/g, ""))
    });
  };

  render() {
    const { price, inFocus } = this.state;
    return (
      <div>
        Price here:
        <input
          value={inFocus ? price : numeral(price).format("0,0")}
          onFocus={this.changeFocus}
          onBlur={this.changeFocus}
          onChange={this.handleInputChange("price")}
        />
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

Когда ввод находится в фокусе, мы используем неформатированное значение.

codesandbox

0 голосов
/ 27 апреля 2018

Вы должны переписать componentDidUpdate, как показано ниже, чтобы заставить его работать (безобразно):

    componentDidUpdate() {
        this.priceInput.current.selectionEnd = this.pricePosition + 1; //tried like this
    }

Дело в том, что вы форматируете только значение, отображаемое на экране, а не само состояние, поэтому курсор не соответствует фактической длине.

Я предлагаю вам переписать свой код, как показано ниже:

import React from "react";
import { render } from "react-dom";
import numeral from "numeral";

class App extends React.Component {
    priceInput = React.createRef();

    constructor(props) {
        super(props);

        numeral.localeData().delimiters.thousands = " ";

        this.state = {
            price: 4500000 // comes from props
        };
    }

    handleInputChange = field => ev => {
        const formattedValue = numeral(ev.target.value).format("0,0");
        this[`${field}Position`] = Number(formattedValue.length);
        this.setState({
            [field]: Number(ev.target.value.replace(/\D/g, ""))
        });
    };

    render() {
        return (
            <div>
                Price here:
                    <input
                        ref={this.priceInput}
                        value={numeral(this.state.price).format("0,0")}
                        onChange={this.handleInputChange("price")}
                    />
            </div>
        );
    }
}

render(<App />, document.getElementById("root"));

Теперь вы можете избавиться от переменной position.

Надеюсь, это поможет;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...