-1

I have a text input and I am trying to restrict it based on the lang attribute. If the lang is set to fr I want to only allow numbers and a single comma in the input and if it's set to en I want to only allow numbers and a single period in the input. I've got it working for fr so far, so I'm basically just wondering what the replace pattern would be for en.

function formatNum(lang, $this, val) {
  let pattern = '';
  if (lang === 'fr') {
    // allow only numbers and a single comma
    pattern = $this.val().replace(/[^0-9,]/g, '').replace(/(,.*?),(.*,)?/, '$1');
  } else {
    // allow only numbers and a single period
  }
  if (pattern !== $this.val()) $this.val(pattern);
}

$(function() {
  $('input').keyup(function() {
      let $this = $(this),
          lang = $this.parent().attr('lang'),
          val = $this.val();
          
      formatNum(lang, $this, val);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div lang="fr">
  <h3>French</h3>
  <input type="text" />
</div>
<div lang="en">
  <h3>English</h3>
  <input type="text" />
</div>
user13286
  • 3,027
  • 9
  • 45
  • 100

1 Answers1

1

I admit this is likely not a direct answer - parsing a number with internationalization is "hard" in JavaScript and doing this on a keyup event to an input is likely a challenge, breaking as the format gets injected. There ARE ways but...

I suggest you parse it as you enter it and put the text of the format (using standard local string method) in another element and replace the text after the change event fires.

Forgive me refactoring your function but it was doing multiple things which breaks the S in SOLID principles so I just returned the formatted number and used it.

I also added an example of a data attribute which might be more standardized than the "lang" attribute.

Other "ways" would be to store the formatted string in a data attribute (instead of the span) and work from that - the challenge is to "show" yet "parse" - and creating a parsing function for every language (or even a few) is going to be a challenge in my opinion.

function formatNum(lang, val) {
  let number = parseFloat(val);
  let formattedNumber = number.toLocaleString(lang)

  return formattedNumber;
}

$(function() {
  $('.number-input').on('keyup', function() {
    let $this = $(this),
      lang = $this.parent().attr('lang'),
      val = $this.val();
    lang == "" ? lang : $this.data("language");
    let formatted = formatNum(lang, val);
    $this.next(".output-of-entry").html(formatted);
  }).on('change', function() {
    $(this).val($(this).next(".output-of-entry").text());
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div lang="fr-FR">
  <h3>French</h3>
  <input class="number-input" type="text" />
  <span class="output-of-entry"></span>
</div>
<div lang="en-US">
  <h3>English</h3>
  <input class="number-input" type="text" />
  <span class="output-of-entry"></span>
</div>
<div>
  <h3>English using data</h3>
  <input data-language="en-US" class="number-input" type="text" />
  <span class="output-of-entry"></span>
</div>
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
  • 1
    Pattern matching: https://stackoverflow.com/q/59389919/125981 This gives some "unformatting" examples to gather the strings if you need incorporate that (I left this out rather than vote to close your question as a duplicate: https://stackoverflow.com/q/29255843/125981) – Mark Schultheiss Feb 03 '22 at 23:06
  • 1
    Also, you can dig into the details of the lang tags https://datatracker.ietf.org/doc/html/rfc5646 – Mark Schultheiss Feb 03 '22 at 23:13