Function with jquery.alphanumeric

5.9k views Asked by At

i wanto implement jquery.alphanumeric in html pattern, so i use jquery plugin from here,

this is my code

<input type="text" char-allow="$#*" class="alpha">
<input type="text" char-allow="+-" class="numeric">
<input type="text" char-allow="&" class="alphanumeric">

<script>
    function setAlphaNumeric(){
        $(".numeric").each(function(){
            var a = $(this).attr("char-allow"); $(this).numeric({allow:a});
        });
        $(".alpha").each(function(){
            var a = $(this).attr("char-allow"); $(this).alpha({allow:a});
        });
        $(".alphanumeric").each(function(){
            var a = $(this).attr("char-allow"); $(this).alphanumeric({allow:a});
        });
    }

$(function(){

setAlphaNumeric();

});
</script>

is there any shortest & best than that code?

1

There are 1 answers

5
SpYk3HH On BEST ANSWER

FYI, with jQuery and a little simple use of RegEx, you really don't need a plugin for this. It's extremely simple.

Update! Here's a quick breakdown of first example.

  • $(document).on: Here, I'm simply making use of the DOM's document variable to assign events via jQuery live feature. This is a handy way to ensure that even elements loaded after the DOM is finished loading (dynamic elements) will still adhere to the given event task.
  • .on('keydown', '.alpha': The first 2 params are our event and our selector, respectively. I chose the keydown event because we can control whether or not to even show a character by returning a boolean value. IF false is returned, then no character will be printed to the UI.
  • var a = e.key;: jQuery Events is nice enough to translate to String what character is being asked for. Here, I simply assign that String to a variable for checking!
  • if (a.length == 1): The reason for this is simple, if the String is longer than 1 or less than 1, then it's not a character. You can see this yourself by using something like console.debug(a); in the Event method, and then watching your console as you type in the input. For example, a Backspace key will have a String of "Backspace".

The RegEx's:

  1. /[a-z]|\$|#|\*/i: alpha
    • [a-z]: Looks for all lower case letters a through z
    • |\$|#|\*: Includes your "allowed" characters, using | as an "OR" separator. A Backslash is needed for the $ and * characters in order to escape them in the RegEx statements; otherwise they have an entirely different meaning of their own.
    • /i: This little suffix tells our RegEx to ignore the case of the characters. So our beginning statement no longer cares if it's Lower or Upper case.
  2. /[0-9]|\+|-/: numeric
    • [0-9]: Looks for each digit, 0 through 9
    • |\+|-: Much the same as the alphabet one, this is your extra "allowed" characters, separated by an | (OR) operator.
  3. /[a-z]|[0-9]|&/i: alphanumeric
    • [a-z]: Looks for all lower case letters a through z
    • |[0-9]: Or looks for each digit, 0 through 9
    • |&: Again, checks for your allowed character.
    • /i: And again, ignore all case issues.

Example 1:

$(document)
 .on('keydown', '.alpha', function(e) {
  var a = e.key;
  if (a.length == 1) return /[a-z]|\$|#|\*/i.test(a);
  return true;
 })
 .on('keydown', '.numeric', function(e) {
  var a = e.key;
  if (a.length == 1) return /[0-9]|\+|-/.test(a);
  return true;
 })
 .on('keydown', '.alphanumeric', function(e) {
  var a = e.key;
  if (a.length == 1) return /[a-z]|[0-9]|&/i.test(a);
  return true;
 })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<hr />
<label for="inpAlpha">Alpha</label>
<input id="inpAlpha" type="text" char-allow="$#*" class="alpha" />
<hr />
<label for="inpNumeric">Num</label>
<input id="inpNumeric" type="text" char-allow="+-" class="numeric" />
<hr />
<label for="inpAlphaNum">Alpha Num</label>
<input id="inpAlphaNum" type="text" char-allow="&" class="alphanumeric" />
<hr />

Or with everything combined in one method, Example 2:

$(document)
 .on('keydown', 'input', function(e) {
  var a = e.key;
  if (a.length == 1) switch (true) {
   case $(this).hasClass('alpha'):
    return /[a-z]|\$|#|\*/i.test(a);
    break;
   case $(this).hasClass('numeric'):
    return /[0-9]|\+|-/.test(a);
    break;
   case $(this).hasClass('alphanumeric'):
    return /[a-z]|[0-9]|&/i.test(a);
    break;
  }
  return true;
 })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<hr />
<label for="inpAlpha">Alpha</label>
<input id="inpAlpha" type="text" char-allow="$#*" class="alpha" />
<hr />
<label for="inpNumeric">Num</label>
<input id="inpNumeric" type="text" char-allow="+-" class="numeric" />
<hr />
<label for="inpAlphaNum">Alpha Num</label>
<input id="inpAlphaNum" type="text" char-allow="&" class="alphanumeric" />
<hr />



And, just for the heck of it, if you really do want a jQuery Plugin, I made a couple very simple ones. The first one is even more simplistic than the Plugin referred to by OP. See My Github for a bit more detailed info than below.

Most Simplistic Version:

This first version is barely 20 lines of code, and could even be minified to be much smaller [QuickLink]. It's very simplistic in that you only need to assign 1 of 3 classes to any input, [ 'alpha', 'numeric', 'alphanumeric' ]. If you want extra characters allowed, then simply add an HTML5 data attribute of "allow" and give it the value of the extra characters to allow.
Like so: <input class="alpha" data-allow="$#*" type="text" />

;(function($) {
 var regEx = {
   alpha: new RegExp('[a-z]', 'i'),
   numeric: new RegExp('[0-9]'),
   alphanumeric: new RegExp('[a-z]|[0-9]', 'i')
  }
 function procInput(a, b, c) {
  switch(!0) {
   case a.hasClass('alpha'):
    return c ? 0 <= c.indexOf(b) || regEx.alpha.test(b) : regEx.alpha.test(b);
   case a.hasClass('numeric'):
    return c ? 0 <= c.indexOf(b) || regEx.numeric.test(b) : regEx.numeric.test(b);
   case a.hasClass('alphanumeric'):
    return c ? 0 <= c.indexOf(b) || regEx.alphanumeric.test(b) : regEx.alphanumeric.test(b);
  }
  return !0;
 }
 $(document).on('keydown', 'input', function(e) {
  var a = $(this), b = e.key, c = a.data('allow');
  return (!e.altKey && !e.ctrlKey) && 1 == b.length ? procInput(a, b, c) : !0;
 });
})(jQuery);

/* The following will "dynamically" make the second Alpha input an alpha only input 3 seconds after load is finished. This shows hwo the event assignment is versatile.  */
setTimeout(function() { $('#inpAlphaB').val('').addClass('alpha'); }, 3e3);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<hr />
<label for="inpAlpha">Alpha</label>
<input id="inpAlpha" type="text" data-allow="$#*" class="alpha" />
<hr />
<label for="inpAlphaB">Alpha B</label>
<input id="inpAlphaB" type="text" /> <sub>Is made "alpha" class 3 seconds after load.</sub>
<hr />
<label for="inpNumeric">Num</label>
<input id="inpNumeric" type="text" data-allow="+-" class="numeric" />
<hr />
<label for="inpAlphaNum">Alpha Num</label>
<input id="inpAlphaNum" type="text" data-allow="&" class="alphanumeric" />
<hr />

Extended Version:

This version is a little more involved. Still pretty simplistic in that you need only assign classes and use the data-allow="string" attribute to allow extras. However, the main difference is that this version has its own Object that can be toggled on and off. It also has a feature in the very first line that allows you to set it to initially be on or off based on whether or not the first variable is true or false. This version will also automatically clean the value of alpha|numeric inputs when toggled on.

;(function($) { // $.inputAlphaNumeric // set first variable "initializeON" to bool to toggle on || off from document.ready
 var initializeON = true;
 
 function __event(e) {
  return $.inputAlphaNumeric.keydown.event.apply($.inputAlphaNumeric, [e, this]);
 }
 
 function adjustValue() { // clean up inputs when feature is toggled 'on'
  if (this.state) {
   var regEx = this.regEx;
   this.inputs.each(function() {
    var a = $(this), b = a.val(), c = a.data('allow');
    if (b != '') switch(!0) {
     case $(this).hasClass('alpha'):
      a.val( b.split('').filter(function(v) { if ((c && 0 <= c.indexOf(v)) || regEx.alpha.test(v)) return v; }).join('') );
      break;
     case $(this).hasClass('numeric'):
      a.val( b.split('').filter(function(v) { if ((c && 0 <= c.indexOf(v)) || regEx.numeric.test(v)) return v; }).join('') );
      break;
     case $(this).hasClass('alphanumeric'):
      a.val( b.split('').filter(function(v) { if ((c && 0 <= c.indexOf(v)) || regEx.alphanumeric.test(v)) return v; }).join('') );
      break;
    }
   });
  }
  return this;
 }
 
 function keyDown() {
  return { event: keyDownEvent, process: keyDownProcess }
 }
 function keyDownEvent(e, inp) {
  var a = $(inp), b = e.key, c = a.data('allow');
  return (!e.altKey && !e.ctrlKey) && 1 == b.length ? this.keydown.process.apply(this, [a, b, c]) : !0;
 }
 function keyDownProcess(a, b, c) {
  var regEx = this.regEx;
  switch(!0) {
   case a.hasClass('alpha'):
    return c ? 0 <= c.indexOf(b) || regEx.alpha.test(b) : regEx.alpha.test(b);
   case a.hasClass('numeric'):
    return c ? 0 <= c.indexOf(b) || regEx.numeric.test(b) : regEx.numeric.test(b);
   case a.hasClass('alphanumeric'):
    return c ? 0 <= c.indexOf(b) || regEx.alphanumeric.test(b) : regEx.alphanumeric.test(b);
  }
  return !0;
 }
 
 function inputAlphaNumeric(initOn) {
  Object.defineProperties(this, {
   __state: { enumerable: false, value: false, writable: true },
   adjustVal: {
    enumerable: false,
    value: adjustValue,
    writable: false
   },
   classes: { enumerable: true, get: function() { return [ 'alpha', 'numeric', 'alphanumeric' ]; } },
   inputs: { enumerable: true, get: function() { return $(this.selector); } },
   keydown: { enumerable: false, get: keyDown },
   off: { value: function() { return this.toggle('off'); } },
   on: { value: function() { return this.toggle('on'); } },
   regEx: {
    enumerable: true,
    get: function() {
     return {
      alpha: new RegExp('[a-z]', 'i'),
      numeric: new RegExp('[0-9]'),
      alphanumeric: new RegExp('[a-z]|[0-9]', 'i')
     }
    }
   },
   selector: { enumerable: true, get: function() { return '.' + this.classes.join(', .'); } },
   state: {
    get: function() { return this.__state; },
    set: function(onOff) {
     switch (typeof onOff) {
      case 'boolean':
       this.__state = onOff
       break;
      case 'string':
       switch (onOff) {
        case 'on':
         this.__state = true;
         break;
        case 'off':
         this.__state = false;
         break;
        default:
         this.__state = true;
       }
       break;
      default:
       this.__state = true;
     }
     return this;
    }
   },
   toggle: {
    value: function(onOff) {
     this.state = void 0 == onOff ? !this.state : onOff;
     $(document)[this.state ? 'on' : 'off']('keydown', 'input', __event);
     return this.adjustVal();
    }
   }
  });
  if (initOn) this.on();
  return this;
 }
 
 $.inputAlphaNumeric = new inputAlphaNumeric(initializeON);
})(jQuery);

// checkbox to toggle feature on and off
$(document).on('change', '[type=checkbox]', function(e) { var a = $.inputAlphaNumeric.toggle(this.checked); if (window['console'] && console.debug) console.debug(a); });
// sets initial state of checkbox based on whether or not feature is on or off
$('[type=checkbox]').prop('checked', $.inputAlphaNumeric.state);

setTimeout(function() { $('#inpAlphaB').val('').addClass('alpha'); }, 3e3);

$.each($.inputAlphaNumeric, function(k,v) { console.debug(k + ":\t", v); });
console.debug("$.inputAlphaNumeric:\t", $.inputAlphaNumeric);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<label for="inpAlpha">Alpha</label>
<input id="inpAlpha" type="text" data-allow="$#* " class="alpha" /><!--Notice I added a "space" value as well-->
<hr />
<label for="inpAlphaB">Alpha B</label>
<input id="inpAlphaB" type="text" /> <sub>Is made "alpha" class 3 seconds after load.</sub>
<hr />
<label for="inpNumeric">Num</label>
<input id="inpNumeric" type="text" data-allow="+-" class="numeric" />
<hr />
<label for="inpAlphaNum">Alpha Num</label>
<input id="inpAlphaNum" type="text" data-allow="&" class="alphanumeric" />
<hr />
<label for="inpAlphaNumToggle">Alpha Num</label>
<input id="inpAlphaNumToggle" type="checkbox" />
<hr />