Логическая ошибка при проверке чисел вместе с символом процента в React Js

В моем проекте у меня есть поле с именем Ставка, которое может принимать эти значения: Например:

  • 2.32
  • 2,32%

Условия:

  • Разрешены только числа.
  • Только две цифры после десятичной точки.
  • Использование букв и других символов запрещено.

Это фрагмент кода, который я использую

handleCheck = (e)=> {
    let onlyNums = e.target.value.replace(/[^0-9\.,%]/g, ''); 
    var str = '';
    var isperc = false;    
    if (onlyNums.indexOf('.') !== -1)
    {     
      var arr = onlyNums.split(".");
      if (arr[1].length >2)
      {
        if ( arr[1].indexOf('%') !== -1)
          isperc = true;
        arr[1] = arr[1].slice(0, 2);
      }
      if (isperc)
        e.target.value = arr[0] + '.' + arr[1] + '%';
      else
        e.target.value = arr[0] + '.' + arr[1];
    }
    if (onlyNums.indexOf('%') !== -1)
    {
      str = onlyNums.indexOf('%');
      var start = (str + 1);     
      onlyNums = e.target.value.slice(0, start);
      e.target.value=onlyNums;
    }

  }

Логическая ошибка при проверке чисел вместе с символом процента в React Js

На картинке выше показана проблема. Поле Ставка принимает буквы также до десятичной точки.

как мне изменить свой код, чтобы избежать этой проблемы? Или Как я могу преобразовать регулярное выражение \d+(\.\d\d)?%?, подобное тому, которое я использовал в функции заменять в вопросе, потому что это регулярное выражение не работает с моим кодом

Не могли бы вы просто использовать регулярное выражение для всего теста? Как например \d+(\.\d\d)?%?? (regex101.com/r/vTkgMH/2)

Telokis 27.11.2018 12:03

@Bhojendra Rauniyar Я изменил свой код вот так let onlyNums = e.target.value.replace(/\d+(\.\d\d)?%?/g, ''); e.target.value = onlyNums Он работает не так, как ожидалось. Связана ли проблема с тем, как я использовал регулярное выражение внутри функции замены. Если да, то каков правильный синтаксис?

Jane Fred 27.11.2018 12:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
727
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я немного изменил регулярное выражение и добавил parseFloat() поверх. Также вызывается для изменения значения ввода сразу после первого вызова замены. Это может быть то, что вы в первую очередь упустили.

class Input extends React.Component {
  
  handleCheck = (e)=> {
    let onlyNums = e.target.value.replace(/[^.%\d]?(\.\%)/g, ''); 
    e.target.value = isNaN(parseFloat(onlyNums))?'':parseFloat(onlyNums);

    var str = '';
    var isperc = false;    
    if (onlyNums.indexOf('.') !== -1)
    {     
      var arr = onlyNums.split(".");
      if (arr[1].length >2)
      {
        if ( arr[1].indexOf('%') !== -1)
          isperc = true;
        arr[1] = arr[1].slice(0, 2);
      }
      if (isperc)
        e.target.value = arr[0] + '.' + arr[1] + '%';
      else
        e.target.value = arr[0] + '.' + arr[1];
    }
    if (onlyNums.indexOf('%') !== -1)
    {
      str = onlyNums.indexOf('%');
      var start = (str + 1);     
      onlyNums = e.target.value.slice(0, start);
      e.target.value=onlyNums;
    }

  }

  render() {
    return (
      <input onChange = {this.handleCheck} />
    );
  }
}

ReactDOM.render(
  <Input />,
  document.getElementById('root')
);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id = "root">

</div>

РЕДАКТИРОВАТЬ (более подход регулярное выражение):

class Input extends React.Component {
    constructor(props) {
        super(props);
        this.input_prev_value = ''; //property for storing previous input value
    }

    handleCheck = (e)=> {
        let input_value = e.target.value.replace(/(\.\%)/,'');  //takes care of '.%' case

        if ((input_value.search(/^[0]{1,}[\d]/)!==-1 || // takes care of leading zeroes
            input_value.search(/^(\d+)([\.])?([\d]{1,2})?([\%])?$/)===-1) &&  //main pattern
            input_value!=='')
            e.target.value  = this.input_prev_value;
        else {
            e.target.value = input_value;
            this.input_prev_value = e.target.value;
        }

    }

    render() {
        return (
            <input onChange = {this.handleCheck} />
        );
    }
}

ReactDOM.render(
    <Input />,
        document.getElementById('root')
);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id = "root"></div>

Другие вопросы по теме