0

I have a requirement to show numbers in text boxes with comma-separator formatting for thousands. Each text box is like this:

 <asp:TextBox ID="txtNumber" MaxLength="16" runat="server" onfocus="unFormatTextBox(this);" onblur="formatTextBox(this);" />

When the page is drawn, the number is formatted server-side, so that 1000.50 will become 1,000.50 and this is set as the text box value.

When the user clicks into the text box - for ease of editing - the commas are removed.

function unFormatTextBox(elementId) {

    // removes commas on focus

    var num = elementId.value;
    elementId.value = num.replaceAll(',', '');

}

When the user clicks elsewhere and the text box loses focus, the entry is reformatted and the commas are reinserted..

function formatTextBox(elementId) {

    // add commas on mouseout
    var num = elementId.value;

    var parts = num.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    elementId.value = parts.join(".");

}

This works perfectly. However it's conflicting with the RegularExpressionValidator..

<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="txtNumber" ErrorMessage="" ValidationExpression="^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]+)?$">*</asp:RegularExpressionValidator>

So the user keys:

1500

When the text box loses focus, e.g. they click to the next one, that gets reformatted as:

1,500

The problem: The Validator then fires and shows the entry as incorrect even though it ought to be fine. The Validator should allow that entry with the comma (I'm then removing that server-side before dealing with the submitted value).

However if the user then clicks Submit, which you'd imagine would not work as a field is highlighted as invalid - actually, it does work and the page submits.

Can anyone help to explain why this is happening and how to stop it? Thanks very much.

Mark852
  • 33
  • 5
  • Just to clarify one point: User keys 1,500 - validator fires and indicates incorrect value. Even so: the form will still submit. User keys ABCD - validator fires and form will *not* submit. Behaviour of validator is correct in this regard. The problem is the on-screen highlighting of the field when it is actually valid. – Mark852 Dec 02 '20 at 08:33

2 Answers2

0

How about checking on keyup event and updating the format while it is typed?

    $('input.number').keyup(function(event) {
      // skip arrow keys
      if(event.which >= 37 && event.which <= 40) return;
    
      // format number
      $(this).val(function(index, value) {
        return value
        .replace(/\D/g, "")
        .replace(/\B(?=(\d{3})+(?!\d))/g, ",")
        ;
      });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<input class="number" id="id_" name="id_" type="text">

Ref: https://stackoverflow.com/a/2632502/8291949

wp78de
  • 18,207
  • 7
  • 43
  • 71
  • Thanks. That would work, I'm sure. However I'm required to exactly mirror the behaviour of another application and that only reformats the field when it loses focus. This is because - I think - the comma being present gets in the way of easily editing the value, so it needs removing when being edited and restoring only after the user has completed their edit and moves to another field. – Mark852 Dec 02 '20 at 08:31
  • Hm, if the behavior cannot be changed, and the event order stays the same, then it's going to be difficult to improve. You could weaken the regex validator by making the `,?` optional but that basically renders the check useles. – wp78de Dec 02 '20 at 15:05
0

The solution to this was to change the RegExp:

<asp:RegularExpressionValidator ID="RegularExpressionValidator8" runat="server" ControlToValidate="txtProductQuantity" ErrorMessage="*" CssClass="fvError" Display="Dynamic" ValidationExpression="^(?:[0-9]+(?:[.,][0-9]+)?|[1-9][0-9]{0,2}(?:(?:\.[0-9]{3})*|(?:,[0-9]{3})*)(?:\.[0-9]+)?)$">*</asp:RegularExpressionValidator>
Mark852
  • 33
  • 5