julian
julian

Reputation: 47

Check for length, then check that value is only numeric-JavaScript

I am attempting to do field validation on 3 textboxes (phone number). Ideally, I only want to validate in case any of the three boxes contain a value. Otherwise, no errors should be generated. Additionally, in the case that any values are placed in the textboxes I want to make sure these are only numeric.

The scenarios go as followed...

1.user enters nothing into any of the boxes: nothing happens
2.user enters "12" into box #1, "222" into box #2, and "4444" into box #3: this results in an incomplete number. Validate.
3.user enters a value of valid length. EX: "11j" "222" "1222": this isn't a valid value, as it contains a letter. Validate.

my current solution works somewhat. Except that it does not allow user to leave any of the fields blank (scenario 1 is not valid). How can i fix this?

Validation:

$("#editArea,#editPrefix,#editSuffix").blur(function () {
        var regex = /^[0-9]+$/;
        var phone = $("#editArea").val() + $("#editSuffix").val() + $("#editPrefix").val();
        var area=$("#editArea").val();
        var suffix=$("#editSuffix").val();
        var prefix=$("#editPrefix").val();
        if (phone.length > 0 && phone.length < 10||!regex.test(area)==true||!regex.test(suffix)==true||!regex.test(prefix)==true) {
            $("#editPhoneError").html('<font color="#cc0000">The number must be a numeric 10 digit value </font>');
            $("#editArea").addClass("validation");
            $("#editPrefix").addClass("validation");
            $("#editSuffix").addClass("validation");
        }
        else {
            $("#editPhoneError").html('<font color="#cc0000"></font>');
            $("#editArea").removeClass("validation");
            $("#editPrefix").removeClass("validation");
            $("#editSuffix").removeClass("validation");
        }
        $("#btnSave").prop("disabled", ($(":input.validation").length > 0));
    });   
}

Markup:

 <div>
 <input id="editArea" maxlength="3" onkeyup="tabout(this,'editPrefix')" name="editArea" style="float:left; width:70px;" type="text" value="@Model.Pharmacy.Area" depends />
 </div>
 <div>
 <input id="editPrefix" maxlength="3" onkeyup="tabout(this,'editSuffix')" name="editPrefix" style="float:left; width:70px;" type="text" value="@Model.Pharmacy.Prefix" depends />
  </div>
  <div>
  <input id="editSuffix" maxlength="4" onkeyup="tabout(this,'editPrefix')" name="editSuffix" style="float:left; width:70px;" type="text" value="@Model.Pharmacy.Suffix" depends />
  </div>
  <span style="margin-left:-208px; margin-top:50px;" id="editPhoneError" value="0"></span>
  </div>

Upvotes: 0

Views: 1864

Answers (3)

trincot
trincot

Reputation: 350034

Just replace this:

if (phone.length > 0 && phone.length < 10||!regex.test(area)==true
       ||!regex.test(suffix)==true||!regex.test(prefix)==true) {

with:

if (area.length > 0 && suffix.length > 0 && prefix.length > 0 &&
       (phone.length < 10 || !regex.test(phone)) {

Note that the || part needs these additional parentheses, as otherwise the preceding && operators take precedence.

Also, note the simplification of the regex test, which you can just apply to phone instead of the individual parts.

Other ideas for improvement

You actually don't have to check the whole phone number, it suffices to only check the current input value (against the maxlength property), and leave the presence of the validation class on the other input fields unaltered. On the other hand, you should validate all three fields when the page loads, which you can do with trigger().

It is better to avoid HTML manipulation when possible, and in that respect you could include the error message in the original HTML, and just hide/show it.

The opposite test for numericals is easier: /\D/ tests for the presence of any non-digit character.

It is more standard to handle the change event, instead of the blur event.

Here is a snippet that incorporates those ideas:

$(function () {
  $('input.phone').change(function() {
    var v = $(this).val();
    // Only check current input:
    var err = v.length > 0 && (v.length < +$(this).attr('maxlength') || /\D/.test(v));
    // ...and only set the validation class on/off for current input
    $(this).toggleClass("validation", err);
    // Count if any has this class, so to show the message and disable the button
    err = $(".validation").length > 0;
    // Leave the message in place, just hide/show it
    $('#editPhoneError').toggleClass('show', err);
    $("#btnSave").prop("disabled", err);
  }).trigger('change'); // trigger at page load
});
.phone { width:70px; }
.error { color: #c00; visibility: hidden }
.validation { border: 3px solid #e00 }
.show { visibility: visible }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input maxlength="3" class="phone" name="editArea" type="text" value="" depends />
<input maxlength="3" class="phone" name="editPrefix" type="text" value="" depends />
<input maxlength="4" class="phone" name="editSuffix" type="text" value="" depends />
<div id="editPhoneError" class="error">The number must be a numeric 10 digit value</div>
<button id="btnSave">Save</button>

Upvotes: 2

johnniebenson
johnniebenson

Reputation: 540

You should consider using class instead of id to make this form more scalable. I've simplified your jQuery a bit and this seems to work well:

https://jsfiddle.net/rh19hfyu/

HTML

<div>
  <input class="phone" id="editArea" maxlength="3" onkeyup="tabout(this,'editPrefix')" name="editArea" type="text" />
</div>

<div>
 <input class="phone" id="editPrefix" maxlength="3" onkeyup="tabout(this,'editSuffix')" name="editPrefix" type="text" />
</div>

<div>
 <input class="phone" id="editSuffix" maxlength="4" onkeyup="tabout(this,'editPrefix')" name="editSuffix" type="text" />
</div>

 <span style="color:#cc0000; display:none;" id="editPhoneError" value="0">The number must be a numeric 10 digit value</span>

JS

  $(function() {

    $(".phone").on("blur", function () {
      var regex = /^[0-9]+$/,
          error = $("#editPhoneError"),
          phone = "";

      $(".phone").each(function() {
        phone = phone + $(this).val();
      });

      if (phone.length > 0) {
        //validate
        if(!regex.test(phone)) {
            error.show();
        }
        else {
            error.hide();
        }
      }
    });   

  });

Upvotes: 0

Augusto Monteiro
Augusto Monteiro

Reputation: 491

You can do sth like:

JS

$(".phone-validation").blur(function () {
        var regex = /^[0-9]+$/;
        var phone = this.value;
        if (phone.length > 0 && phone.length < this.getAttribute("maxlength") && !regex.test(phone)) {
            $("#editPhoneError").html('<font color="#cc0000">The number must be a numeric 10 digit value </font>');
            $(this).addClass("validation");
        }
        else {
            $("#editPhoneError").html('<font color="#cc0000"></font>');
            $(this).removeClass("validation");
        }
        $("#btnSave").prop("disabled", ($(":input.validation").length > 0));
    });   
}

Markup:

 <div>
 <input class="phone-validation" maxlength="3" onkeyup="tabout(this,'editPrefix')" name="editArea" style="float:left; width:70px;" type="text" value="@Model.Pharmacy.Area" depends />
 </div>
 <div>
 <input class="phone-validation" maxlength="3" onkeyup="tabout(this,'editSuffix')" name="editPrefix" style="float:left; width:70px;" type="text" value="@Model.Pharmacy.Prefix" depends />
  </div>
  <div>
  <input class="phone-validation" maxlength="4" onkeyup="tabout(this,'editPrefix')" name="editSuffix" style="float:left; width:70px;" type="text" value="@Model.Pharmacy.Suffix" depends />
  </div>
  <span style="margin-left:-208px; margin-top:50px;" id="editPhoneError" value="0"></span>
  </div>

Upvotes: 1

Related Questions