Regex Javascript - text input audit
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

We are needing to audit a text input for a number of conditions and was looking to get some help getting some highly efficient well structured solution. Basically we want to analyze the input for a few conditions

Is all uppercase
Is all lowercase
Is more than 25 characters
Is between 25 and 50 characters
Is over 25 characters
Is title case
Character count including spaces

In the sample code (jsfiddle would be nice) we want a text input where we can put some text. As we input we want the text to be checked against the above tests. -"as it passes or fails we just want to show a green or red icon indicating pass or fail. Ideally we don't need to submit to get results, it's just evaluated as we type. Finally it would be awesome if this was somewhat modular so as we end up with more tests we can keep adding them in an organized fashion

Ideally no jquery dependency

Hey Qdev, not clear what this looks like. Do you want to check a single field for many conditions? Each field would have one condition? Character count including spaces means you'd give an arbitrary count? Isn't this a superset of conditions 3 to 6? 3 and 6 are the same, right?
julianobs 3 years ago
Yes single field which we run all of these tests against. Character count would show how many characters we have input to that field
Qdev 3 years ago
Big job to make it modular as in reusable and extendable, but I am working on it (without jQuery) :-)
LayZee 3 years ago
I just added a modular solution with samples.
LayZee 3 years ago
hey everyone, great solutions. I see some of you did a really nice job handling title case validation. Ill review and award in the next 24 hours.... its going to be tough to pick here :)
Qdev 3 years ago
Any problems, Qdev?
LayZee 3 years ago
hi Qdev, any update on this bounty ?
kerncy 3 years ago
Did you get to pick a winner, Qdev?
LayZee almost 3 years ago
awarded to daphee

Crowdsource coding tasks.

8 Solutions


Here is my solution : https://jsfiddle.net/dstq6pd5/14/

A test can be created at the top of the JS using array. First element is a unique id, second element is the text to display and the third one is the function test to perform. This function must return true or false.

By this way, you can add or remove tests easily just by coding the function.

Do not hesitate f you have any question.


Hi,

I have been busy creating this jQuery plugin for a while now. As you see it is still in development phase, but has enough done to do what you want.

Here is the jsFiddle demo. The data-check attribute determines which checks/tests are checked for the input. You can see in the js how extra checks can be added. You will notice that the 'minlength' check is not there as it is built into the plugin.

Unfortunately it uses jQuery as it is a plugin created for it.

@Qdev, I have updated the plugin by removing jQuery from its core. Here is an updated jsFiddle that uses the core directly - so it does not depend on jQuery.
chesedo 3 years ago
Winning solution

Hi,

here is my solution: https://jsfiddle.net/2d0Lfudn/7/

If you need more edge cases handled for the title case detection just comment.
In case you simply want a allow a word to be lowercase just add it to the smallWords array in line 40.


Hi, please see my solution here: https://jsfiddle.net/zqqx92yy/3/

Do let me know if something is not quite right!

I've added a comment that shows where you can add more tests.


See: jsfiddle demo

With HTML:

<label>Enter your input: <input id="input"></input></label>
<div>Characters: <span id="counter">0</span></div>
<div id="errors"></div>

And CSS:

.error {
  color: red;
}

This JS should work:

// define rules
var rules = [{
    regex: /^[A-Z]+$/,
    message: 'Is all uppercase'
}, {
    regex: /^[a-z]+$/,
    message: 'Is all lowercase'
}, {
    regex: /^.{26,}$/,
    message: 'Is more than 25 characters'
}, {
    regex: /^.{25,50}$/,
    message: 'Is between 25 and 50 characters'
}, {
    regex: /^(?:[A-Z][a-z]*)+$/,
    message: 'Is title case'
}];

// store reference to dom elements
var errorElement = document.getElementById('errors'),
    inputElement = document.getElementById('input'),
    counterElement = document.getElementById('counter');

// react to user input
inputElement.onkeyup = function() {

    // run all tests, build up errors html and set as error element content
    errorElement.innerHTML = rules.reduce(function(memo, rule){
        if (rule.regex.test(inputElement.value)) {
            memo.push('<div class="error">' + rule.message + '</div>');
        }
        return memo;
    }, []).join('');

    // set counter
    counterElement.innerHTML = this.value.length;

}

jsfiddle

Html

<label>Enter your input: <input id="input"></input></label>
<div>Characters: <span id="counter">0</span></div>
<div id="errors"></div>

CSS:

.input-error {
   border-color: red;
  }

 .input-success {
  border-color: green;
}

.errors {
  color: red;
}

.success {
 color: green;
}

Javascript:

var inputElement = document.getElementById('input');

inputElement.onkeyup = function() {
  var value = this.value;
  //Counter update
  document.getElementById('counter').innerHTML = value.length;

  //Reset buttons state
  document.getElementById('success').innerHTML = '';
  document.getElementById('errors').innerHTML = '';

  this.className = '';

  if (value.length == 0) {
    return;
  }

  //Validate input
  var msg = validateInput(this.value);

  if (msg.length == 0) {
    inputElement.className = 'input-success';
    document.getElementById('errors').innerHTML = '';
    document.getElementById('success').innerHTML = '<p>All pass!</p>';
  } else {
    inputElement.className = 'input-error';
    document.getElementById('errors').innerHTML = msg.join('');
  }
}

function Rule(rule, message) {
  this.rule = rule;
  this.message = message;
  this.isRegex = rule instanceof RegExp;
  this.isFunction = typeof rule == 'function';
  this.validate = function(value) {
    if (this.isRegex) {
      return rule.test(value);
    } else if (this.isFunction) {
      return rule.call(this, value);
    }
  };
}

// Function that defines the input value
function validateInput(value) {
  // Example with regex
  var lowerCaseRule = new Rule(/^[a-z]+$/, 'All lower case');
  var titleCase = new Rule(/^(?:[A-Z][a-z]*)+$/, 'Is title case');
  var betweenNCharacters = new Rule(/^.{25,50}$/, 'Is between 25 and 50 characters');

  //Example with function 
  var upperCaseRule = new Rule(function(value) {
    return value == value.toLowerCase();
  }, 'All upper case');
  var moreThanNChar = new Rule(function(value) {
    return value.length > 25;
  }, 'Is more than 25 characters');

  rules = []
  rules.push(lowerCaseRule);
  rules.push(upperCaseRule);
  rules.push(betweenNCharacters);
  rules.push(moreThanNChar);
  rules.push(titleCase);

  var msg = [];
  for (var i = 0; i < rules.length; i++) {
    var rule = rules[i];
    if (rule.validate(value)) {
      msg.push('<div class="error">' + rule.message + '</div>');
    }
  }
  return msg;
}

Modular solution

Too much code to include complete source code here.

Sample solution as JSFiddle (Validatinator is included as an external resource)

Features

  • No jQuery
  • Not only regular expressions - not all validations can be made with a RegExp
  • Based on Validatinator - easy to add new validation rules (see sample solution)
  • Character counter using single delegated event handler
  • Validations using in total one delegated event handler per <form> element:
    • Between x and y characters (betweenLength:x,y)
    • At least x characters (minLength:x)
    • Lower case only (lowerCase)
    • Upper case only (upperCase)
    • Title case only (titleCase), e.g. "A Boat For My Father"
    • Real title case only (titleCase:real) with extensive word list of articles, conjunctions, and prepositions, e.g. "A Boat for My Father"
    • Lots of other built-in validations
  • Validation icons - accessible to color blind users, low contrast screens, outdoor environments, etc.
  • Customizable validation messages
  • Toggles disabled state of submit button based on form validation
  • Validates on input, cut, and paste events
  • Example styling

Sample markup

<form name="example-form">
    <div class="js-field-wrapper field-wrapper">
        <input name="example-field" type="text"
            data-character-counter />
    </div>

    <button type="submit">
        Submit
    </button>
</form>

Sample validation config

var validator = new Validation({
    'example-form': {
        'example-field': {
            betweenLength: [25, 50],
            lowerCase: null,
            minLength: 25,
            titleCase: 'real',
            upperCase: null
        }
    }
});
UPDATE: Fixed real title case validation.
LayZee 3 years ago
View Timeline