Subversion Repositories My Stuff

Rev

View as "text/plain" | Blame | Last modification | View Log | RSS feed

jQuery.fn.maxLength = function(len)
{
  var maxLengthKeyPress = new Array();
  var maxLengthChange = new Array();
  var appleKeyOn = false;
 
  //the second argument should be true if len should be based on
  //the maxlength attribute instead of the input
  var useAttr = arguments.length>1 ? arguments[1] : false;
 
  var handleKeyUp = function(e)
  {
    //if the apple key (macs) is being pressed, set the indicator
    if(e.keyCode==224||e.keyCode==91)
      appleKeyOn = false;
  }
 
  var handleKeyDown = function(e)
  {
    //if the apple key (macs) is being released, turn off the indicator
    if(e.keyCode==224||e.keyCode==91)
      appleKeyOn = true;
  }
 
  var handleKeyPress = function(e)
  {  
    //if this keyCode does not increase the length of the textarea value,
    //just let it go
    if(appleKeyOn || (e.charCode==0&&e.keyCode!=13) || e.ctrlKey)
      return;

    //get the textarea element
    var textarea = $(this);
    //if the length should be based on the maxlength attribute instead of the
    //input, use that
    len = useAttr ? parseInt(textarea.attr('maxlength')) : len;
    //get the value of the textarea
    var val = textarea.val();
    //get the length of the current text selection
    var selected = Math.abs(textarea.attr('selectionStart') - textarea.attr('selectionEnd'));
    selected = isNaN(selected) ? 0 : selected;
    //if this is the maximum length
    if(val.length==len && selected<1)
      return false;
    else if(val.length>len && selected<(val.length-len))
      return textarea.val(textarea.val().substring(0,len));
  };
 
  var handleChange = function(e)
  {
    //get the textarea element
    var textarea = $(this);
   
    //if the length should be based on the maxlength attribute instead of the
    //input, use that
    len = useAttr ? parseInt(textarea.attr('maxlength')) : len;
   
    //truncate the textarea to its proper length
    textarea.val(textarea.val().substring(0,len));
  };
 
  //get the current keyup and change functions
  var removeKeyPress = maxLengthKeyPress[this.selector];
  var removeChange = maxLengthChange[this.selector];

  //remove the keyup and change functions from any matched elements in case
  //a maxlength was previously set and a new one is being set
  this.die('keypress', removeKeyPress);
  this.die('change', removeChange);
 
  if(len==0 && !useAttr)
    return;
 
  //set the keyup and change functions for this element set and all future
  //elements matching this selector
  this.live('keypress', handleKeyPress);
  this.live('change', handleChange);
  this.live('keydown', handleKeyDown);
  this.live('keyup', handleKeyUp);
 
  //save the current keyup and change functions so that they can be
  //remove later
  maxLengthKeyPress[this.selector] = handleKeyPress;
  maxLengthChange[this.selector] = handleChange;
 
  //trigger a keypress event so that the limit will be enforced
  this.keypress();
};

$(function()
{
  //limit the length of all textareas with the maxlength attribute
  //NOTE: setting maxlength on a textarea is NOT valid XHTML. this
  //was added for coders who want to code loosely--not me!
  $('textarea[maxlength]').maxLength(null, true);
});