Skip to content

Instantly share code, notes, and snippets.

@glideranderson
Created October 11, 2011 15:22
Show Gist options
  • Save glideranderson/1278380 to your computer and use it in GitHub Desktop.
Save glideranderson/1278380 to your computer and use it in GitHub Desktop.
Update to jquery.counter-2.0.js
/*! jQuery.counter.js (jQuery Character and Word Counter plugin)
v2.0 (c) Wilkins Fernandez
MIT License
*/
(function($) {
$.fn.extend({
counter : function(options) {
var defaults = {
type : 'char', // {char || word}
count : 'down', // count {up || down} from or to the goal number
goal : 140, // count {to || from} this number
text : true, // Show description of counter
msg : ''
}, $countObj = '', countIndex = '',
// Pass {} as first argument to preserve defaults/options for comparision
options = $.extend({}, defaults, options), methods = {
/* Adds the counter to the page and binds counter to user input fields */
init : function($obj) {
var objID = $obj.attr('id'), counterID = objID + '_count';
// Insert counter after text area/box
$('<div/>').attr('id', objID + '_counter').html("<span id=" + counterID + "/> " + methods.setMsg() ).insertAfter($obj);
// Set $countObj jQuery object
$countObj = $('#' + counterID);
// Bind methods to events
methods.bind($obj);
},
bind : function($obj) {
$obj.bind("keypress.counter keydown.counter keyup.counter blur.counter focus.counter change.counter paste.counter", methods.updateCounter);
$obj.bind("keydown.counter", methods.doStopTyping);
$obj.trigger('keydown');
},
/* Sets the appropriate message after counter */
setMsg : function() {
if(options.msg !== '') {
return options.msg;
}
this.text = "character word left max".split(' ');
this.chars = "s ( )".split(' ');
this.msg = "";
switch (options.type) {
case "char":
if(options.count === defaults.count && options.text) {
// x character(s) left
this.msg = this.text[0] + this.chars[1] + this.chars[0] + this.chars[2] + " " + this.text[2];
} else if(options.count === "up" && options.text) {
// x characters (x max)
this.msg = this.text[0] + this.chars[0] + " " + this.chars[1] + options.goal + " " + this.text[3] + this.chars[2];
}
break;
case "word":
if(options.count === defaults.count && options.text) {
// x word(s) left
this.msg = this.text[1] + this.chars[1] + this.chars[0] + this.chars[2] + " " + this.text[2];
} else if(options.count === "up" && options.text) {
// x word(s) (x max)
this.msg = this.text[1] + this.chars[1] + this.chars[0] + this.chars[2] + " " + this.chars[1] + options.goal + " " + this.text[3] + this.chars[2];
}
break;
default:
}
return this.msg;
},
/* Returns the amount of words passed in the val argument
* @param val Words to count */
getWords : function(val) {
if(val !== "") {
return $.trim(val).replace(/\s+/g, " ").split(" ").length;
} else {
return 0;
}
},
updateCounter : function(e) {
// Save reference to $(this)
var $this = $(this);
// Is the goal amount passed? (most common when pasting)
if(countIndex < 0 || countIndex > options.goal) {
methods.passedGoal($this);
}
// Counting characters...
if(options.type === defaults.type) {
// ...down
if(options.count === defaults.count) {
countIndex = options.goal - $this.val().length;
// ...up
} else if(options.count === 'up') {
countIndex = $this.val().length;
}
//$countObj.text(countIndex);
// Counting words...
} else if(options.type === 'word') {
// ...down
if(options.count === defaults.count) {
// Count words
countIndex = methods.getWords($this.val());
//console.log('count words ' + countIndex);
// Then subtract
countIndex = options.goal - countIndex;
// Update text
$countObj.text(countIndex);
// ...up
} else if(options.count === 'up') {
countIndex = methods.getWords($this.val());
//$countObj.text(countIndex);
}
}
// Is the goal amount passed? (most common when pasting)
if(countIndex < 0 || countIndex > options.goal) {
methods.passedGoal($this);
}
// Update text
if(countIndex < 0)
countIndex = 0;
$countObj.text(countIndex);
return;
},
/* Stops the ability to type */
doStopTyping : function(e) {
// backspace, delete, tab, left, up, right, down, end, home, spacebar
var keys = [46, 8, 9, 35, 36, 37, 38, 39, 40, 32], $this = $(this);
if(methods.isGoalReached(e)) {
// NOTE: Refactoring this condition into a function was too slow; it'd let you type 1 more character, THEN stop you and remove it
if(e.keyCode !== keys[0] && e.keyCode !== keys[1] && e.keyCode !== keys[2] && e.keyCode !== keys[3] && e.keyCode !== keys[4] && e.keyCode !== keys[5] && e.keyCode !== keys[6] && e.keyCode !== keys[7] && e.keyCode !== keys[8]) {
// Stop typing when counting characters
if(options.type === defaults.type) {
return false;
// Counting words, only allow backspace & delete
} else if(e.keyCode !== keys[9] && e.keyCode !== keys[1] && options.type != defaults.type) {
return true;
} else {
return false;
}
}
}
},
/* Checks to see if the goal number has been reached */
isGoalReached : function(e) {
var _goal;
// Counting down
if(options.count === defaults.count) {
_goal = 0;
return (countIndex <= _goal ) ? true : false;
} else {
// Counting up
_goal = options.goal;
return (countIndex >= _goal ) ? true : false;
}
},
/* Removes extra words when the amount of words in the input go over the desired goal.
* @param {Number} numOfWords Amount of words you would like shown
* @param {String} text The full text to condense
* */
wordStrip : function(numOfWords, text) {
var wordCount = text.replace(/\s+/g, ' ').split(' ').length;
//console.log('wordCount' + wordCount + ' numOfWords ' + numOfWords);
// Get the word count by counting the spaces (after eliminating trailing white space)
text = $.trim(text);
// Make it worth executing
if(numOfWords <= 0 || numOfWords === wordCount) {
return text;
} else {
text = $.trim(text).split(' ');
//console.log(text);
text.splice(numOfWords, wordCount, '');
//console.log('stripped text length ' + text.length);
return $.trim(text.join(' '));
}
},
/* If the goal is passed, trim the chars/words down to what is allowed. Also, reset the counter. */
passedGoal : function($obj) {
var userInput = $obj.val();
if(options.type === 'word') {
$obj.val(methods.wordStrip(options.goal, userInput));
}
if(options.type === 'char') {
$obj.val(userInput.substring(0, options.goal));
}
// Reset to 0
if(options.count === 'down') { // type
$countObj.val('0');
}
// Reset to goal
if(options.count === 'up') { // type
$countObj.val(options.goal);
}
}
};
return this.each(function() {
methods.init($(this));
});
}
});
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment