3

I've run into an issue with a jQuery script I made for formatting the input of currency to proper 2 decimal places and a comma for 1,000's. It works perfectly in chrome, but when I tested in Edge the console log showed an error for "unexpected quantifier", and in firefox, the console shows error for "invalid regex group".

Here is the line that is throwing the error:

return value.replace(/(?!\.)\D/g, "").replace(/(?<=\..*)\./g, "").replace(/(?<=\.\d\d).*/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, ",");

This is the full function:

$('#sg-amount').on('change click keyup input paste',(function (event) {
    $(this).val(function (index, value) {
        return value.replace(/(?!\.)\D/g, "").replace(/(?<=\..*)\./g, "").replace(/(?<=\.\d\d).*/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    });
  }));

EDIT

This question is different than others as it does a few things:
1. It adds commas 2. Allows decimals 3. Limits the decimal place to 2 digits. 4. Does it all on Keyup

The other solutions I have found on stackoverflow do not do ALL of those things. I want to continue using jQuery and do not want to use Javascript. I like the simplicity of this code and don't want 500 lines of code to make it work.

It works perfectly in chrome, but does not work in Edge, or Firefox. I haven't tried any other browsers yet.

EDIT 2

Based on comments below, maybe this will help me more. Here is what I am wanting to accomplish with each replace:

.replace(/(?!\.)\D/g, "") deletes all non numeric characters except .

.replace(/(?<=\..*)\./g, "") removes all extra . except the first .

.replace(/(?<=\.\d\d).*/g, "") deletes everything after 2 decimal places

.replace(/\B(?=(\d{3})+(?!\d))/g, ",") inserts commas at appropriate places

Since some of these calls are causing errors in certain browsers, is there a better string to use in each replace that is cross browser friendly?

Here is a fiddle

RiotAct
  • 743
  • 9
  • 33
  • Possible duplicate of [How can I format numbers as dollars currency string in JavaScript?](https://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-dollars-currency-string-in-javascript) – JasonB Sep 25 '18 at 03:00
  • Its not because I'm using a different method. – RiotAct Sep 25 '18 at 03:55
  • 1
    But when you say "I admit I found this formatting code online, and have no clue about properly formatting numbers this way" and you are trying to do something ( format a value as currency ) about which there is already a popular answered question, I read this as your real question is how to format the currency and you could just update your broken found code to use a more widely accepted method. – JasonB Sep 25 '18 at 04:12
  • Include a link to the source of this code for context, and some html so we can create a runnable snippet that reproduces your errors in those browsers and I'll gladly retract my vote and try to troubleshoot with you. – JasonB Sep 25 '18 at 04:13
  • all i need to know is why the return value line is causing an error in certain browsers. It works in chrome. If you don't know, please go away and let someone who does answer – RiotAct Sep 25 '18 at 04:27
  • I believe the quantifier in question is this part: `(\d{3})` **`+`** I don't think you need more then one lookahead nor do I believe lookahead groups are quantifable. – zer00ne Sep 25 '18 at 04:54
  • Lookbehind groups: `(?<=` are not universally supported in JavaScript yet, it seems Chrome is outpacing Firefox again. – zer00ne Sep 25 '18 at 05:06

1 Answers1

3

Ok so thanks to @zer00ne and his comments I learned a bit today. First, ES2018: RegExp lookbehind assertions have been implemented in Chrome and are currently underway with Edge and Firefox, but are not yet supported. So I did some digging and found that for example, the expression ?<= was throwing an error and I was able to replace it with ?:

The other expression I couldn't get to work after the change was .replace(/(?<=\.\d\d).*/g, "") to delete everything after 2 decimal places. So I swapped it out with this expressesion: .replace(/\.(\d\d)\d?$/, '.$1') and that did the trick!

So altogether here is the fix!

$('#sg-amount').on('change click keyup input paste',(function (event) {
  $(this).val(function (index, value) {
    return value.replace(/(?!\.)\D/g, "").replace(/(?:\..*)\./g, "").replace(/\.(\d\d)\d?$/, '.$1').replace(/\B(?=(\d{3})+(?!\d))/g, ",");
   });
 }));

I have updated my fiddle to reflect the changes.
Fiddle

RiotAct
  • 743
  • 9
  • 33