Sasquatch
Sasquatch

Reputation: 27

How to validate single lines in Html TextAreaFor against regular expression(s)

I am stuck with the following problem. On a web page in my current C# / MVC project, I added some control elements to fill a model. Among these control elements is a text area, designed using @Html.TextAreaFor:

<div class="smt-textarea ">
                @Html.LabelFor(m => m.Numbers):
                @Html.TextAreaFor(m => m. Numbers, new
                {
                    @class = "form-control",
                    id = "smt-textarea",
                    rows = 25,
                })

            </div>

Users should enter a sequence of numbers into that text area. The number sequence follows a specific pattern. The pattern is later evaluated in code-behind methods, which are working well, and which are not part of my question here.

As a new feature, the numbers entered in the text area should now be validated regarding the amount of numbers in the actual sequence. The rule states that only digits from 0-9 can be entered in the text area. A number sequence should consist of exactly 19 digits.

Since I need to directly access the text area, I figured it might be a good idea to opt for Javascript in this particular case. I should note that I am quite new to JS and this might be one part of the problem. Be that as it may, based on some posts here on SO, I came up with the following preliminary solution.

console.log(textArea.value);
    var reg = /\d{19,19}/;
    let regex = new RegExp(reg);

    if (regex.test(textArea.value)) {
        console.log(regex.test(textArea.value));
        alert("IT'S A MATCH !!!");
    } else {
        alert("SORRY, NO MATCH.");
    }
}

window.onload = function () {
    var textArea = document.getElementById("smt-textarea");
    textArea.onkeyup = function (evt) {
        evt = evt || window.event;

        if (evt.keyCode === 13) {
            validateTextArea(this);
        }
    };
};

Unfortunately, the code seems to validate the entire text area, meaning I do get a match whenever there are one more digit sequences matching the pattern, e.g. when entering the following

12345
0276114931111401167
skjfsjgrs
ksgfskgjsgjsrgs

skjfsjgrs and ksgfskgjsgjsrgs are valid because they are preceded by a "valid" number sequence. What I would like to accomplish is that upon pressing the <ENTER> key, only the current line of the text area should be validated against the regular expression outlined in the sample. If the current line does not match, a warning message should be displayed. Once the user corrected his/her digit sequence, validation should continue moving to the next line until the next error pops up.

Upvotes: 0

Views: 717

Answers (1)

Roman Koliada
Roman Koliada

Reputation: 5112

At the moment your validation will be passed if your string from text area contains a sequence from 19 numbers. In order to make sure each line is valid you'd better use ^ and $ anchors to match the whole string from start to end. Something like this: /^(\d{3}\n?)*$/

var textArea = document.getElementById("smt-textarea");
textArea.onkeyup = function(evt) {
  evt = evt || window.event;

  if (evt.keyCode === 13) {
    validateTextArea(this);
  }
};

function validateTextArea(textArea) {
  let regex = new RegExp(/^(\d{19}\n?)*$/);

  if (regex.test(textArea.value)) {
    alert("IT'S A MATCH !!!");
  } else {
    alert("SORRY, NO MATCH.");
  }
}
<textarea name="" id="smt-textarea" rows="25"></textarea>

Also it might be a good idea to trim your string value in order to avoid problems with white-space characters in the end.

Update

Here is another version which validate line by line:

var textArea = document.getElementById("smt-textarea");
textArea.onkeyup = function(evt) {
  evt = evt || window.event;

  if (evt.keyCode === 13) {
    validateTextArea(this);
  }
};

function validateTextArea(textArea) {
  let lines = textArea.value.trim().split('\n');
  let regex = new RegExp(/^\d{19}$/);
  let invalid = lines.some(function(line, index) {
    let lineInvalid = !regex.test(line);
    if (lineInvalid) {
      alert(`Line ${index+1} is invalid`);
    }

    return lineInvalid;
  });

  console.log(`Text area is ${(invalid ? 'invalid' : 'valid')}`);
}
<textarea name="" id="smt-textarea" rows="25"></textarea>

Upvotes: 1

Related Questions