简体   繁体   English

JavaScript正则表达式:当输入字段onChange事件触发时,格式化字段

[英]JavaScript Regex: When input field onChange event fires, format fields

I am using react 16.8.2 new hooks API. 我正在使用React 16.8.2新的钩子API。 -Just for info- -仅供参考-

My problem only involves JS. 我的问题只涉及JS。

I have two input fields. 我有两个输入字段。 They take only numbers as inputs. 他们仅将数字作为输入。 If the user enters /\\D+/ (non-digits), the field is set to ''(empty). 如果用户输入/\\D+/ (非数字),则该字段将设置为“(空)”。 If he enters 2.3393 , the number should always be rounded to two decimal places 2.34 如果他输入2.3393 ,则该数字应始终四舍五入到两位小数2.34

Field1 : onChange formats the number to $ 32,233,233,322.24 Field1onChange将数字格式化为$ 32,233,233,322.24

Field2 : onChange formats the number to 99% . Field2onChange将数字格式化为99% Decimals places are simply truncated. 小数位会被截断。

The Input field should be able to handle e.nativeEvent.inputType deleteContentBackward as well. Input字段也应该能够处理e.nativeEvent.inputType deleteContentBackward Such that if the user is at $ 2 and deletes 2 , Field1 becomes empty. 这样,如果用户的价格为$ 2并删除2 ,则Field1变为空。 Similarly for Field2. 对于Field2同样。 1% on deleting % becomes empty. 删除%时有1%变为空。

So far I have this: 到目前为止我有这个:

const handleInputChange = function (e) {
     const val = e.target.value;
     const formatValue = function () {
        if (/.*\d?\.\d*/.test(val)) return val.replace(/(?<=\d?\.\d*)\..*/g, '');
        return +val.replace(/\$\s?|(,+)|%/g, '');
      };  

      if (formatValue()) {
        if (fieldSuffix === 'Percentage') {
          if (e.nativeEvent.inputType === 'deleteContentBackward') return setVal(`${formatValue()}%`.replace(/^\d%$|\d(?=%)/, ''));
          return setVal(`${formatValue()}%`);
        }   
        if (fieldSuffix === 'Dollars') return setVal(`$ ${formatValue()}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','));
        return setVal(formatValue());
      }   
      return setVal('');
 };

return (
    <input
        value={val}
        onChange={handleInputChange}
    /> 
)

It does not work well for when user enters single . 当用户输入single时,它不能很好地工作. . $ are prepend for every . $是每一个的前缀. keystroke. 按键。 The case that when user enters /\\D+/ is not handled. 用户输入/\\D+/情况不予处理。 % Field2 decimal place truncation case is also not handled. % Field2小数位截断大小写情况也未处理。 I can think of other cases also that are not handled. 我还可以想到其他未处理的案件。

My code is getting complicated. 我的代码越来越复杂。 This approach is not elegant. 这种方法并不优雅。 Please Help. 请帮忙。

The following code works well. 以下代码运行良好。

const handleInputChange = function (e) {
      const formatValue = function () {
        // Remove non-digit, except '.' and remove everything beginning from second decimal '.'
        return e.target.value.replace(/[^0-9.]|(?<=^[^.]*\.[^.]*)\..*/g, '');
      };

      if (formatValue()) {
        if (fieldSuffix === 'Percentage') {
          // Percentage decimal truncated
          const truncatedPercentage = formatValue().replace(/\..*/, '');
          if (e.nativeEvent.inputType === 'deleteContentBackward') return setVal(`${formatValue()}%`.replace(/^\d%$|(\d|\.)(?=%)/, ''));
          return setVal(`${truncatedPercentage}%`);
        } 
        if (fieldSuffix === 'Dollars') {
          // Truncated to two decimal places, not rounded
          const truncatedDollar = formatValue().replace(/(?<=\.\d{2}).*/, '');
          // Format and insert ','
          return setVal(`$ ${truncatedDollar}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','));
        } 
      } 
      return setVal('');
};

I still feel that there is a lot of redundancy and unhandled cases in this code 我仍然觉得这段代码中有很多冗余和未处理的情况

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM