From 52ff64b3cfb4f185afd0e632eb63fd86a27a7f41 Mon Sep 17 00:00:00 2001 From: ractoon Date: Tue, 8 Nov 2016 22:02:34 +0000 Subject: [PATCH 01/34] 0.5.0 --- package.json | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index c8acc96..4462f58 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,31 @@ { - "name": "jquery-text-counter", - "title": "jQuery Text Counter", - "description": "jQuery plugin to count text/characters in a textarea or input. Allows error notifications on minimum or maximum number of characters/words.", - "keywords": [ - "jquery-plugin", - "ecosystem:jquery", - "words", - "characters", - "counter", - "minimum", - "maximum" - ], - "version": "0.4.0", - "author": { - "name": "ractoon", - "url": "http://www.ractoon.com" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/ractoon/jQuery-Text-Counter/blob/master/LICENSE.md" - } - ], - "bugs": "https://github.com/ractoon/jQuery-Text-Counter/issues", - "homepage": "https://github.com/ractoon/jQuery-Text-Counter", - "repository": "https://github.com/ractoon/jQuery-Text-Counter", - "dependencies": { - "jquery": ">=1.5" - } -} \ No newline at end of file + "name": "jquery-text-counter", + "title": "jQuery Text Counter", + "description": "jQuery plugin to count text/characters in a textarea or input. Allows error notifications on minimum or maximum number of characters/words.", + "keywords": [ + "jquery-plugin", + "ecosystem:jquery", + "words", + "characters", + "counter", + "minimum", + "maximum" + ], + "version": "0.5.0", + "author": { + "name": "ractoon", + "url": "http://www.ractoon.com" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/ractoon/jQuery-Text-Counter/blob/master/LICENSE.md" + } + ], + "bugs": "https://github.com/ractoon/jQuery-Text-Counter/issues", + "homepage": "https://github.com/ractoon/jQuery-Text-Counter", + "repository": "https://github.com/ractoon/jQuery-Text-Counter", + "dependencies": { + "jquery": ">=1.5" + } +} From 3d78f7df2847045d7ff59c519e3802f82da27ab2 Mon Sep 17 00:00:00 2001 From: ractoon Date: Thu, 10 Nov 2016 09:32:17 -0700 Subject: [PATCH 02/34] Multiple classes errorText fix --- README.md | 3 ++- bower.json | 2 +- package.json | 1 - textcounter.jquery.json | 2 +- textcounter.js | 9 +++++---- textcounter.min.js | 5 +---- 6 files changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2ee9318..cc84b2e 100644 --- a/README.md +++ b/README.md @@ -155,4 +155,5 @@ init : function(el){} // Callback: function(element - [SammyB](https://github.com/SammyB) - countdown starting count fix - [eprincen2](https://github.com/eprincen2) - jQuery Validate compatibility fix - [Hexodus](https://github.com/Hexodus) - minunder/maxunder events -- [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container \ No newline at end of file +- [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container +- [dtipson](https://github.com/dtipson) - multiple classes error fix \ No newline at end of file diff --git a/bower.json b/bower.json index dd1b11c..e679bfc 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.4.0", + "version": "0.4.1", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 4462f58..0ae3296 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "minimum", "maximum" ], - "version": "0.5.0", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index 1666241..ac96070 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,7 @@ "minimum", "maximum" ], - "version": "0.4.0", + "version": "0.4.1", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 87393f4..5ba8c84 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.4.0 +* jQuery Text Counter Plugin v0.4.1 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon @@ -25,8 +25,8 @@ var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, counterNum = base.options.countDown ? base.options.max : 0; - base.$text_counter = $('').addClass(base.options.textCountClass).text(counterNum); - base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).text(counterText).append(base.$text_counter); + base.$text_counter = $('').addClass(base.options.textCountClass).text(counterNum); + base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).text(counterText).append(base.$text_counter); base.$el.after(base.$container); // bind input events @@ -164,7 +164,8 @@ base.setErrors = function(type) { var $this = base.$el, - $countEl = $base.$container; + $countEl = base.$container, + errorText = ''; $this.addClass(base.options.inputErrorClass); $countEl.addClass(base.options.counterErrorClass); diff --git a/textcounter.min.js b/textcounter.min.js index 5aef493..fb9a624 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -5,7 +5,4 @@ * Copyright 2014 ractoon * Released under the MIT license */ -(function(a){a.textcounter=function(c,b){var d=this;d.$el=a(c);d.el=c;d.$el.data("textcounter",d);d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,b);var f=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0;d.$text_counter=a("").addClass(d.options.textCountClass).text(e);d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).text(f).append(d.$text_counter);d.$el.after(d.$container);d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter");d.options.init(d.el)};d.checkLimits=function(o){var p=d.$el,t=d.$container,r=p.val(),h=0,u=0,s=o.originalEvent===undefined?false:true;if(!a.isEmptyObject(r)){if(d.options.type=="word"){h=r.trim().replace(/\s+/gi," ").split(" ").length}else{if(d.options.countSpaces){h=r.replace(/[^\S\n|\r|\r\n]/g," ").length}else{h=r.replace(/\s/g,"").length -}if(d.options.countExtendedCharacters){var l=r.match(/[^\x00-\xff]/gi);if(l==null){h=r.length}else{h=r.length+l.length}}}}if(d.options.max=="auto"){var q=d.$el.attr("maxlength");if(typeof q!=="undefined"&&q!==false){d.options.max=q}else{d.$container.text("error: [maxlength] attribute not set")}}u=d.options.countDown?d.options.max-h:h;d.setCount(u);if(d.options.min>0&&s){if(h=d.options.min){d.options.mincount(d.el);d.clearErrors("min")}}}if(d.options.max!==-1){if(h>=d.options.max&&d.options.max!=0){d.options.maxcount(d.el);if(d.options.stopInputAtMaximum){var k="";if(d.options.type=="word"){var m=r.split(/[^\S\n]/g);var j=0;while(j=d.options.max-1){break}if(m[j]!==undefined){k+=m[j]+" ";j++}}}else{if(d.options.countSpaces){k=r.substring(0,d.options.max)}else{var g=r.split(""),n=g.length,f=0,j=0;while(f'+errorText+"")}}};d.clearErrors=function(e){var g=d.$el,f=d.$container;f.children(".error-text-"+e).remove();if(f.children(".error-text").length==0){g.removeClass(d.options.inputErrorClass);f.removeClass(d.options.counterErrorClass)}};d.init()};a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: ",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:true,stopInputAtMaximum:true,countSpaces:false,countDown:false,countDownText:"Remaining: ",countExtendedCharacters:false,maxunder:function(b){},minunder:function(b){},maxcount:function(b){},mincount:function(b){},init:function(b){}}; -a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}})(jQuery); +!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0;d.$text_counter=a("").addClass(d.options.textCountClass).text(e),d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).text(b).append(d.$text_counter),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(!a.isEmptyObject(f))if("word"==d.options.type)g=f.trim().replace(/\s+/gi," ").split(" ").length;else if(g=d.options.countSpaces?f.replace(/[^\S\n|\r|\r\n]/g," ").length:f.replace(/\s/g,"").length,d.options.countExtendedCharacters){var j=f.match(/[^\x00-\xff]/gi);g=null==j?f.length:f.length+j.length}if("auto"==d.options.max){var k=d.$el.attr("maxlength");"undefined"!=typeof k&&k!==!1?d.options.max=k:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),d.options.max!==-1)if(g>=d.options.max&&0!=d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var l="";if("word"==d.options.type)for(var m=f.split(/[^\S\n]/g),n=0;n=d.options.max-1);)void 0!==m[n]&&(l+=m[n]+" ",n++);else if(d.options.countSpaces)l=f.substring(0,d.options.max);else for(var o=f.split(""),p=o.length,q=0,n=0;q'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: ",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: ",countExtendedCharacters:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file From bb7bd13076df9bd4f76f23b1f95a891ab5eec896 Mon Sep 17 00:00:00 2001 From: ractoon Date: Thu, 10 Nov 2016 09:32:31 -0700 Subject: [PATCH 03/34] npm version 0.4.1 --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 0ae3296..86263ab 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "minimum", "maximum" ], + "version": "0.4.1", "author": { "name": "ractoon", "url": "http://www.ractoon.com" From bf32a6a327c0e49ca0c7be290e438fde13b04175 Mon Sep 17 00:00:00 2001 From: ractoon Date: Thu, 24 Nov 2016 22:46:31 -0700 Subject: [PATCH 04/34] Flexible counterText/countDownText replacements --- README.md | 5 ++--- bower.json | 1 - package.json | 1 - textcounter.jquery.json | 1 - textcounter.js | 13 ++++++------- textcounter.min.js | 4 ++-- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index cc84b2e..e9518d5 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,6 @@ Define minimum characters and set custom `countDownText` ([view editable code](h ```javascript $('input').textcounter({ min: 20, - countDownText: "Characters Left: " }); ``` @@ -117,7 +116,7 @@ countContainerClass : "text-count-wrapper", // class applied to the count textCountClass : "text-count", // class applied to the counter length inputErrorClass : "error", // error class appended to the input element if error occurs counterErrorClass : "error", // error class appended to the countContainerElement if error occurs -counterText : "Total Count: ", // counter text +counterText : "Total Count: %d", // counter text, %d replaced with count value errorTextElement : "div", // error text element minimumErrorText : "Minimum not met", // error message for minimum not met, maximumErrorText : "Maximum exceeded", // error message for maximum range exceeded, @@ -125,7 +124,7 @@ displayErrorText : true, // display error text message stopInputAtMaximum : true, // stop further text input if maximum reached countSpaces : false, // count spaces as character (only for "character" type) countDown : false, // if the counter should deduct from maximum characters/words rather than counting up -countDownText : "Remaining: ", // count down text +countDownText : "Remaining: %d", // count down text, %d replaced with remaining value countExtendedCharacters : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) // Callback API diff --git a/bower.json b/bower.json index e679bfc..67b7fb9 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,5 @@ { "name": "jquery-text-counter", - "version": "0.4.1", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 86263ab..0ae3296 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "minimum", "maximum" ], - "version": "0.4.1", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index ac96070..3f7b8f3 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,6 @@ "minimum", "maximum" ], - "version": "0.4.1", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 5ba8c84..5438631 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,4 @@ /*! -* jQuery Text Counter Plugin v0.4.1 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon @@ -23,10 +22,11 @@ // append the count element var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, - counterNum = base.options.countDown ? base.options.max : 0; + counterNum = base.options.countDown ? base.options.max : 0, + $formatted_counter_text = $('
').html(counterText.replace('%d', '' + counterNum + '')).contents(); - base.$text_counter = $('').addClass(base.options.textCountClass).text(counterNum); - base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).text(counterText).append(base.$text_counter); + base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).append($formatted_counter_text); + base.$text_counter = base.$container.find('span'); base.$el.after(base.$container); // bind input events @@ -86,7 +86,6 @@ // set the current text count base.setCount(textTotalCount); - if (base.options.min > 0 && eventTriggered) { // if a minimum value has been set if (textCount < base.options.min) { base.setErrors('min'); @@ -211,7 +210,7 @@ 'textCountClass' : "text-count", // class applied to the counter length 'inputErrorClass' : "error", // error class appended to the input element if error occurs 'counterErrorClass' : "error", // error class appended to the countContainerElement if error occurs - 'counterText' : "Total Count: ", // counter text + 'counterText' : "Total Count: %d", // counter text 'errorTextElement' : "div", // error text element 'minimumErrorText' : "Minimum not met", // error message for minimum not met, 'maximumErrorText' : "Maximum exceeded", // error message for maximum range exceeded, @@ -219,7 +218,7 @@ 'stopInputAtMaximum' : true, // stop further text input if maximum reached 'countSpaces' : false, // count spaces as character (only for "character" type) 'countDown' : false, // if the counter should deduct from maximum characters/words rather than counting up - 'countDownText' : "Remaining: ", // count down text + 'countDownText' : "Remaining: %d", // count down text 'countExtendedCharacters' : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) // Callback API diff --git a/textcounter.min.js b/textcounter.min.js index fb9a624..89d0557 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,8 +1,8 @@ /*! -* jQuery Text Counter Plugin v0.4.0 +* jQuery Text Counter Plugin v0.5.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon * Released under the MIT license */ -!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0;d.$text_counter=a("").addClass(d.options.textCountClass).text(e),d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).text(b).append(d.$text_counter),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(!a.isEmptyObject(f))if("word"==d.options.type)g=f.trim().replace(/\s+/gi," ").split(" ").length;else if(g=d.options.countSpaces?f.replace(/[^\S\n|\r|\r\n]/g," ").length:f.replace(/\s/g,"").length,d.options.countExtendedCharacters){var j=f.match(/[^\x00-\xff]/gi);g=null==j?f.length:f.length+j.length}if("auto"==d.options.max){var k=d.$el.attr("maxlength");"undefined"!=typeof k&&k!==!1?d.options.max=k:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),d.options.max!==-1)if(g>=d.options.max&&0!=d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var l="";if("word"==d.options.type)for(var m=f.split(/[^\S\n]/g),n=0;n=d.options.max-1);)void 0!==m[n]&&(l+=m[n]+" ",n++);else if(d.options.countSpaces)l=f.substring(0,d.options.max);else for(var o=f.split(""),p=o.length,q=0,n=0;q'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: ",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: ",countExtendedCharacters:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file +!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(!a.isEmptyObject(f))if("word"==d.options.type)g=f.trim().replace(/\s+/gi," ").split(" ").length;else if(g=d.options.countSpaces?f.replace(/[^\S\n|\r|\r\n]/g," ").length:f.replace(/\s/g,"").length,d.options.countExtendedCharacters){var j=f.match(/[^\x00-\xff]/gi);g=null==j?f.length:f.length+j.length}if("auto"==d.options.max){var k=d.$el.attr("maxlength");"undefined"!=typeof k&&k!==!1?d.options.max=k:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),d.options.max!==-1)if(g>=d.options.max&&0!=d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var l="";if("word"==d.options.type)for(var m=f.split(/[^\S\n]/g),n=0;n=d.options.max-1);)void 0!==m[n]&&(l+=m[n]+" ",n++);else if(d.options.countSpaces)l=f.substring(0,d.options.max);else for(var o=f.split(""),p=o.length,q=0,n=0;q'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file From cd511e11153f42296883e632eac9555f344b92fb Mon Sep 17 00:00:00 2001 From: ractoon Date: Thu, 24 Nov 2016 22:47:28 -0700 Subject: [PATCH 05/34] Version 0.5.0 Flexible counterText/countDownText replacments --- README.md | 1 + bower.json | 1 + package.json | 1 + textcounter.jquery.json | 1 + textcounter.js | 1 + 5 files changed, 5 insertions(+) diff --git a/README.md b/README.md index e9518d5..4aa0805 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ Define minimum characters and set custom `countDownText` ([view editable code](h ```javascript $('input').textcounter({ min: 20, + countDownText: "%d characters remaining" }); ``` diff --git a/bower.json b/bower.json index 67b7fb9..95d3a93 100644 --- a/bower.json +++ b/bower.json @@ -1,5 +1,6 @@ { "name": "jquery-text-counter", + "version": "0.5.0", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 0ae3296..4462f58 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "minimum", "maximum" ], + "version": "0.5.0", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index 3f7b8f3..f598869 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,6 +9,7 @@ "minimum", "maximum" ], + "version": "0.5.0", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 5438631..41b5d25 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,4 +1,5 @@ /*! +* jQuery Text Counter Plugin v0.5.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon From 57743bc8abae2d6bd742b308a6b9c8bd46b5d9ca Mon Sep 17 00:00:00 2001 From: ractoon Date: Tue, 29 Nov 2016 13:04:47 -0700 Subject: [PATCH 06/34] Example link updates --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4aa0805..c47325d 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Basic usage ([view editable code](http://jsfiddle.net/ractoon/p7x72La3/)): $('input').textcounter(); ``` -Define maximum words and allow further input ([view editable code](http://jsfiddle.net/ractoon/n4ufjo3b/)): +Define maximum words and allow further input ([view editable code](https://jsfiddle.net/ractoon/n4ufjo3b/)): ```javascript $('input').textcounter({ @@ -48,7 +48,7 @@ $('input').textcounter({ }); ``` -Define minimum characters and set custom `countDownText` ([view editable code](http://jsfiddle.net/ractoon/jx8awxbb/)): +Define minimum characters and set custom `countDownText` ([view editable code](https://jsfiddle.net/ractoon/jx8awxbb/)): ```javascript $('input').textcounter({ @@ -59,7 +59,7 @@ $('input').textcounter({ ## Example -[View editable example](http://jsfiddle.net/ractoon/1xkuyp46/1/) +[View editable example](http://jsfiddle.net/ractoon/1xkuyp46/) ## Elements From bbde3a2a9b5a70ec51b2e3923c2b81e10148e1bf Mon Sep 17 00:00:00 2001 From: ractoon Date: Tue, 14 Feb 2017 09:51:16 -0700 Subject: [PATCH 07/34] Two character carriage return option --- README.md | 4 +- bower.json | 2 +- package.json | 2 +- textcounter.jquery.json | 2 +- textcounter.js | 436 +++++++++++++++++++++------------------- textcounter.min.js | 4 +- 6 files changed, 234 insertions(+), 216 deletions(-) diff --git a/README.md b/README.md index c47325d..bbb066a 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ countSpaces : false, // count spaces as character countDown : false, // if the counter should deduct from maximum characters/words rather than counting up countDownText : "Remaining: %d", // count down text, %d replaced with remaining value countExtendedCharacters : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) +twoCharCarriageReturn : false, // count carriage returns/newlines as 2 characters // Callback API maxunder : function(el){}, // Callback: function(element) - Fires when counter is under max limit @@ -156,4 +157,5 @@ init : function(el){} // Callback: function(element - [eprincen2](https://github.com/eprincen2) - jQuery Validate compatibility fix - [Hexodus](https://github.com/Hexodus) - minunder/maxunder events - [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container -- [dtipson](https://github.com/dtipson) - multiple classes error fix \ No newline at end of file +- [dtipson](https://github.com/dtipson) - multiple classes error fix +- [jmichalicek](https://github.com/jmichalicek) - count carriage returns/newlines as 2 characters \ No newline at end of file diff --git a/bower.json b/bower.json index 95d3a93..5a2b2f4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.5.0", + "version": "0.6.0", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 4462f58..6d8d185 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "minimum", "maximum" ], - "version": "0.5.0", + "version": "0.6.0", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index f598869..1f9668e 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,7 @@ "minimum", "maximum" ], - "version": "0.5.0", + "version": "0.6.0", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 41b5d25..5a9e6d1 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,239 +1,255 @@ /*! -* jQuery Text Counter Plugin v0.5.0 +* jQuery Text Counter Plugin v0.6.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon * Released under the MIT license */ ;(function($) { - $.textcounter = function(el, options) { - // To avoid scope issues, use 'base' instead of 'this' - // to reference this class from internal events and functions. - var base = this; - - // Access to jQuery and DOM versions of element - base.$el = $(el); - base.el = el; + $.textcounter = function(el, options) { + // To avoid scope issues, use 'base' instead of 'this' + // to reference this class from internal events and functions. + var base = this; + + // Access to jQuery and DOM versions of element + base.$el = $(el); + base.el = el; + + // Add a reverse reference to the DOM object + base.$el.data('textcounter', base); + + base.init = function() { + base.options = $.extend({}, $.textcounter.defaultOptions, options); + + // append the count element + var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, + counterNum = base.options.countDown ? base.options.max : 0, + $formatted_counter_text = $('
').html(counterText.replace('%d', '' + counterNum + '')).contents(); + + base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).append($formatted_counter_text); + base.$text_counter = base.$container.find('span'); + base.$el.after(base.$container); + + // bind input events + base.$el.bind('keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter', base.checkLimits).trigger('click.textcounter'); + + // TextCounter: init(el) Callback + base.options.init(base.el); + }; + + base.checkLimits = function(e) { + var $this = base.$el, + $countEl = base.$container, + $text = $this.val(), + textCount = 0, + textTotalCount = 0, + eventTriggered = e.originalEvent === undefined ? false : true; + + if (!$.isEmptyObject($text)) { + if (base.options.type == "word") { // word count + textCount = $text.trim().replace(/\s+/gi, ' ').split(' ').length; + } + else { // character count + // count carriage returns/newlines as 2 characters + if (base.options.twoCharCarriageReturn) { + var carriageReturns = $text.match(/(\r\n|\n|\r)/g), + carriageReturnsCount = 0; + + if (carriageReturns !== null) { + carriageReturnsCount = carriageReturns.length; + } + } + + if (base.options.countSpaces) { // if need to count spaces + textCount = $text.replace(/[^\S\n|\r|\r\n]/g, ' ').length; + } + else { + textCount = $text.replace(/\s/g, '').length; + } + + // count extended characters (e.g. Chinese) + if (base.options.countExtendedCharacters) { + var extended = $text.match(/[^\x00-\xff]/gi); + + if (extended == null) { + textCount = $text.length; + } else { + textCount = $text.length + extended.length; + } + } + + if (base.options.twoCharCarriageReturn) { + textCount += carriageReturnsCount; + } + } + } - // Add a reverse reference to the DOM object - base.$el.data("textcounter", base); + // if max is auto retrieve value + if (base.options.max == 'auto') { + var max = base.$el.attr('maxlength'); - base.init = function() { - base.options = $.extend({}, $.textcounter.defaultOptions, options); + if (typeof max !== 'undefined' && max !== false) { + base.options.max = max; + } + else { + base.$container.text('error: [maxlength] attribute not set'); + } + } - // append the count element - var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, - counterNum = base.options.countDown ? base.options.max : 0, - $formatted_counter_text = $('
').html(counterText.replace('%d', '' + counterNum + '')).contents(); + // if this is a countdown counter deduct from the max characters/words + textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; - base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).append($formatted_counter_text); - base.$text_counter = base.$container.find('span'); - base.$el.after(base.$container); + // set the current text count + base.setCount(textTotalCount); - // bind input events - base.$el.bind('keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter', base.checkLimits).trigger('click.textcounter'); + if (base.options.min > 0 && eventTriggered) { // if a minimum value has been set + if (textCount < base.options.min) { + base.setErrors('min'); - // TextCounter: init(el) Callback - base.options.init(base.el); - }; + // TextCounter: minunder(el) Callback + base.options.minunder(base.el); + } + else if (textCount >= base.options.min) { + // TextCounter: mincount(el) Callback + base.options.mincount(base.el); - base.checkLimits = function(e) { - var $this = base.$el, - $countEl = base.$container, - $text = $this.val(), - textCount = 0, - textTotalCount = 0, - eventTriggered = e.originalEvent === undefined ? false : true; - - if (!$.isEmptyObject($text)) { - if (base.options.type == "word") { // word count - textCount = $text.trim().replace(/\s+/gi, ' ').split(' ').length; - } - else { // character count - if (base.options.countSpaces) { // if need to count spaces - textCount = $text.replace(/[^\S\n|\r|\r\n]/g, ' ').length; - } - else { - textCount = $text.replace(/\s/g, '').length; - } - - if (base.options.countExtendedCharacters) { - var extended = $text.match(/[^\x00-\xff]/gi); - - if (extended == null) { - textCount = $text.length; - } else { - textCount = $text.length + extended.length; + base.clearErrors('min'); + } } - } - } - } - - // if max is auto retrieve value - if (base.options.max == 'auto') { - var max = base.$el.attr('maxlength'); - - if (typeof max !== 'undefined' && max !== false) { - base.options.max = max; - } - else { - base.$container.text('error: [maxlength] attribute not set'); - } - } - - // if this is a countdown counter deduct from the max characters/words - textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; - - // set the current text count - base.setCount(textTotalCount); - - if (base.options.min > 0 && eventTriggered) { // if a minimum value has been set - if (textCount < base.options.min) { - base.setErrors('min'); - - // TextCounter: minunder(el) Callback - base.options.minunder(base.el); - } - else if (textCount >= base.options.min) { - // TextCounter: mincount(el) Callback - base.options.mincount(base.el); - - base.clearErrors('min'); - } - } - - if (base.options.max !== -1) { // if a maximum value has been set - if (textCount >= base.options.max && base.options.max != 0) { - // TextCounter: maxcount(el) Callback - base.options.maxcount(base.el); - - if (base.options.stopInputAtMaximum) { // if the string should be trimmed at the maximum length - var trimmedString = ''; - - if (base.options.type == "word") { // word type - var wordArray = $text.split(/[^\S\n]/g); - var i = 0; - - // iterate over individual words - while (i < wordArray.length) { - // if over the maximum words allowed break; - if (i >= base.options.max - 1) break; - - if (wordArray[i] !== undefined) { - trimmedString += wordArray[i] + ' '; - i++; + + if (base.options.max !== -1) { // if a maximum value has been set + if (textCount >= base.options.max && base.options.max != 0) { + // TextCounter: maxcount(el) Callback + base.options.maxcount(base.el); + + if (base.options.stopInputAtMaximum) { // if the string should be trimmed at the maximum length + var trimmedString = ''; + + if (base.options.type == "word") { // word type + var wordArray = $text.split(/[^\S\n]/g); + var i = 0; + + // iterate over individual words + while (i < wordArray.length) { + // if over the maximum words allowed break; + if (i >= base.options.max - 1) break; + + if (wordArray[i] !== undefined) { + trimmedString += wordArray[i] + ' '; + i++; + } + } + } + else { // character type + if (base.options.countSpaces) { // if spaces should be counted + trimmedString = $text.substring(0, base.options.max); + } + else { + var charArray = $text.split(''), + totalCharacters = charArray.length, + charCount = 0, + i = 0; + + while (charCount < base.options.max && i < totalCharacters) { + if (charArray[i] !== ' ') charCount++; + trimmedString += charArray[i++]; + } + } + } + + $this.val(trimmedString.trim()); + + textTotalCount = base.options.countDown ? 0 : base.options.max; + base.setCount(textTotalCount); + } else { + base.setErrors('max'); + } + } + else { + // TextCounter: maxunder(el) Callback + base.options.maxunder(base.el); + base.clearErrors('max'); } - } } - else { // character type - if (base.options.countSpaces) { // if spaces should be counted - trimmedString = $text.substring(0, base.options.max); - } - else { - var charArray = $text.split(''), - totalCharacters = charArray.length, - charCount = 0, - i = 0; - - while (charCount < base.options.max && i < totalCharacters) { - if (charArray[i] !== ' ') charCount++; - trimmedString += charArray[i++]; + }; + + base.setCount = function(count) { + base.$text_counter.text(count); + }; + + base.setErrors = function(type) { + var $this = base.$el, + $countEl = base.$container, + errorText = ''; + + $this.addClass(base.options.inputErrorClass); + $countEl.addClass(base.options.counterErrorClass); + + if (base.options.displayErrorText) { + switch(type) { + case 'min': + errorText = base.options.minimumErrorText; + break; + case 'max': + errorText = base.options.maximumErrorText; + break; + } + + if (!$countEl.children('.error-text-' + type).length) { + $countEl.append('<' + base.options.errorTextElement + ' class="error-text error-text-' + type + '">' + errorText + ''); } - } } + }; - $this.val(trimmedString.trim()); + base.clearErrors = function(type) { + var $this = base.$el, + $countEl = base.$container; - textTotalCount = base.options.countDown ? 0 : base.options.max; - base.setCount(textTotalCount); - } else { - base.setErrors('max'); - } - } - else { - // TextCounter: maxunder(el) Callback - base.options.maxunder(base.el); - base.clearErrors('max'); - } - } - }; + $countEl.children('.error-text-' + type).remove(); - base.setCount = function(count) { - base.$text_counter.text(count); - }; + if ($countEl.children('.error-text').length == 0) { + $this.removeClass(base.options.inputErrorClass); + $countEl.removeClass(base.options.counterErrorClass); + } + }; - base.setErrors = function(type) { - var $this = base.$el, - $countEl = base.$container, - errorText = ''; - - $this.addClass(base.options.inputErrorClass); - $countEl.addClass(base.options.counterErrorClass); - - if (base.options.displayErrorText) { - switch(type) { - case 'min': - errorText = base.options.minimumErrorText; - break; - case 'max': - errorText = base.options.maximumErrorText; - break; - } - - if (!$countEl.children('.error-text-' + type).length) { - $countEl.append('<' + base.options.errorTextElement + ' class="error-text error-text-' + type + '">' + errorText + ''); - } - } + // kick it off + base.init(); }; - base.clearErrors = function(type) { - var $this = base.$el, - $countEl = base.$container; - - $countEl.children('.error-text-' + type).remove(); - - if ($countEl.children('.error-text').length == 0) { - $this.removeClass(base.options.inputErrorClass); - $countEl.removeClass(base.options.counterErrorClass); - } + $.textcounter.defaultOptions = { + 'type' : "character", // "character" or "word" + 'min' : 0, // minimum number of characters/words + 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute + 'countContainerElement' : "div", // HTML element to wrap the text count in + 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement + 'textCountClass' : "text-count", // class applied to the counter length + 'inputErrorClass' : "error", // error class appended to the input element if error occurs + 'counterErrorClass' : "error", // error class appended to the countContainerElement if error occurs + 'counterText' : "Total Count: %d", // counter text + 'errorTextElement' : "div", // error text element + 'minimumErrorText' : "Minimum not met", // error message for minimum not met, + 'maximumErrorText' : "Maximum exceeded", // error message for maximum range exceeded, + 'displayErrorText' : true, // display error text messages for minimum/maximum values + 'stopInputAtMaximum' : true, // stop further text input if maximum reached + 'countSpaces' : false, // count spaces as character (only for "character" type) + 'countDown' : false, // if the counter should deduct from maximum characters/words rather than counting up + 'countDownText' : "Remaining: %d", // count down text + 'countExtendedCharacters' : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) + 'twoCharCarriageReturn' : false, // count carriage returns/newlines as 2 characters + + // Callback API + 'maxunder' : function(el){}, // Callback: function(element) - Fires when counter under max limit + 'minunder' : function(el){}, // Callback: function(element) - Fires when counter under min limit + 'maxcount' : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count + 'mincount' : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count + 'init' : function(el){} // Callback: function(element) - Fires after the counter is initially setup }; - // kick it off - base.init(); - }; - - $.textcounter.defaultOptions = { - 'type' : "character", // "character" or "word" - 'min' : 0, // minimum number of characters/words - 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute - 'countContainerElement' : "div", // HTML element to wrap the text count in - 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement - 'textCountClass' : "text-count", // class applied to the counter length - 'inputErrorClass' : "error", // error class appended to the input element if error occurs - 'counterErrorClass' : "error", // error class appended to the countContainerElement if error occurs - 'counterText' : "Total Count: %d", // counter text - 'errorTextElement' : "div", // error text element - 'minimumErrorText' : "Minimum not met", // error message for minimum not met, - 'maximumErrorText' : "Maximum exceeded", // error message for maximum range exceeded, - 'displayErrorText' : true, // display error text messages for minimum/maximum values - 'stopInputAtMaximum' : true, // stop further text input if maximum reached - 'countSpaces' : false, // count spaces as character (only for "character" type) - 'countDown' : false, // if the counter should deduct from maximum characters/words rather than counting up - 'countDownText' : "Remaining: %d", // count down text - 'countExtendedCharacters' : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) - - // Callback API - maxunder : function(el){}, // Callback: function(element) - Fires when counter under max limit - minunder : function(el){}, // Callback: function(element) - Fires when counter under min limit - maxcount : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count - mincount : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count - init : function(el){} // Callback: function(element) - Fires after the counter is initially setup - }; - - $.fn.textcounter = function(options) { - return this.each(function() { - new $.textcounter(this, options); - }); - }; + $.fn.textcounter = function(options) { + return this.each(function() { + new $.textcounter(this, options); + }); + }; })(jQuery); diff --git a/textcounter.min.js b/textcounter.min.js index 89d0557..de126cb 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,8 +1,8 @@ /*! -* jQuery Text Counter Plugin v0.5.0 +* jQuery Text Counter Plugin v0.6.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon * Released under the MIT license */ -!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(!a.isEmptyObject(f))if("word"==d.options.type)g=f.trim().replace(/\s+/gi," ").split(" ").length;else if(g=d.options.countSpaces?f.replace(/[^\S\n|\r|\r\n]/g," ").length:f.replace(/\s/g,"").length,d.options.countExtendedCharacters){var j=f.match(/[^\x00-\xff]/gi);g=null==j?f.length:f.length+j.length}if("auto"==d.options.max){var k=d.$el.attr("maxlength");"undefined"!=typeof k&&k!==!1?d.options.max=k:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),d.options.max!==-1)if(g>=d.options.max&&0!=d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var l="";if("word"==d.options.type)for(var m=f.split(/[^\S\n]/g),n=0;n=d.options.max-1);)void 0!==m[n]&&(l+=m[n]+" ",n++);else if(d.options.countSpaces)l=f.substring(0,d.options.max);else for(var o=f.split(""),p=o.length,q=0,n=0;q'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file +!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(!a.isEmptyObject(f))if("word"==d.options.type)g=f.trim().replace(/\s+/gi," ").split(" ").length;else{if(d.options.twoCharCarriageReturn){var j=f.match(/(\r\n|\n|\r)/g),k=0;null!==j&&(k=j.length)}if(g=d.options.countSpaces?f.replace(/[^\S\n|\r|\r\n]/g," ").length:f.replace(/\s/g,"").length,d.options.countExtendedCharacters){var l=f.match(/[^\x00-\xff]/gi);g=null==l?f.length:f.length+l.length}d.options.twoCharCarriageReturn&&(g+=k)}if("auto"==d.options.max){var m=d.$el.attr("maxlength");"undefined"!=typeof m&&m!==!1?d.options.max=m:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),d.options.max!==-1)if(g>=d.options.max&&0!=d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var n="";if("word"==d.options.type)for(var o=f.split(/[^\S\n]/g),p=0;p=d.options.max-1);)void 0!==o[p]&&(n+=o[p]+" ",p++);else if(d.options.countSpaces)n=f.substring(0,d.options.max);else for(var q=f.split(""),r=q.length,s=0,p=0;s'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file From 810c3a678a8fee0f9966e5a0023e5c7a87778fdb Mon Sep 17 00:00:00 2001 From: ractoon Date: Sat, 8 Apr 2017 21:33:24 -0600 Subject: [PATCH 08/34] Incorrect word countdown fix Fix for issue #26 --- bower.json | 2 +- package.json | 2 +- textcounter.jquery.json | 2 +- textcounter.js | 6 +++--- textcounter.min.js | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bower.json b/bower.json index 5a2b2f4..f023020 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.6.0", + "version": "0.6.1", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 6d8d185..71accaa 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "minimum", "maximum" ], - "version": "0.6.0", + "version": "0.6.1", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index 1f9668e..00ba4a0 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,7 @@ "minimum", "maximum" ], - "version": "0.6.0", + "version": "0.6.1", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 5a9e6d1..5e9c44a 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.6.0 +* jQuery Text Counter Plugin v0.6.1 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon @@ -118,7 +118,7 @@ } if (base.options.max !== -1) { // if a maximum value has been set - if (textCount >= base.options.max && base.options.max != 0) { + if (textCount >= base.options.max && base.options.max !== 0) { // TextCounter: maxcount(el) Callback base.options.maxcount(base.el); @@ -132,7 +132,7 @@ // iterate over individual words while (i < wordArray.length) { // if over the maximum words allowed break; - if (i >= base.options.max - 1) break; + if (i >= base.options.max) break; if (wordArray[i] !== undefined) { trimmedString += wordArray[i] + ' '; diff --git a/textcounter.min.js b/textcounter.min.js index de126cb..1754020 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,8 +1,8 @@ /*! -* jQuery Text Counter Plugin v0.6.0 +* jQuery Text Counter Plugin v0.6.1 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon * Released under the MIT license */ -!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(!a.isEmptyObject(f))if("word"==d.options.type)g=f.trim().replace(/\s+/gi," ").split(" ").length;else{if(d.options.twoCharCarriageReturn){var j=f.match(/(\r\n|\n|\r)/g),k=0;null!==j&&(k=j.length)}if(g=d.options.countSpaces?f.replace(/[^\S\n|\r|\r\n]/g," ").length:f.replace(/\s/g,"").length,d.options.countExtendedCharacters){var l=f.match(/[^\x00-\xff]/gi);g=null==l?f.length:f.length+l.length}d.options.twoCharCarriageReturn&&(g+=k)}if("auto"==d.options.max){var m=d.$el.attr("maxlength");"undefined"!=typeof m&&m!==!1?d.options.max=m:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),d.options.max!==-1)if(g>=d.options.max&&0!=d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var n="";if("word"==d.options.type)for(var o=f.split(/[^\S\n]/g),p=0;p=d.options.max-1);)void 0!==o[p]&&(n+=o[p]+" ",p++);else if(d.options.countSpaces)n=f.substring(0,d.options.max);else for(var q=f.split(""),r=q.length,s=0,p=0;s'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file +!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(!a.isEmptyObject(f))if("word"==d.options.type)g=f.trim().replace(/\s+/gi," ").split(" ").length;else{if(d.options.twoCharCarriageReturn){var j=f.match(/(\r\n|\n|\r)/g),k=0;null!==j&&(k=j.length)}if(g=d.options.countSpaces?f.replace(/[^\S\n|\r|\r\n]/g," ").length:f.replace(/\s/g,"").length,d.options.countExtendedCharacters){var l=f.match(/[^\x00-\xff]/gi);g=null==l?f.length:f.length+l.length}d.options.twoCharCarriageReturn&&(g+=k)}if("auto"==d.options.max){var m=d.$el.attr("maxlength");void 0!==m&&!1!==m?d.options.max=m:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),-1!==d.options.max)if(g>=d.options.max&&0!==d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var n="";if("word"==d.options.type)for(var o=f.split(/[^\S\n]/g),p=0;p=d.options.max);)void 0!==o[p]&&(n+=o[p]+" ",p++);else if(d.options.countSpaces)n=f.substring(0,d.options.max);else for(var q=f.split(""),r=q.length,s=0,p=0;s'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file From c9253188335e8f6f73654c6bd869fdd463650f32 Mon Sep 17 00:00:00 2001 From: Diptopol Dam Date: Mon, 10 Apr 2017 11:00:46 +0600 Subject: [PATCH 09/34] Fixed text count for new line If stopInputAtMaximum is set true and we try to insert more character than max limit, plugin will trim the text. For twoCharCarriageReturn option true, if we add a newline which exceeds max limit, plugin will trim but total text count do not decrease by 2. Fixed the issue by reusing textCount for trimmed text. --- textcounter.js | 95 ++++++++++++++++++++++++++++------------------ textcounter.min.js | 2 +- 2 files changed, 59 insertions(+), 38 deletions(-) diff --git a/textcounter.js b/textcounter.js index 5e9c44a..bb105c0 100644 --- a/textcounter.js +++ b/textcounter.js @@ -46,42 +46,7 @@ eventTriggered = e.originalEvent === undefined ? false : true; if (!$.isEmptyObject($text)) { - if (base.options.type == "word") { // word count - textCount = $text.trim().replace(/\s+/gi, ' ').split(' ').length; - } - else { // character count - // count carriage returns/newlines as 2 characters - if (base.options.twoCharCarriageReturn) { - var carriageReturns = $text.match(/(\r\n|\n|\r)/g), - carriageReturnsCount = 0; - - if (carriageReturns !== null) { - carriageReturnsCount = carriageReturns.length; - } - } - - if (base.options.countSpaces) { // if need to count spaces - textCount = $text.replace(/[^\S\n|\r|\r\n]/g, ' ').length; - } - else { - textCount = $text.replace(/\s/g, '').length; - } - - // count extended characters (e.g. Chinese) - if (base.options.countExtendedCharacters) { - var extended = $text.match(/[^\x00-\xff]/gi); - - if (extended == null) { - textCount = $text.length; - } else { - textCount = $text.length + extended.length; - } - } - - if (base.options.twoCharCarriageReturn) { - textCount += carriageReturnsCount; - } - } + textCount = base.textCount($text); } // if max is auto retrieve value @@ -159,7 +124,8 @@ $this.val(trimmedString.trim()); - textTotalCount = base.options.countDown ? 0 : base.options.max; + textCount = base.textCount($this.val()); + textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; base.setCount(textTotalCount); } else { base.setErrors('max'); @@ -173,6 +139,61 @@ } }; + base.textCount = function(text) { + var textCount = 0; + + if (base.options.type == "word") { // word count + textCount = base.wordCount(text); + } + else { // character count + textCount = base.characterCount(text); + } + + return textCount; + }; + + base.wordCount = function(text) { + return text.trim().replace(/\s+/gi, ' ').split(' ').length; + }; + + base.characterCount = function(text) { + var textCount = 0, + carriageReturnsCount = 0; + + // count carriage returns/newlines as 2 characters + if (base.options.twoCharCarriageReturn) { + var carriageReturns = text.match(/(\r\n|\n|\r)/g); + + if (carriageReturns !== null) { + carriageReturnsCount = carriageReturns.length; + } + } + + if (base.options.countSpaces) { // if need to count spaces + textCount = text.replace(/[^\S\n|\r|\r\n]/g, ' ').length; + } + else { + textCount = text.replace(/\s/g, '').length; + } + + // count extended characters (e.g. Chinese) + if (base.options.countExtendedCharacters) { + var extended = text.match(/[^\x00-\xff]/gi); + + if (extended == null) { + textCount = text.length; + } else { + textCount = text.length + extended.length; + } + } + + if (base.options.twoCharCarriageReturn) { + textCount += carriageReturnsCount; + } + + return textCount; + }; + base.setCount = function(count) { base.$text_counter.text(count); }; diff --git a/textcounter.min.js b/textcounter.min.js index 1754020..44fccc9 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -5,4 +5,4 @@ * Copyright 2014 ractoon * Released under the MIT license */ -!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(!a.isEmptyObject(f))if("word"==d.options.type)g=f.trim().replace(/\s+/gi," ").split(" ").length;else{if(d.options.twoCharCarriageReturn){var j=f.match(/(\r\n|\n|\r)/g),k=0;null!==j&&(k=j.length)}if(g=d.options.countSpaces?f.replace(/[^\S\n|\r|\r\n]/g," ").length:f.replace(/\s/g,"").length,d.options.countExtendedCharacters){var l=f.match(/[^\x00-\xff]/gi);g=null==l?f.length:f.length+l.length}d.options.twoCharCarriageReturn&&(g+=k)}if("auto"==d.options.max){var m=d.$el.attr("maxlength");void 0!==m&&!1!==m?d.options.max=m:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),-1!==d.options.max)if(g>=d.options.max&&0!==d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var n="";if("word"==d.options.type)for(var o=f.split(/[^\S\n]/g),p=0;p=d.options.max);)void 0!==o[p]&&(n+=o[p]+" ",p++);else if(d.options.countSpaces)n=f.substring(0,d.options.max);else for(var q=f.split(""),r=q.length,s=0,p=0;s'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file +!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(a.isEmptyObject(f)||(g=d.textCount(f)),"auto"==d.options.max){var j=d.$el.attr("maxlength");void 0!==j&&!1!==j?d.options.max=j:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),-1!==d.options.max)if(g>=d.options.max&&0!==d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var k="";if("word"==d.options.type)for(var l=f.split(/[^\S\n]/g),m=0;m=d.options.max);)void 0!==l[m]&&(k+=l[m]+" ",m++);else if(d.options.countSpaces)k=f.substring(0,d.options.max);else for(var n=f.split(""),o=n.length,p=0,m=0;p'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file From dc35ab73ad765a12f66a1b2f36619efecaf32282 Mon Sep 17 00:00:00 2001 From: ractoon Date: Sat, 15 Apr 2017 22:04:48 -0600 Subject: [PATCH 10/34] Version 0.6.2 --- README.md | 3 ++- bower.json | 2 +- package.json | 2 +- textcounter.jquery.json | 2 +- textcounter.js | 2 +- textcounter.min.js | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bbb066a..8b33537 100644 --- a/README.md +++ b/README.md @@ -158,4 +158,5 @@ init : function(el){} // Callback: function(element - [Hexodus](https://github.com/Hexodus) - minunder/maxunder events - [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container - [dtipson](https://github.com/dtipson) - multiple classes error fix -- [jmichalicek](https://github.com/jmichalicek) - count carriage returns/newlines as 2 characters \ No newline at end of file +- [jmichalicek](https://github.com/jmichalicek) - count carriage returns/newlines as 2 characters +- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix \ No newline at end of file diff --git a/bower.json b/bower.json index f023020..91208e3 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.6.1", + "version": "0.6.2", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 71accaa..f8bfe4f 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "minimum", "maximum" ], - "version": "0.6.1", + "version": "0.6.2", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index 00ba4a0..7985e3d 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,7 @@ "minimum", "maximum" ], - "version": "0.6.1", + "version": "0.6.2", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index bb105c0..17e9bfd 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.6.1 +* jQuery Text Counter Plugin v0.6.2 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon diff --git a/textcounter.min.js b/textcounter.min.js index 44fccc9..5d83a3a 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.6.1 +* jQuery Text Counter Plugin v0.6.2 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon From 00852f1386032d57a2bf1518731bf8d1e97564c7 Mon Sep 17 00:00:00 2001 From: Diptopol Dam Date: Sun, 16 Apr 2017 15:10:48 +0600 Subject: [PATCH 11/34] Fixed the trimmed text calculation for new line Previously, for stopInputAtMaximum option trimmed text calculation does not consider twoCharCarriageReturn value. As a result, if text contains new lines, user will able to insert extra characters after reaching the max value. --- textcounter.js | 25 ++++++++++++++++++------- textcounter.min.js | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/textcounter.js b/textcounter.js index 17e9bfd..c9fe309 100644 --- a/textcounter.js +++ b/textcounter.js @@ -106,8 +106,12 @@ } } else { // character type + var maxLimit = (base.options.twoCharCarriageReturn) ? + base.options.max - base.twoCharCarriageReturnCount($text) + : base.options.max; + if (base.options.countSpaces) { // if spaces should be counted - trimmedString = $text.substring(0, base.options.max); + trimmedString = $text.substring(0, maxLimit); } else { var charArray = $text.split(''), @@ -115,7 +119,7 @@ charCount = 0, i = 0; - while (charCount < base.options.max && i < totalCharacters) { + while (charCount < maxLimit && i < totalCharacters) { if (charArray[i] !== ' ') charCount++; trimmedString += charArray[i++]; } @@ -162,11 +166,7 @@ // count carriage returns/newlines as 2 characters if (base.options.twoCharCarriageReturn) { - var carriageReturns = text.match(/(\r\n|\n|\r)/g); - - if (carriageReturns !== null) { - carriageReturnsCount = carriageReturns.length; - } + carriageReturnsCount = base.twoCharCarriageReturnCount(text); } if (base.options.countSpaces) { // if need to count spaces @@ -194,6 +194,17 @@ return textCount; }; + base.twoCharCarriageReturnCount = function(text) { + var carriageReturns = text.match(/(\r\n|\n|\r)/g), + carriageReturnsCount = 0; + + if (carriageReturns !== null) { + carriageReturnsCount = carriageReturns.length; + } + + return carriageReturnsCount; + }; + base.setCount = function(count) { base.$text_counter.text(count); }; diff --git a/textcounter.min.js b/textcounter.min.js index 5d83a3a..4db34f7 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -5,4 +5,4 @@ * Copyright 2014 ractoon * Released under the MIT license */ -!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(a.isEmptyObject(f)||(g=d.textCount(f)),"auto"==d.options.max){var j=d.$el.attr("maxlength");void 0!==j&&!1!==j?d.options.max=j:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),-1!==d.options.max)if(g>=d.options.max&&0!==d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var k="";if("word"==d.options.type)for(var l=f.split(/[^\S\n]/g),m=0;m=d.options.max);)void 0!==l[m]&&(k+=l[m]+" ",m++);else if(d.options.countSpaces)k=f.substring(0,d.options.max);else for(var n=f.split(""),o=n.length,p=0,m=0;p'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file +!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(a.isEmptyObject(f)||(g=d.textCount(f)),"auto"==d.options.max){var j=d.$el.attr("maxlength");void 0!==j&&!1!==j?d.options.max=j:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),-1!==d.options.max)if(g>=d.options.max&&0!==d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var k="";if("word"==d.options.type)for(var l=f.split(/[^\S\n]/g),m=0;m=d.options.max);)void 0!==l[m]&&(k+=l[m]+" ",m++);else{var n=d.options.twoCharCarriageReturn?d.options.max-d.twoCharCarriageReturnCount(f):d.options.max;if(d.options.countSpaces)k=f.substring(0,n);else for(var o=f.split(""),p=o.length,q=0,m=0;q'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file From 5a2b85db28dab5708b58d5566659a7d7238d7870 Mon Sep 17 00:00:00 2001 From: ractoon Date: Tue, 18 Apr 2017 21:33:15 -0600 Subject: [PATCH 12/34] Version 0.6.3 --- README.md | 2 +- bower.json | 2 +- package.json | 2 +- textcounter.jquery.json | 2 +- textcounter.js | 2 +- textcounter.min.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8b33537..5a1f992 100644 --- a/README.md +++ b/README.md @@ -159,4 +159,4 @@ init : function(el){} // Callback: function(element - [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container - [dtipson](https://github.com/dtipson) - multiple classes error fix - [jmichalicek](https://github.com/jmichalicek) - count carriage returns/newlines as 2 characters -- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix \ No newline at end of file +- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix \ No newline at end of file diff --git a/bower.json b/bower.json index 91208e3..c864d56 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.6.2", + "version": "0.6.3", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index f8bfe4f..99d1aad 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "minimum", "maximum" ], - "version": "0.6.2", + "version": "0.6.3", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index 7985e3d..e5ea545 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,7 @@ "minimum", "maximum" ], - "version": "0.6.2", + "version": "0.6.3", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index c9fe309..c36bccf 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.6.2 +* jQuery Text Counter Plugin v0.6.3 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon diff --git a/textcounter.min.js b/textcounter.min.js index 4db34f7..5059819 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.6.2 +* jQuery Text Counter Plugin v0.6.3 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon From 070f851dcbb7ce3182504f1e69de1481be4e8f02 Mon Sep 17 00:00:00 2001 From: Diptopol Dam Date: Thu, 20 Jul 2017 11:58:29 +0600 Subject: [PATCH 13/34] Fixed maximum error text occurance Maximum error text should only occur when character or word count exceeds maximum limit. Currently error message is given at the maximum limit. Fixed the issue. --- textcounter.js | 3 ++- textcounter.min.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/textcounter.js b/textcounter.js index c36bccf..56f0a52 100644 --- a/textcounter.js +++ b/textcounter.js @@ -83,10 +83,11 @@ } if (base.options.max !== -1) { // if a maximum value has been set - if (textCount >= base.options.max && base.options.max !== 0) { + if (textCount === base.options.max && base.options.max !== 0) { // TextCounter: maxcount(el) Callback base.options.maxcount(base.el); + } else if (textCount > base.options.max && base.options.max !== 0) { if (base.options.stopInputAtMaximum) { // if the string should be trimmed at the maximum length var trimmedString = ''; diff --git a/textcounter.min.js b/textcounter.min.js index 5059819..b800a43 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -5,4 +5,4 @@ * Copyright 2014 ractoon * Released under the MIT license */ -!function(a){a.textcounter=function(b,c){var d=this;d.$el=a(b),d.el=b,d.$el.data("textcounter",d),d.init=function(){d.options=a.extend({},a.textcounter.defaultOptions,c);var b=d.options.countDown?d.options.countDownText:d.options.counterText,e=d.options.countDown?d.options.max:0,f=a("
").html(b.replace("%d",''+e+"")).contents();d.$container=a("<"+d.options.countContainerElement+"/>").addClass(d.options.countContainerClass).append(f),d.$text_counter=d.$container.find("span"),d.$el.after(d.$container),d.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",d.checkLimits).trigger("click.textcounter"),d.options.init(d.el)},d.checkLimits=function(b){var c=d.$el,f=(d.$container,c.val()),g=0,h=0,i=void 0!==b.originalEvent;if(a.isEmptyObject(f)||(g=d.textCount(f)),"auto"==d.options.max){var j=d.$el.attr("maxlength");void 0!==j&&!1!==j?d.options.max=j:d.$container.text("error: [maxlength] attribute not set")}if(h=d.options.countDown?d.options.max-g:g,d.setCount(h),d.options.min>0&&i&&(g=d.options.min&&(d.options.mincount(d.el),d.clearErrors("min"))),-1!==d.options.max)if(g>=d.options.max&&0!==d.options.max)if(d.options.maxcount(d.el),d.options.stopInputAtMaximum){var k="";if("word"==d.options.type)for(var l=f.split(/[^\S\n]/g),m=0;m=d.options.max);)void 0!==l[m]&&(k+=l[m]+" ",m++);else{var n=d.options.twoCharCarriageReturn?d.options.max-d.twoCharCarriageReturnCount(f):d.options.max;if(d.options.countSpaces)k=f.substring(0,n);else for(var o=f.split(""),p=o.length,q=0,m=0;q'+e+"")}},d.clearErrors=function(a){var b=d.$el,c=d.$container;c.children(".error-text-"+a).remove(),0==c.children(".error-text").length&&(b.removeClass(d.options.inputErrorClass),c.removeClass(d.options.counterErrorClass))},d.init()},a.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(a){},minunder:function(a){},maxcount:function(a){},mincount:function(a){},init:function(a){}},a.fn.textcounter=function(b){return this.each(function(){new a.textcounter(this,b)})}}(jQuery); \ No newline at end of file +!function(t){t.textcounter=function(n,o){var e=this;e.$el=t(n),e.el=n,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,o);var n=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,i=t("
").html(n.replace("%d",''+r+"")).contents();e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(i),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(n){var o=e.$el,r=(e.$container,o.val()),i=0,a=0,s=void 0!==n.originalEvent;if(t.isEmptyObject(r)||(i=e.textCount(r)),"auto"==e.options.max){var u=e.$el.attr("maxlength");void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set")}if(a=e.options.countDown?e.options.max-i:i,e.setCount(a),e.options.min>0&&s&&(i=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(i===e.options.max&&0!==e.options.max)e.options.maxcount(e.el);else if(i>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var p=r.split(/[^\S\n]/g),l=0;l=e.options.max);)void 0!==p[l]&&(c+=p[l]+" ",l++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,d=0,l=0;d'+r+"")}},e.clearErrors=function(t){var n=e.$el,o=e.$container;o.children(".error-text-"+t).remove(),0==o.children(".error-text").length&&(n.removeClass(e.options.inputErrorClass),o.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(n){return this.each(function(){new t.textcounter(this,n)})}}(jQuery); \ No newline at end of file From 2546bda2829c8ca185c998bd813b75dafc333ce9 Mon Sep 17 00:00:00 2001 From: ractoon Date: Sat, 29 Jul 2017 21:50:10 -0600 Subject: [PATCH 14/34] 0.6.4 Maximum text reached condition fix --- README.md | 2 +- bower.json | 2 +- package.json | 2 +- textcounter.jquery.json | 2 +- textcounter.js | 2 +- textcounter.min.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5a1f992..0989cc8 100644 --- a/README.md +++ b/README.md @@ -159,4 +159,4 @@ init : function(el){} // Callback: function(element - [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container - [dtipson](https://github.com/dtipson) - multiple classes error fix - [jmichalicek](https://github.com/jmichalicek) - count carriage returns/newlines as 2 characters -- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix \ No newline at end of file +- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix, maximum text reached condition fix \ No newline at end of file diff --git a/bower.json b/bower.json index c864d56..b917ce3 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.6.3", + "version": "0.6.4", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 99d1aad..066e8bc 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "minimum", "maximum" ], - "version": "0.6.3", + "version": "0.6.4", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index e5ea545..0010d17 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,7 @@ "minimum", "maximum" ], - "version": "0.6.3", + "version": "0.6.4", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 56f0a52..4f524cb 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.6.3 +* jQuery Text Counter Plugin v0.6.4 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon diff --git a/textcounter.min.js b/textcounter.min.js index b800a43..1e17646 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.6.3 +* jQuery Text Counter Plugin v0.6.4 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon From 4a47c26869aa6f657a4e3f44ab8522fbe3543159 Mon Sep 17 00:00:00 2001 From: Diptopol Dam Date: Thu, 3 Aug 2017 15:12:45 +0600 Subject: [PATCH 15/34] Added text count overflow message show For appropriate parameters, added text count overflow message feature. --- textcounter.js | 103 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 29 deletions(-) diff --git a/textcounter.js b/textcounter.js index 4f524cb..6eb6451 100644 --- a/textcounter.js +++ b/textcounter.js @@ -24,9 +24,17 @@ // append the count element var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, counterNum = base.options.countDown ? base.options.max : 0, - $formatted_counter_text = $('
').html(counterText.replace('%d', '' + counterNum + '')).contents(); + $formatted_counter_text = $('
').addClass('text-counter-div') + .html(counterText.replace('%d', '' + counterNum + '')), + $count_overflow_text = $('
').addClass(base.options.countOverflowTextCss); + + base.hideMessage($count_overflow_text); + + base.$container = $('<' + base.options.countContainerElement + '/>') + .addClass(base.options.countContainerClass) + .append($formatted_counter_text) + .append($count_overflow_text); - base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).append($formatted_counter_text); base.$text_counter = base.$container.find('span'); base.$el.after(base.$container); @@ -218,22 +226,54 @@ $this.addClass(base.options.inputErrorClass); $countEl.addClass(base.options.counterErrorClass); - if (base.options.displayErrorText) { - switch(type) { - case 'min': - errorText = base.options.minimumErrorText; - break; - case 'max': - errorText = base.options.maximumErrorText; - break; + switch(type) { + case 'min': + errorText = base.options.minimumErrorText; + break; + case 'max': + errorText = base.options.maximumErrorText; + + if (base.options.countOverflow) { + base.setOverflowMessage(); } + break; + } + + if (base.options.displayErrorText) { if (!$countEl.children('.error-text-' + type).length) { $countEl.append('<' + base.options.errorTextElement + ' class="error-text error-text-' + type + '">' + errorText + ''); } } }; + base.setOverflowMessage = function () { + base.hideMessage(base.$container.find('.text-counter-div')); + + base.removeOverflowMessage(); + + var overflowText = base.options.countOverflowText + .replace('%d', base.textCount(base.$el.val()) - base.options.max) + .replace('%type', base.options.type); + + + var overflowDiv = base.$container.find('.' + base.options.countOverflowTextCss).append(overflowText); + base.showMessage(overflowDiv); + }, + + base.removeOverflowMessage = function () { + base.$container.find('.' + base.options.countOverflowTextCss).empty(); + }, + + base.showMessage = function ($selector) { + $selector.css('display', 'inline'); + }, + + base.hideMessage = function ($selector) { + $selector.css('display', 'none'); + }, + + base.clearErrors = function(type) { var $this = base.$el, $countEl = base.$container; @@ -241,6 +281,8 @@ $countEl.children('.error-text-' + type).remove(); if ($countEl.children('.error-text').length == 0) { + base.removeOverflowMessage(); + base.showMessage(base.$container.find('.text-counter-div')); $this.removeClass(base.options.inputErrorClass); $countEl.removeClass(base.options.counterErrorClass); } @@ -251,25 +293,28 @@ }; $.textcounter.defaultOptions = { - 'type' : "character", // "character" or "word" - 'min' : 0, // minimum number of characters/words - 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute - 'countContainerElement' : "div", // HTML element to wrap the text count in - 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement - 'textCountClass' : "text-count", // class applied to the counter length - 'inputErrorClass' : "error", // error class appended to the input element if error occurs - 'counterErrorClass' : "error", // error class appended to the countContainerElement if error occurs - 'counterText' : "Total Count: %d", // counter text - 'errorTextElement' : "div", // error text element - 'minimumErrorText' : "Minimum not met", // error message for minimum not met, - 'maximumErrorText' : "Maximum exceeded", // error message for maximum range exceeded, - 'displayErrorText' : true, // display error text messages for minimum/maximum values - 'stopInputAtMaximum' : true, // stop further text input if maximum reached - 'countSpaces' : false, // count spaces as character (only for "character" type) - 'countDown' : false, // if the counter should deduct from maximum characters/words rather than counting up - 'countDownText' : "Remaining: %d", // count down text - 'countExtendedCharacters' : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) - 'twoCharCarriageReturn' : false, // count carriage returns/newlines as 2 characters + 'type' : "character", // "character" or "word" + 'min' : 0, // minimum number of characters/words + 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute + 'countContainerElement' : "div", // HTML element to wrap the text count in + 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement + 'textCountClass' : "text-count", // class applied to the counter length + 'inputErrorClass' : "error", // error class appended to the input element if error occurs + 'counterErrorClass' : "error", // error class appended to the countContainerElement if error occurs + 'counterText' : "Total Count: %d", // counter text + 'errorTextElement' : "div", // error text element + 'minimumErrorText' : "Minimum not met", // error message for minimum not met, + 'maximumErrorText' : "Maximum exceeded", // error message for maximum range exceeded, + 'displayErrorText' : true, // display error text messages for minimum/maximum values + 'stopInputAtMaximum' : true, // stop further text input if maximum reached + 'countSpaces' : false, // count spaces as character (only for "character" type) + 'countDown' : false, // if the counter should deduct from maximum characters/words rather than counting up + 'countDownText' : "Remaining: %d", // count down text + 'countExtendedCharacters' : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) + 'twoCharCarriageReturn' : false, // count carriage returns/newlines as 2 characters + 'countOverflow' : false, // count text overflow + 'countOverflowText' : "About %d %type has been entered", // text message for count overflow + 'countOverflowTextCss' : "text-overflow-div", // css for overflow text count // Callback API 'maxunder' : function(el){}, // Callback: function(element) - Fires when counter under max limit From 9a861d674e7ab1f4d7bfe4baf4d3f1956628448b Mon Sep 17 00:00:00 2001 From: Diptopol Dam Date: Thu, 3 Aug 2017 15:16:22 +0600 Subject: [PATCH 16/34] Fixed error message for text count is in maximum limit --- textcounter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/textcounter.js b/textcounter.js index 6eb6451..4f653d3 100644 --- a/textcounter.js +++ b/textcounter.js @@ -94,6 +94,7 @@ if (textCount === base.options.max && base.options.max !== 0) { // TextCounter: maxcount(el) Callback base.options.maxcount(base.el); + base.clearErrors('max'); } else if (textCount > base.options.max && base.options.max !== 0) { if (base.options.stopInputAtMaximum) { // if the string should be trimmed at the maximum length From 80226fd6dc67786672271de1d4d79d7fad795da0 Mon Sep 17 00:00:00 2001 From: Diptopol Dam Date: Thu, 3 Aug 2017 15:30:11 +0600 Subject: [PATCH 17/34] Updated the minified js --- textcounter.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/textcounter.min.js b/textcounter.min.js index 1e17646..483a31e 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -5,4 +5,4 @@ * Copyright 2014 ractoon * Released under the MIT license */ -!function(t){t.textcounter=function(n,o){var e=this;e.$el=t(n),e.el=n,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,o);var n=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,i=t("
").html(n.replace("%d",''+r+"")).contents();e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(i),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(n){var o=e.$el,r=(e.$container,o.val()),i=0,a=0,s=void 0!==n.originalEvent;if(t.isEmptyObject(r)||(i=e.textCount(r)),"auto"==e.options.max){var u=e.$el.attr("maxlength");void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set")}if(a=e.options.countDown?e.options.max-i:i,e.setCount(a),e.options.min>0&&s&&(i=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(i===e.options.max&&0!==e.options.max)e.options.maxcount(e.el);else if(i>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var p=r.split(/[^\S\n]/g),l=0;l=e.options.max);)void 0!==p[l]&&(c+=p[l]+" ",l++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,d=0,l=0;d'+r+"")}},e.clearErrors=function(t){var n=e.$el,o=e.$container;o.children(".error-text-"+t).remove(),0==o.children(".error-text").length&&(n.removeClass(e.options.inputErrorClass),o.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(n){return this.each(function(){new t.textcounter(this,n)})}}(jQuery); \ No newline at end of file +!function(t){t.textcounter=function(e,n){var o=this;o.$el=t(e),o.el=e,o.$el.data("textcounter",o),o.init=function(){o.options=t.extend({},t.textcounter.defaultOptions,n);var e=o.options.countDown?o.options.countDownText:o.options.counterText,r=o.options.countDown?o.options.max:0,i=t("
").addClass("text-counter-div").html(e.replace("%d",''+r+"")),s=t("
").addClass(o.options.countOverflowTextCss);o.hideMessage(s),o.$container=t("<"+o.options.countContainerElement+"/>").addClass(o.options.countContainerClass).append(i).append(s),o.$text_counter=o.$container.find("span"),o.$el.after(o.$container),o.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",o.checkLimits).trigger("click.textcounter"),o.options.init(o.el)},o.checkLimits=function(e){var n=o.$el,r=(o.$container,n.val()),i=0,s=0,a=void 0!==e.originalEvent;if(t.isEmptyObject(r)||(i=o.textCount(r)),"auto"==o.options.max){var u=o.$el.attr("maxlength");void 0!==u&&!1!==u?o.options.max=u:o.$container.text("error: [maxlength] attribute not set")}if(s=o.options.countDown?o.options.max-i:i,o.setCount(s),o.options.min>0&&a&&(i=o.options.min&&(o.options.mincount(o.el),o.clearErrors("min"))),-1!==o.options.max)if(i===o.options.max&&0!==o.options.max)o.options.maxcount(o.el),o.clearErrors("max");else if(i>o.options.max&&0!==o.options.max)if(o.options.stopInputAtMaximum){var c="";if("word"==o.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=o.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=o.options.twoCharCarriageReturn?o.options.max-o.twoCharCarriageReturnCount(r):o.options.max;if(o.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),d=m.length,f=0,p=0;f'+r+""))},o.setOverflowMessage=function(){o.hideMessage(o.$container.find(".text-counter-div")),o.removeOverflowMessage();var t=o.options.countOverflowText.replace("%d",o.textCount(o.$el.val())-o.options.max).replace("%type",o.options.type),e=o.$container.find("."+o.options.countOverflowTextCss).append(t);o.showMessage(e)},o.removeOverflowMessage=function(){o.$container.find("."+o.options.countOverflowTextCss).empty()},o.showMessage=function(t){t.css("display","inline")},o.hideMessage=function(t){t.css("display","none")},o.clearErrors=function(t){var e=o.$el,n=o.$container;n.children(".error-text-"+t).remove(),0==n.children(".error-text").length&&(o.removeOverflowMessage(),o.showMessage(o.$container.find(".text-counter-div")),e.removeClass(o.options.inputErrorClass),n.removeClass(o.options.counterErrorClass))},o.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"About %d %type has been entered",countOverflowTextCss:"text-overflow-div",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(e){return this.each(function(){new t.textcounter(this,e)})}}(jQuery); \ No newline at end of file From 3893371b71f88a35b92ff8e5fab0c641514ceb5a Mon Sep 17 00:00:00 2001 From: Diptopol Dam Date: Thu, 3 Aug 2017 16:43:00 +0600 Subject: [PATCH 18/34] Updated default text count overflow message --- textcounter.js | 2 +- textcounter.min.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/textcounter.js b/textcounter.js index 4f653d3..29f98a6 100644 --- a/textcounter.js +++ b/textcounter.js @@ -314,7 +314,7 @@ 'countExtendedCharacters' : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) 'twoCharCarriageReturn' : false, // count carriage returns/newlines as 2 characters 'countOverflow' : false, // count text overflow - 'countOverflowText' : "About %d %type has been entered", // text message for count overflow + 'countOverflowText' : "About %d extra %type(s) have been entered", // text message for count overflow 'countOverflowTextCss' : "text-overflow-div", // css for overflow text count // Callback API diff --git a/textcounter.min.js b/textcounter.min.js index 483a31e..50a0034 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -5,4 +5,4 @@ * Copyright 2014 ractoon * Released under the MIT license */ -!function(t){t.textcounter=function(e,n){var o=this;o.$el=t(e),o.el=e,o.$el.data("textcounter",o),o.init=function(){o.options=t.extend({},t.textcounter.defaultOptions,n);var e=o.options.countDown?o.options.countDownText:o.options.counterText,r=o.options.countDown?o.options.max:0,i=t("
").addClass("text-counter-div").html(e.replace("%d",''+r+"")),s=t("
").addClass(o.options.countOverflowTextCss);o.hideMessage(s),o.$container=t("<"+o.options.countContainerElement+"/>").addClass(o.options.countContainerClass).append(i).append(s),o.$text_counter=o.$container.find("span"),o.$el.after(o.$container),o.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",o.checkLimits).trigger("click.textcounter"),o.options.init(o.el)},o.checkLimits=function(e){var n=o.$el,r=(o.$container,n.val()),i=0,s=0,a=void 0!==e.originalEvent;if(t.isEmptyObject(r)||(i=o.textCount(r)),"auto"==o.options.max){var u=o.$el.attr("maxlength");void 0!==u&&!1!==u?o.options.max=u:o.$container.text("error: [maxlength] attribute not set")}if(s=o.options.countDown?o.options.max-i:i,o.setCount(s),o.options.min>0&&a&&(i=o.options.min&&(o.options.mincount(o.el),o.clearErrors("min"))),-1!==o.options.max)if(i===o.options.max&&0!==o.options.max)o.options.maxcount(o.el),o.clearErrors("max");else if(i>o.options.max&&0!==o.options.max)if(o.options.stopInputAtMaximum){var c="";if("word"==o.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=o.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=o.options.twoCharCarriageReturn?o.options.max-o.twoCharCarriageReturnCount(r):o.options.max;if(o.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),d=m.length,f=0,p=0;f'+r+""))},o.setOverflowMessage=function(){o.hideMessage(o.$container.find(".text-counter-div")),o.removeOverflowMessage();var t=o.options.countOverflowText.replace("%d",o.textCount(o.$el.val())-o.options.max).replace("%type",o.options.type),e=o.$container.find("."+o.options.countOverflowTextCss).append(t);o.showMessage(e)},o.removeOverflowMessage=function(){o.$container.find("."+o.options.countOverflowTextCss).empty()},o.showMessage=function(t){t.css("display","inline")},o.hideMessage=function(t){t.css("display","none")},o.clearErrors=function(t){var e=o.$el,n=o.$container;n.children(".error-text-"+t).remove(),0==n.children(".error-text").length&&(o.removeOverflowMessage(),o.showMessage(o.$container.find(".text-counter-div")),e.removeClass(o.options.inputErrorClass),n.removeClass(o.options.counterErrorClass))},o.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"About %d %type has been entered",countOverflowTextCss:"text-overflow-div",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(e){return this.each(function(){new t.textcounter(this,e)})}}(jQuery); \ No newline at end of file +!function(t){t.textcounter=function(e,n){var o=this;o.$el=t(e),o.el=e,o.$el.data("textcounter",o),o.init=function(){o.options=t.extend({},t.textcounter.defaultOptions,n);var e=o.options.countDown?o.options.countDownText:o.options.counterText,r=o.options.countDown?o.options.max:0,i=t("
").addClass("text-counter-div").html(e.replace("%d",''+r+"")),s=t("
").addClass(o.options.countOverflowTextCss);o.hideMessage(s),o.$container=t("<"+o.options.countContainerElement+"/>").addClass(o.options.countContainerClass).append(i).append(s),o.$text_counter=o.$container.find("span"),o.$el.after(o.$container),o.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",o.checkLimits).trigger("click.textcounter"),o.options.init(o.el)},o.checkLimits=function(e){var n=o.$el,r=(o.$container,n.val()),i=0,s=0,a=void 0!==e.originalEvent;if(t.isEmptyObject(r)||(i=o.textCount(r)),"auto"==o.options.max){var u=o.$el.attr("maxlength");void 0!==u&&!1!==u?o.options.max=u:o.$container.text("error: [maxlength] attribute not set")}if(s=o.options.countDown?o.options.max-i:i,o.setCount(s),o.options.min>0&&a&&(i=o.options.min&&(o.options.mincount(o.el),o.clearErrors("min"))),-1!==o.options.max)if(i===o.options.max&&0!==o.options.max)o.options.maxcount(o.el),o.clearErrors("max");else if(i>o.options.max&&0!==o.options.max)if(o.options.stopInputAtMaximum){var c="";if("word"==o.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=o.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=o.options.twoCharCarriageReturn?o.options.max-o.twoCharCarriageReturnCount(r):o.options.max;if(o.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),d=m.length,f=0,p=0;f'+r+""))},o.setOverflowMessage=function(){o.hideMessage(o.$container.find(".text-counter-div")),o.removeOverflowMessage();var t=o.options.countOverflowText.replace("%d",o.textCount(o.$el.val())-o.options.max).replace("%type",o.options.type),e=o.$container.find("."+o.options.countOverflowTextCss).append(t);o.showMessage(e)},o.removeOverflowMessage=function(){o.$container.find("."+o.options.countOverflowTextCss).empty()},o.showMessage=function(t){t.css("display","inline")},o.hideMessage=function(t){t.css("display","none")},o.clearErrors=function(t){var e=o.$el,n=o.$container;n.children(".error-text-"+t).remove(),0==n.children(".error-text").length&&(o.removeOverflowMessage(),o.showMessage(o.$container.find(".text-counter-div")),e.removeClass(o.options.inputErrorClass),n.removeClass(o.options.counterErrorClass))},o.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"About %d extra %type(s) have been entered",countOverflowTextCss:"text-overflow-div",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(e){return this.each(function(){new t.textcounter(this,e)})}}(jQuery); \ No newline at end of file From 4dac25904356e74c0089f3f20c83601b40d3e4a3 Mon Sep 17 00:00:00 2001 From: ractoon Date: Sun, 6 Aug 2017 18:17:39 -0600 Subject: [PATCH 19/34] Merge pull request #36, minor adjustments --- README.md | 2 +- bower.json | 2 +- package.json | 2 +- textcounter.jquery.json | 2 +- textcounter.js | 87 ++++++++++++++++++++--------------------- textcounter.min.js | 4 +- 6 files changed, 49 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 0989cc8..51cdb2f 100644 --- a/README.md +++ b/README.md @@ -159,4 +159,4 @@ init : function(el){} // Callback: function(element - [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container - [dtipson](https://github.com/dtipson) - multiple classes error fix - [jmichalicek](https://github.com/jmichalicek) - count carriage returns/newlines as 2 characters -- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix, maximum text reached condition fix \ No newline at end of file +- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix, maximum text reached condition fix, text count overflow notification \ No newline at end of file diff --git a/bower.json b/bower.json index b917ce3..0a53c10 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.6.4", + "version": "0.7.0", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 066e8bc..57a0945 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "minimum", "maximum" ], - "version": "0.6.4", + "version": "0.7.0", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index 0010d17..66a1d2c 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,7 @@ "minimum", "maximum" ], - "version": "0.6.4", + "version": "0.7.0", "author": { "name": "ractoon", "url": "http://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 29f98a6..88ac187 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.6.4 +* jQuery Text Counter Plugin v0.7.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon @@ -24,9 +24,9 @@ // append the count element var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, counterNum = base.options.countDown ? base.options.max : 0, - $formatted_counter_text = $('
').addClass('text-counter-div') + $formatted_counter_text = $('
').addClass(base.options.textCountMessage) .html(counterText.replace('%d', '' + counterNum + '')), - $count_overflow_text = $('
').addClass(base.options.countOverflowTextCss); + $count_overflow_text = $('
').addClass(base.options.countOverflowContainerClass); base.hideMessage($count_overflow_text); @@ -229,16 +229,16 @@ switch(type) { case 'min': - errorText = base.options.minimumErrorText; - break; + errorText = base.options.minimumErrorText; + break; case 'max': - errorText = base.options.maximumErrorText; + errorText = base.options.maximumErrorText; - if (base.options.countOverflow) { - base.setOverflowMessage(); - } + if (base.options.countOverflow) { + base.setOverflowMessage(); + } - break; + break; } if (base.options.displayErrorText) { @@ -249,21 +249,20 @@ }; base.setOverflowMessage = function () { - base.hideMessage(base.$container.find('.text-counter-div')); + base.hideMessage(base.$container.find('.' + base.options.textCountMessage)); base.removeOverflowMessage(); var overflowText = base.options.countOverflowText .replace('%d', base.textCount(base.$el.val()) - base.options.max) - .replace('%type', base.options.type); + .replace('%type', base.options.type + 's'); - - var overflowDiv = base.$container.find('.' + base.options.countOverflowTextCss).append(overflowText); + var overflowDiv = base.$container.find('.' + base.options.countOverflowContainerClass).append(overflowText); base.showMessage(overflowDiv); }, base.removeOverflowMessage = function () { - base.$container.find('.' + base.options.countOverflowTextCss).empty(); + base.$container.find('.' + base.options.countOverflowContainerClass).empty(); }, base.showMessage = function ($selector) { @@ -274,7 +273,6 @@ $selector.css('display', 'none'); }, - base.clearErrors = function(type) { var $this = base.$el, $countEl = base.$container; @@ -283,7 +281,7 @@ if ($countEl.children('.error-text').length == 0) { base.removeOverflowMessage(); - base.showMessage(base.$container.find('.text-counter-div')); + base.showMessage(base.$container.find('.' + base.options.textCountMessage)); $this.removeClass(base.options.inputErrorClass); $countEl.removeClass(base.options.counterErrorClass); } @@ -294,35 +292,36 @@ }; $.textcounter.defaultOptions = { - 'type' : "character", // "character" or "word" - 'min' : 0, // minimum number of characters/words - 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute - 'countContainerElement' : "div", // HTML element to wrap the text count in - 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement - 'textCountClass' : "text-count", // class applied to the counter length - 'inputErrorClass' : "error", // error class appended to the input element if error occurs - 'counterErrorClass' : "error", // error class appended to the countContainerElement if error occurs - 'counterText' : "Total Count: %d", // counter text - 'errorTextElement' : "div", // error text element - 'minimumErrorText' : "Minimum not met", // error message for minimum not met, - 'maximumErrorText' : "Maximum exceeded", // error message for maximum range exceeded, - 'displayErrorText' : true, // display error text messages for minimum/maximum values - 'stopInputAtMaximum' : true, // stop further text input if maximum reached - 'countSpaces' : false, // count spaces as character (only for "character" type) - 'countDown' : false, // if the counter should deduct from maximum characters/words rather than counting up - 'countDownText' : "Remaining: %d", // count down text - 'countExtendedCharacters' : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) - 'twoCharCarriageReturn' : false, // count carriage returns/newlines as 2 characters - 'countOverflow' : false, // count text overflow - 'countOverflowText' : "About %d extra %type(s) have been entered", // text message for count overflow - 'countOverflowTextCss' : "text-overflow-div", // css for overflow text count + 'type' : "character", // "character" or "word" + 'min' : 0, // minimum number of characters/words + 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute + 'countContainerElement' : "div", // HTML element to wrap the text count in + 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement + 'textCountMessage' : "text-count-message", // class applied to the counter message + 'textCountClass' : "text-count", // class applied to the counter length (the count number) + 'inputErrorClass' : "error", // error class appended to the input element if error occurs + 'counterErrorClass' : "error", // error class appended to the countContainerElement if error occurs + 'counterText' : "Total Count: %d", // counter text + 'errorTextElement' : "div", // error text element + 'minimumErrorText' : "Minimum not met", // error message for minimum not met, + 'maximumErrorText' : "Maximum exceeded", // error message for maximum range exceeded, + 'displayErrorText' : true, // display error text messages for minimum/maximum values + 'stopInputAtMaximum' : true, // stop further text input if maximum reached + 'countSpaces' : false, // count spaces as character (only for "character" type) + 'countDown' : false, // if the counter should deduct from maximum characters/words rather than counting up + 'countDownText' : "Remaining: %d", // count down text + 'countExtendedCharacters' : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) + 'twoCharCarriageReturn' : false, // count carriage returns/newlines as 2 characters + 'countOverflow' : false, // display text overflow element + 'countOverflowText' : "Maximum %type exceeded by %d", // count overflow text + 'countOverflowContainerClass' : "text-count-overflow-wrapper", // class applied to the count overflow wrapper // Callback API - 'maxunder' : function(el){}, // Callback: function(element) - Fires when counter under max limit - 'minunder' : function(el){}, // Callback: function(element) - Fires when counter under min limit - 'maxcount' : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count - 'mincount' : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count - 'init' : function(el){} // Callback: function(element) - Fires after the counter is initially setup + 'maxunder' : function(el){}, // Callback: function(element) - Fires when counter under max limit + 'minunder' : function(el){}, // Callback: function(element) - Fires when counter under min limit + 'maxcount' : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count + 'mincount' : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count + 'init' : function(el){} // Callback: function(element) - Fires after the counter is initially setup }; $.fn.textcounter = function(options) { diff --git a/textcounter.min.js b/textcounter.min.js index 50a0034..0310a29 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,8 +1,8 @@ /*! -* jQuery Text Counter Plugin v0.6.4 +* jQuery Text Counter Plugin v0.7.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon * Released under the MIT license */ -!function(t){t.textcounter=function(e,n){var o=this;o.$el=t(e),o.el=e,o.$el.data("textcounter",o),o.init=function(){o.options=t.extend({},t.textcounter.defaultOptions,n);var e=o.options.countDown?o.options.countDownText:o.options.counterText,r=o.options.countDown?o.options.max:0,i=t("
").addClass("text-counter-div").html(e.replace("%d",''+r+"")),s=t("
").addClass(o.options.countOverflowTextCss);o.hideMessage(s),o.$container=t("<"+o.options.countContainerElement+"/>").addClass(o.options.countContainerClass).append(i).append(s),o.$text_counter=o.$container.find("span"),o.$el.after(o.$container),o.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",o.checkLimits).trigger("click.textcounter"),o.options.init(o.el)},o.checkLimits=function(e){var n=o.$el,r=(o.$container,n.val()),i=0,s=0,a=void 0!==e.originalEvent;if(t.isEmptyObject(r)||(i=o.textCount(r)),"auto"==o.options.max){var u=o.$el.attr("maxlength");void 0!==u&&!1!==u?o.options.max=u:o.$container.text("error: [maxlength] attribute not set")}if(s=o.options.countDown?o.options.max-i:i,o.setCount(s),o.options.min>0&&a&&(i=o.options.min&&(o.options.mincount(o.el),o.clearErrors("min"))),-1!==o.options.max)if(i===o.options.max&&0!==o.options.max)o.options.maxcount(o.el),o.clearErrors("max");else if(i>o.options.max&&0!==o.options.max)if(o.options.stopInputAtMaximum){var c="";if("word"==o.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=o.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=o.options.twoCharCarriageReturn?o.options.max-o.twoCharCarriageReturnCount(r):o.options.max;if(o.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),d=m.length,f=0,p=0;f'+r+""))},o.setOverflowMessage=function(){o.hideMessage(o.$container.find(".text-counter-div")),o.removeOverflowMessage();var t=o.options.countOverflowText.replace("%d",o.textCount(o.$el.val())-o.options.max).replace("%type",o.options.type),e=o.$container.find("."+o.options.countOverflowTextCss).append(t);o.showMessage(e)},o.removeOverflowMessage=function(){o.$container.find("."+o.options.countOverflowTextCss).empty()},o.showMessage=function(t){t.css("display","inline")},o.hideMessage=function(t){t.css("display","none")},o.clearErrors=function(t){var e=o.$el,n=o.$container;n.children(".error-text-"+t).remove(),0==n.children(".error-text").length&&(o.removeOverflowMessage(),o.showMessage(o.$container.find(".text-counter-div")),e.removeClass(o.options.inputErrorClass),n.removeClass(o.options.counterErrorClass))},o.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"About %d extra %type(s) have been entered",countOverflowTextCss:"text-overflow-div",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(e){return this.each(function(){new t.textcounter(this,e)})}}(jQuery); \ No newline at end of file +!function(t){t.textcounter=function(n,o){var e=this;e.$el=t(n),e.el=n,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,o);var n=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,i=t("
").addClass(e.options.textCountMessage).html(n.replace("%d",''+r+"")),s=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(s),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(i).append(s),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(n){var o=e.$el,r=(e.$container,o.val()),i=0,s=0,a=void 0!==n.originalEvent;if(t.isEmptyObject(r)||(i=e.textCount(r)),"auto"==e.options.max){var u=e.$el.attr("maxlength");void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set")}if(s=e.options.countDown?e.options.max-i:i,e.setCount(s),e.options.min>0&&a&&(i=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(i===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(i>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=e.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,d=0,p=0;d'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessage)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),n=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(n)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var n=e.$el,o=e.$container;o.children(".error-text-"+t).remove(),0==o.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessage)),n.removeClass(e.options.inputErrorClass),o.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessage:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(n){return this.each(function(){new t.textcounter(this,n)})}}(jQuery); \ No newline at end of file From de34af847df0044834cf4f1fcf7d80aa0827f3ac Mon Sep 17 00:00:00 2001 From: ractoon Date: Sun, 6 Aug 2017 18:22:39 -0600 Subject: [PATCH 20/34] Text count message param name --- textcounter.js | 8 ++++---- textcounter.min.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/textcounter.js b/textcounter.js index 88ac187..4078a3d 100644 --- a/textcounter.js +++ b/textcounter.js @@ -24,7 +24,7 @@ // append the count element var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, counterNum = base.options.countDown ? base.options.max : 0, - $formatted_counter_text = $('
').addClass(base.options.textCountMessage) + $formatted_counter_text = $('
').addClass(base.options.textCountMessageClass) .html(counterText.replace('%d', '' + counterNum + '')), $count_overflow_text = $('
').addClass(base.options.countOverflowContainerClass); @@ -249,7 +249,7 @@ }; base.setOverflowMessage = function () { - base.hideMessage(base.$container.find('.' + base.options.textCountMessage)); + base.hideMessage(base.$container.find('.' + base.options.textCountMessageClass)); base.removeOverflowMessage(); @@ -281,7 +281,7 @@ if ($countEl.children('.error-text').length == 0) { base.removeOverflowMessage(); - base.showMessage(base.$container.find('.' + base.options.textCountMessage)); + base.showMessage(base.$container.find('.' + base.options.textCountMessageClass)); $this.removeClass(base.options.inputErrorClass); $countEl.removeClass(base.options.counterErrorClass); } @@ -297,7 +297,7 @@ 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute 'countContainerElement' : "div", // HTML element to wrap the text count in 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement - 'textCountMessage' : "text-count-message", // class applied to the counter message + 'textCountMessageClass' : "text-count-message", // class applied to the counter message 'textCountClass' : "text-count", // class applied to the counter length (the count number) 'inputErrorClass' : "error", // error class appended to the input element if error occurs 'counterErrorClass' : "error", // error class appended to the countContainerElement if error occurs diff --git a/textcounter.min.js b/textcounter.min.js index 0310a29..ad6f19f 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -5,4 +5,4 @@ * Copyright 2014 ractoon * Released under the MIT license */ -!function(t){t.textcounter=function(n,o){var e=this;e.$el=t(n),e.el=n,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,o);var n=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,i=t("
").addClass(e.options.textCountMessage).html(n.replace("%d",''+r+"")),s=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(s),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(i).append(s),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(n){var o=e.$el,r=(e.$container,o.val()),i=0,s=0,a=void 0!==n.originalEvent;if(t.isEmptyObject(r)||(i=e.textCount(r)),"auto"==e.options.max){var u=e.$el.attr("maxlength");void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set")}if(s=e.options.countDown?e.options.max-i:i,e.setCount(s),e.options.min>0&&a&&(i=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(i===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(i>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=e.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,d=0,p=0;d'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessage)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),n=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(n)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var n=e.$el,o=e.$container;o.children(".error-text-"+t).remove(),0==o.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessage)),n.removeClass(e.options.inputErrorClass),o.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessage:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(n){return this.each(function(){new t.textcounter(this,n)})}}(jQuery); \ No newline at end of file +!function(t){t.textcounter=function(n,o){var e=this;e.$el=t(n),e.el=n,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,o);var n=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,s=t("
").addClass(e.options.textCountMessageClass).html(n.replace("%d",''+r+"")),i=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(i),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(s).append(i),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(n){var o=e.$el,r=(e.$container,o.val()),s=0,i=0,a=void 0!==n.originalEvent;if(t.isEmptyObject(r)||(s=e.textCount(r)),"auto"==e.options.max){var u=e.$el.attr("maxlength");void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set")}if(i=e.options.countDown?e.options.max-s:s,e.setCount(i),e.options.min>0&&a&&(s=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(s===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(s>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=e.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,d=0,p=0;d'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessageClass)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),n=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(n)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var n=e.$el,o=e.$container;o.children(".error-text-"+t).remove(),0==o.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessageClass)),n.removeClass(e.options.inputErrorClass),o.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessageClass:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(n){return this.each(function(){new t.textcounter(this,n)})}}(jQuery); \ No newline at end of file From 2b5cc2e4cfe4fb6d8acf47f283ef3a5077f33e34 Mon Sep 17 00:00:00 2001 From: ractoon Date: Sun, 6 Aug 2017 18:26:47 -0600 Subject: [PATCH 21/34] README update --- README.md | 52 ++++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 51cdb2f..45ca221 100644 --- a/README.md +++ b/README.md @@ -109,32 +109,36 @@ Fires when counter is under min limit. ## Options ```javascript -type : "character", // "character" or "word" -min : 0, // minimum number of characters/words -max : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute -countContainerElement : "div", // HTML element to wrap the text count in -countContainerClass : "text-count-wrapper", // class applied to the countContainerElement -textCountClass : "text-count", // class applied to the counter length -inputErrorClass : "error", // error class appended to the input element if error occurs -counterErrorClass : "error", // error class appended to the countContainerElement if error occurs -counterText : "Total Count: %d", // counter text, %d replaced with count value -errorTextElement : "div", // error text element -minimumErrorText : "Minimum not met", // error message for minimum not met, -maximumErrorText : "Maximum exceeded", // error message for maximum range exceeded, -displayErrorText : true, // display error text messages for minimum/maximum values -stopInputAtMaximum : true, // stop further text input if maximum reached -countSpaces : false, // count spaces as character (only for "character" type) -countDown : false, // if the counter should deduct from maximum characters/words rather than counting up -countDownText : "Remaining: %d", // count down text, %d replaced with remaining value -countExtendedCharacters : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) -twoCharCarriageReturn : false, // count carriage returns/newlines as 2 characters +type : "character", // "character" or "word" +min : 0, // minimum number of characters/words +max : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute +countContainerElement : "div", // HTML element to wrap the text count in +countContainerClass : "text-count-wrapper", // class applied to the countContainerElement +textCountMessageClass : "text-count-message", // class applied to the counter message +textCountClass : "text-count", // class applied to the counter length (the count number) +inputErrorClass : "error", // error class appended to the input element if error occurs +counterErrorClass : "error", // error class appended to the countContainerElement if error occurs +counterText : "Total Count: %d", // counter text +errorTextElement : "div", // error text element +minimumErrorText : "Minimum not met", // error message for minimum not met, +maximumErrorText : "Maximum exceeded", // error message for maximum range exceeded, +displayErrorText : true, // display error text messages for minimum/maximum values +stopInputAtMaximum : true, // stop further text input if maximum reached +countSpaces : false, // count spaces as character (only for "character" type) +countDown : false, // if the counter should deduct from maximum characters/words rather than counting up +countDownText : "Remaining: %d", // count down text +countExtendedCharacters : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) +twoCharCarriageReturn : false, // count carriage returns/newlines as 2 characters +countOverflow : false, // display text overflow element +countOverflowText : "Maximum %type exceeded by %d", // count overflow text +countOverflowContainerClass : "text-count-overflow-wrapper", // class applied to the count overflow wrapper // Callback API -maxunder : function(el){}, // Callback: function(element) - Fires when counter is under max limit -minunder : function(el){}, // Callback: function(element) - Fires when counter is under min limit -maxcount : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count -mincount : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count -init : function(el){} // Callback: function(element) - Fires after the counter is initially setup +maxunder : function(el){}, // Callback: function(element) - Fires when counter under max limit +minunder : function(el){}, // Callback: function(element) - Fires when counter under min limit +maxcount : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count +mincount : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count +init : function(el){} // Callback: function(element) - Fires after the counter is initially setup ``` ## Development From b48d136fd8b032472be5da096e5a2ff2bf44a65d Mon Sep 17 00:00:00 2001 From: trevorloflin Date: Wed, 18 Oct 2017 16:24:36 -0700 Subject: [PATCH 22/34] Added display cutoffs. --- README.md | 2 ++ textcounter.js | 13 +++++++++++++ textcounter.min.js | 16 ++++++++-------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 45ca221..b148c87 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,8 @@ twoCharCarriageReturn : false, // count carriage countOverflow : false, // display text overflow element countOverflowText : "Maximum %type exceeded by %d", // count overflow text countOverflowContainerClass : "text-count-overflow-wrapper", // class applied to the count overflow wrapper +minDisplayCutoff : -1, // maximum number of characters/words above the minimum to display a count +maxDisplayCutoff : -1, // maximum number of characters/words below the maximum to display a count // Callback API maxunder : function(el){}, // Callback: function(element) - Fires when counter under max limit diff --git a/textcounter.js b/textcounter.js index 4078a3d..25addc6 100644 --- a/textcounter.js +++ b/textcounter.js @@ -151,6 +151,17 @@ base.clearErrors('max'); } } + + // hide the counter if it doesn't meet either the minimum or maximum display cutoff + if (base.options.minDisplayCutoff == -1 && base.options.maxDisplayCutoff == -1) { + base.$container.show(); + } else if (textCount <= base.options.min + base.options.minDisplayCutoff) { + base.$container.show(); + } else if (base.options.max !== -1 && textCount >= base.options.max - base.options.maxDisplayCutoff) { + base.$container.show(); + } else { + base.$container.hide(); + } }; base.textCount = function(text) { @@ -315,6 +326,8 @@ 'countOverflow' : false, // display text overflow element 'countOverflowText' : "Maximum %type exceeded by %d", // count overflow text 'countOverflowContainerClass' : "text-count-overflow-wrapper", // class applied to the count overflow wrapper + 'minDisplayCutoff' : -1, // maximum number of characters/words above the minimum to display a count + 'maxDisplayCutoff' : -1, // maximum number of characters/words below the maximum to display a count // Callback API 'maxunder' : function(el){}, // Callback: function(element) - Fires when counter under max limit diff --git a/textcounter.min.js b/textcounter.min.js index ad6f19f..033a9b2 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,8 +1,8 @@ -/*! -* jQuery Text Counter Plugin v0.7.0 -* https://github.com/ractoon/jQuery-Text-Counter -* -* Copyright 2014 ractoon -* Released under the MIT license -*/ -!function(t){t.textcounter=function(n,o){var e=this;e.$el=t(n),e.el=n,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,o);var n=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,s=t("
").addClass(e.options.textCountMessageClass).html(n.replace("%d",''+r+"")),i=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(i),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(s).append(i),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(n){var o=e.$el,r=(e.$container,o.val()),s=0,i=0,a=void 0!==n.originalEvent;if(t.isEmptyObject(r)||(s=e.textCount(r)),"auto"==e.options.max){var u=e.$el.attr("maxlength");void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set")}if(i=e.options.countDown?e.options.max-s:s,e.setCount(i),e.options.min>0&&a&&(s=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(s===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(s>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=e.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,d=0,p=0;d'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessageClass)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),n=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(n)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var n=e.$el,o=e.$container;o.children(".error-text-"+t).remove(),0==o.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessageClass)),n.removeClass(e.options.inputErrorClass),o.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessageClass:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(n){return this.each(function(){new t.textcounter(this,n)})}}(jQuery); \ No newline at end of file +/*! +* jQuery Text Counter Plugin v0.7.0 +* https://github.com/ractoon/jQuery-Text-Counter +* +* Copyright 2014 ractoon +* Released under the MIT license +*/ +!function(t){t.textcounter=function(o,n){var e=this;e.$el=t(o),e.el=o,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,n);var o=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,s=t("
").addClass(e.options.textCountMessageClass).html(o.replace("%d",''+r+"")),i=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(i),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(s).append(i),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(o){var n=e.$el,r=(e.$container,n.val()),s=0,i=0,a=void 0!==o.originalEvent;if(t.isEmptyObject(r)||(s=e.textCount(r)),"auto"==e.options.max){var u=e.$el.attr("maxlength");void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set")}if(i=e.options.countDown?e.options.max-s:s,e.setCount(i),e.options.min>0&&a&&(s=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(s===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(s>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=e.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,f=0,p=0;f=e.options.max-e.options.maxDisplayCutoff?e.$container.show():e.$container.hide()},e.textCount=function(t){return"word"==e.options.type?e.wordCount(t):e.characterCount(t)},e.wordCount=function(t){return t.trim().replace(/\s+/gi," ").split(" ").length},e.characterCount=function(t){var o=0,n=0;if(e.options.twoCharCarriageReturn&&(n=e.twoCharCarriageReturnCount(t)),o=e.options.countSpaces?t.replace(/[^\S\n|\r|\r\n]/g," ").length:t.replace(/\s/g,"").length,e.options.countExtendedCharacters){var r=t.match(/[^\x00-\xff]/gi);o=null==r?t.length:t.length+r.length}return e.options.twoCharCarriageReturn&&(o+=n),o},e.twoCharCarriageReturnCount=function(t){var o=t.match(/(\r\n|\n|\r)/g),n=0;return null!==o&&(n=o.length),n},e.setCount=function(t){e.$text_counter.text(t)},e.setErrors=function(t){var o=e.$el,n=e.$container,r="";switch(o.addClass(e.options.inputErrorClass),n.addClass(e.options.counterErrorClass),t){case"min":r=e.options.minimumErrorText;break;case"max":r=e.options.maximumErrorText,e.options.countOverflow&&e.setOverflowMessage()}e.options.displayErrorText&&(n.children(".error-text-"+t).length||n.append("<"+e.options.errorTextElement+' class="error-text error-text-'+t+'">'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessageClass)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),o=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(o)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var o=e.$el,n=e.$container;n.children(".error-text-"+t).remove(),0==n.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessageClass)),o.removeClass(e.options.inputErrorClass),n.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessageClass:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",minDisplayCutoff:-1,maxDisplayCutoff:-1,maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(o){return this.each(function(){new t.textcounter(this,o)})}}(jQuery); \ No newline at end of file From abc2085117f64f0367418e2403719f6f463f55c2 Mon Sep 17 00:00:00 2001 From: trevorloflin Date: Wed, 18 Oct 2017 16:39:41 -0700 Subject: [PATCH 23/34] Added attribution. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b148c87..998a40f 100644 --- a/README.md +++ b/README.md @@ -165,4 +165,5 @@ init : function(el){} // Callback: func - [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container - [dtipson](https://github.com/dtipson) - multiple classes error fix - [jmichalicek](https://github.com/jmichalicek) - count carriage returns/newlines as 2 characters -- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix, maximum text reached condition fix, text count overflow notification \ No newline at end of file +- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix, maximum text reached condition fix, text count overflow notification +- [trevorloflin](https://github.com/trevorloflin) - `minDisplayCutoff` and `maxDisplayCutoff` options \ No newline at end of file From ff15b1355862ea83a82038eb0c8f1179c0ef8f86 Mon Sep 17 00:00:00 2001 From: ractoon Date: Sun, 6 Aug 2017 18:26:47 -0600 Subject: [PATCH 24/34] README update --- textcounter.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/textcounter.js b/textcounter.js index 4078a3d..9eded5b 100644 --- a/textcounter.js +++ b/textcounter.js @@ -68,6 +68,16 @@ base.$container.text('error: [maxlength] attribute not set'); } } + else if (base.options.max == 'autocustom') { + var max = base.$el.attr(base.options.autoCustomAttr); + + if (typeof max !== 'undefined' && max !== false) { + base.options.max = max; + } + else { + base.$container.text('error: [' + base.options.autoCustomAttr + '] attribute not set'); + } + } // if this is a countdown counter deduct from the max characters/words textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; @@ -294,7 +304,8 @@ $.textcounter.defaultOptions = { 'type' : "character", // "character" or "word" 'min' : 0, // minimum number of characters/words - 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute + 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute, 'autocustom' to use a custom attribute for the length (must) + 'autoCustomAttr' : "counterlimit", // custom attribute name with the counter limit if the max is 'autocustom' 'countContainerElement' : "div", // HTML element to wrap the text count in 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement 'textCountMessageClass' : "text-count-message", // class applied to the counter message From feea47b135ef72d988fec1df29d57b66262f9bb0 Mon Sep 17 00:00:00 2001 From: ractoon Date: Sun, 6 Aug 2017 18:26:47 -0600 Subject: [PATCH 25/34] README update --- textcounter.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/textcounter.js b/textcounter.js index 4078a3d..9eded5b 100644 --- a/textcounter.js +++ b/textcounter.js @@ -68,6 +68,16 @@ base.$container.text('error: [maxlength] attribute not set'); } } + else if (base.options.max == 'autocustom') { + var max = base.$el.attr(base.options.autoCustomAttr); + + if (typeof max !== 'undefined' && max !== false) { + base.options.max = max; + } + else { + base.$container.text('error: [' + base.options.autoCustomAttr + '] attribute not set'); + } + } // if this is a countdown counter deduct from the max characters/words textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; @@ -294,7 +304,8 @@ $.textcounter.defaultOptions = { 'type' : "character", // "character" or "word" 'min' : 0, // minimum number of characters/words - 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute + 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute, 'autocustom' to use a custom attribute for the length (must) + 'autoCustomAttr' : "counterlimit", // custom attribute name with the counter limit if the max is 'autocustom' 'countContainerElement' : "div", // HTML element to wrap the text count in 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement 'textCountMessageClass' : "text-count-message", // class applied to the counter message From 0685632d3d6238b7cf203c06e762f271858ed2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Almeida?= Date: Tue, 24 Oct 2017 18:56:14 +0100 Subject: [PATCH 26/34] autocustom support --- README.md | 55 +++++++++++++++++++++++++--------------------- textcounter.js | 2 +- textcounter.min.js | 2 +- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 51cdb2f..2574036 100644 --- a/README.md +++ b/README.md @@ -109,32 +109,37 @@ Fires when counter is under min limit. ## Options ```javascript -type : "character", // "character" or "word" -min : 0, // minimum number of characters/words -max : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute -countContainerElement : "div", // HTML element to wrap the text count in -countContainerClass : "text-count-wrapper", // class applied to the countContainerElement -textCountClass : "text-count", // class applied to the counter length -inputErrorClass : "error", // error class appended to the input element if error occurs -counterErrorClass : "error", // error class appended to the countContainerElement if error occurs -counterText : "Total Count: %d", // counter text, %d replaced with count value -errorTextElement : "div", // error text element -minimumErrorText : "Minimum not met", // error message for minimum not met, -maximumErrorText : "Maximum exceeded", // error message for maximum range exceeded, -displayErrorText : true, // display error text messages for minimum/maximum values -stopInputAtMaximum : true, // stop further text input if maximum reached -countSpaces : false, // count spaces as character (only for "character" type) -countDown : false, // if the counter should deduct from maximum characters/words rather than counting up -countDownText : "Remaining: %d", // count down text, %d replaced with remaining value -countExtendedCharacters : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) -twoCharCarriageReturn : false, // count carriage returns/newlines as 2 characters +type : "character", // "character" or "word" +min : 0, // minimum number of characters/words +max : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute, 'autocustom' to use a custom attribute for the length (must set "autoCustomAttr") +autoCustomAttr : "counterlimit", // custom attribute name with the counter limit if the max is 'autocustom' +countContainerElement : "div", // HTML element to wrap the text count in +countContainerClass : "text-count-wrapper", // class applied to the countContainerElement +textCountMessageClass : "text-count-message", // class applied to the counter message +textCountClass : "text-count", // class applied to the counter length (the count number) +inputErrorClass : "error", // error class appended to the input element if error occurs +counterErrorClass : "error", // error class appended to the countContainerElement if error occurs +counterText : "Total Count: %d", // counter text +errorTextElement : "div", // error text element +minimumErrorText : "Minimum not met", // error message for minimum not met, +maximumErrorText : "Maximum exceeded", // error message for maximum range exceeded, +displayErrorText : true, // display error text messages for minimum/maximum values +stopInputAtMaximum : true, // stop further text input if maximum reached +countSpaces : false, // count spaces as character (only for "character" type) +countDown : false, // if the counter should deduct from maximum characters/words rather than counting up +countDownText : "Remaining: %d", // count down text +countExtendedCharacters : false, // count extended UTF-8 characters as 2 bytes (such as Chinese characters) +twoCharCarriageReturn : false, // count carriage returns/newlines as 2 characters +countOverflow : false, // display text overflow element +countOverflowText : "Maximum %type exceeded by %d", // count overflow text +countOverflowContainerClass : "text-count-overflow-wrapper", // class applied to the count overflow wrapper // Callback API -maxunder : function(el){}, // Callback: function(element) - Fires when counter is under max limit -minunder : function(el){}, // Callback: function(element) - Fires when counter is under min limit -maxcount : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count -mincount : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count -init : function(el){} // Callback: function(element) - Fires after the counter is initially setup +maxunder : function(el){}, // Callback: function(element) - Fires when counter under max limit +minunder : function(el){}, // Callback: function(element) - Fires when counter under min limit +maxcount : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count +mincount : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count +init : function(el){} // Callback: function(element) - Fires after the counter is initially setup ``` ## Development @@ -159,4 +164,4 @@ init : function(el){} // Callback: function(element - [juliovedovatto](https://github.com/juliovedovatto) / [alvaro-canepa](https://github.com/alvaro-canepa) - multiple classes support for counter container - [dtipson](https://github.com/dtipson) - multiple classes error fix - [jmichalicek](https://github.com/jmichalicek) - count carriage returns/newlines as 2 characters -- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix, maximum text reached condition fix, text count overflow notification \ No newline at end of file +- [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix, maximum text reached condition fix, text count overflow notification diff --git a/textcounter.js b/textcounter.js index 9eded5b..7ac76eb 100644 --- a/textcounter.js +++ b/textcounter.js @@ -304,7 +304,7 @@ $.textcounter.defaultOptions = { 'type' : "character", // "character" or "word" 'min' : 0, // minimum number of characters/words - 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute, 'autocustom' to use a custom attribute for the length (must) + 'max' : 200, // maximum number of characters/words, -1 for unlimited, 'auto' to use maxlength attribute, 'autocustom' to use a custom attribute for the length (must set "autoCustomAttr") 'autoCustomAttr' : "counterlimit", // custom attribute name with the counter limit if the max is 'autocustom' 'countContainerElement' : "div", // HTML element to wrap the text count in 'countContainerClass' : "text-count-wrapper", // class applied to the countContainerElement diff --git a/textcounter.min.js b/textcounter.min.js index ad6f19f..be6bb72 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -5,4 +5,4 @@ * Copyright 2014 ractoon * Released under the MIT license */ -!function(t){t.textcounter=function(n,o){var e=this;e.$el=t(n),e.el=n,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,o);var n=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,s=t("
").addClass(e.options.textCountMessageClass).html(n.replace("%d",''+r+"")),i=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(i),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(s).append(i),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(n){var o=e.$el,r=(e.$container,o.val()),s=0,i=0,a=void 0!==n.originalEvent;if(t.isEmptyObject(r)||(s=e.textCount(r)),"auto"==e.options.max){var u=e.$el.attr("maxlength");void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set")}if(i=e.options.countDown?e.options.max-s:s,e.setCount(i),e.options.min>0&&a&&(s=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(s===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(s>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=e.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,d=0,p=0;d'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessageClass)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),n=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(n)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var n=e.$el,o=e.$container;o.children(".error-text-"+t).remove(),0==o.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessageClass)),n.removeClass(e.options.inputErrorClass),o.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessageClass:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(n){return this.each(function(){new t.textcounter(this,n)})}}(jQuery); \ No newline at end of file +!!function(t){t.textcounter=function(o,n){var e=this;e.$el=t(o),e.el=o,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,n);var o=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,s=t("
").addClass(e.options.textCountMessageClass).html(o.replace("%d",''+r+"")),i=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(i),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(s).append(i),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(o){var n=e.$el,r=(e.$container,n.val()),s=0,i=0,a=void 0!==o.originalEvent;if(t.isEmptyObject(r)||(s=e.textCount(r)),"auto"==e.options.max)void 0!==(u=e.$el.attr("maxlength"))&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set");else if("autocustom"==e.options.max){var u=e.$el.attr(e.options.autoCustomAttr);void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: ["+e.options.autoCustomAttr+"] attribute not set")}if(i=e.options.countDown?e.options.max-s:s,e.setCount(i),e.options.min>0&&a&&(s=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(s===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(s>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=e.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var x=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,x);else for(var m=r.split(""),C=m.length,d=0,p=0;d'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessageClass)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),o=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(o)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var o=e.$el,n=e.$container;n.children(".error-text-"+t).remove(),0==n.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessageClass)),o.removeClass(e.options.inputErrorClass),n.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,autoCustomAttr:"counterlimit",countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessageClass:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(o){return this.each(function(){new t.textcounter(this,o)})}}(jQuery); From 3a88079a79de589c0dc3e9e20a141d8c2ba62710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Almeida?= Date: Tue, 24 Oct 2017 19:50:30 +0100 Subject: [PATCH 27/34] Update README.md Fix typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2574036..1022e72 100644 --- a/README.md +++ b/README.md @@ -135,8 +135,8 @@ countOverflowText : "Maximum %type exceeded by %d", // count overflow countOverflowContainerClass : "text-count-overflow-wrapper", // class applied to the count overflow wrapper // Callback API -maxunder : function(el){}, // Callback: function(element) - Fires when counter under max limit -minunder : function(el){}, // Callback: function(element) - Fires when counter under min limit +maxunder : function(el){}, // Callback: function(element) - Fires when counter is under max limit +minunder : function(el){}, // Callback: function(element) - Fires when counter is under min limit maxcount : function(el){}, // Callback: function(element) - Fires when the counter hits the maximum word/character count mincount : function(el){}, // Callback: function(element) - Fires when the counter hits the minimum word/character count init : function(el){} // Callback: function(element) - Fires after the counter is initially setup From 84d4a0663bc94a72735796fcbd0c8818fb30f53d Mon Sep 17 00:00:00 2001 From: ractoon Date: Wed, 15 Nov 2017 21:42:27 -0700 Subject: [PATCH 28/34] Version 0.8.0 Merge #37 --- bower.json | 2 +- package.json | 4 ++-- textcounter.jquery.json | 4 ++-- textcounter.js | 2 +- textcounter.min.js | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bower.json b/bower.json index 0a53c10..e4a1e27 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.7.0", + "version": "0.8.0", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 57a0945..1fb5004 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ "minimum", "maximum" ], - "version": "0.7.0", + "version": "0.8.0", "author": { "name": "ractoon", - "url": "http://www.ractoon.com" + "url": "https://www.ractoon.com" }, "licenses": [ { diff --git a/textcounter.jquery.json b/textcounter.jquery.json index 66a1d2c..ea542f7 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,10 +9,10 @@ "minimum", "maximum" ], - "version": "0.7.0", + "version": "0.8.0", "author": { "name": "ractoon", - "url": "http://www.ractoon.com" + "url": "https://www.ractoon.com" }, "licenses": [ { diff --git a/textcounter.js b/textcounter.js index 25addc6..5f90754 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.7.0 +* jQuery Text Counter Plugin v0.8.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon diff --git a/textcounter.min.js b/textcounter.min.js index 033a9b2..73ac410 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.7.0 +* jQuery Text Counter Plugin v0.8.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon From 716a1c21b989dfb6eb19287d55f50b9f2d194022 Mon Sep 17 00:00:00 2001 From: Goran Miric Date: Fri, 15 Mar 2019 12:59:30 +0100 Subject: [PATCH 29/34] 48: Accessibility - Count down remaining characters/text. --- textcounter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/textcounter.js b/textcounter.js index beb0afe..6ea021b 100644 --- a/textcounter.js +++ b/textcounter.js @@ -25,6 +25,7 @@ var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, counterNum = base.options.countDown ? base.options.max : 0, $formatted_counter_text = $('
').addClass(base.options.textCountMessageClass) + .attr('aria-live', 'assertive').attr('aria-atomic', 'true') .html(counterText.replace('%d', '' + counterNum + '')), $count_overflow_text = $('
').addClass(base.options.countOverflowContainerClass); From 5ccb0b1496218c7646ef2b333b959775d96e2f00 Mon Sep 17 00:00:00 2001 From: ractoon Date: Mon, 24 Feb 2020 20:36:37 -0700 Subject: [PATCH 30/34] Merge a11ty improvements from @goranmiric --- README.md | 1 + bower.json | 2 +- package.json | 2 +- textcounter.jquery.json | 2 +- textcounter.js | 10 +++++----- textcounter.min.js | 4 ++-- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 716a141..f296fe6 100644 --- a/README.md +++ b/README.md @@ -169,3 +169,4 @@ init : function(el){} // Callback: func - [diptopol](https://github.com/diptopol) - `stopInputAtMaximum` with `twoCharCarriageReturn` count fix, trimmed newline calculation fix, maximum text reached condition fix, text count overflow notification - [trevorloflin](https://github.com/trevorloflin) - `minDisplayCutoff` and `maxDisplayCutoff` options - [t3mujin](https://github.com/t3mujin) - autocustom support (maxlength workaround), text fixes +- [goranmiric ](https://github.com/goranmiric) - accessibility enhancements diff --git a/bower.json b/bower.json index e4a1e27..6dcf984 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.8.0", + "version": "0.9.0", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 1fb5004..3405281 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "minimum", "maximum" ], - "version": "0.8.0", + "version": "0.9.0", "author": { "name": "ractoon", "url": "https://www.ractoon.com" diff --git a/textcounter.jquery.json b/textcounter.jquery.json index ea542f7..ffe30e4 100644 --- a/textcounter.jquery.json +++ b/textcounter.jquery.json @@ -9,7 +9,7 @@ "minimum", "maximum" ], - "version": "0.8.0", + "version": "0.9.0", "author": { "name": "ractoon", "url": "https://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 6ea021b..52b3147 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.8.0 +* jQuery Text Counter Plugin v0.9.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon @@ -71,7 +71,7 @@ } else if (base.options.max == 'autocustom') { var max = base.$el.attr(base.options.autoCustomAttr); - + if (typeof max !== 'undefined' && max !== false) { base.options.max = max; } @@ -162,11 +162,11 @@ base.clearErrors('max'); } } - + // hide the counter if it doesn't meet either the minimum or maximum display cutoff if (base.options.minDisplayCutoff == -1 && base.options.maxDisplayCutoff == -1) { - base.$container.show(); - } else if (textCount <= base.options.min + base.options.minDisplayCutoff) { + base.$container.show(); + } else if (textCount <= base.options.min + base.options.minDisplayCutoff) { base.$container.show(); } else if (base.options.max !== -1 && textCount >= base.options.max - base.options.maxDisplayCutoff) { base.$container.show(); diff --git a/textcounter.min.js b/textcounter.min.js index c5d0439..33267f8 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,8 +1,8 @@ /*! -* jQuery Text Counter Plugin v0.8.0 +* jQuery Text Counter Plugin v0.9.0 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon * Released under the MIT license */ -!function(t){t.textcounter=function(o,n){var e=this;e.$el=t(o),e.el=o,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,n);var o=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,s=t("
").addClass(e.options.textCountMessageClass).html(o.replace("%d",''+r+"")),i=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(i),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(s).append(i),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(o){var n=e.$el,r=(e.$container,n.val()),s=0,i=0,a=void 0!==o.originalEvent;if(t.isEmptyObject(r)||(s=e.textCount(r)),"auto"==e.options.max)void 0!==(u=e.$el.attr("maxlength"))&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set");else if("autocustom"==e.options.max){var u=e.$el.attr(e.options.autoCustomAttr);void 0!==u&&!1!==u?e.options.max=u:e.$container.text("error: ["+e.options.autoCustomAttr+"] attribute not set")}if(i=e.options.countDown?e.options.max-s:s,e.setCount(i),e.options.min>0&&a&&(s=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(s===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(s>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var p=r.split(/[^\S\n]/g),l=0;l=e.options.max);)void 0!==p[l]&&(c+=p[l]+" ",l++);else{var m=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,m);else for(var x=r.split(""),C=x.length,f=0,l=0;f=e.options.max-e.options.maxDisplayCutoff?e.$container.show():e.$container.hide()},e.textCount=function(t){return"word"==e.options.type?e.wordCount(t):e.characterCount(t)},e.wordCount=function(t){return t.trim().replace(/\s+/gi," ").split(" ").length},e.characterCount=function(t){var o=0,n=0;if(e.options.twoCharCarriageReturn&&(n=e.twoCharCarriageReturnCount(t)),o=e.options.countSpaces?t.replace(/[^\S\n|\r|\r\n]/g," ").length:t.replace(/\s/g,"").length,e.options.countExtendedCharacters){var r=t.match(/[^\x00-\xff]/gi);o=null==r?t.length:t.length+r.length}return e.options.twoCharCarriageReturn&&(o+=n),o},e.twoCharCarriageReturnCount=function(t){var o=t.match(/(\r\n|\n|\r)/g),n=0;return null!==o&&(n=o.length),n},e.setCount=function(t){e.$text_counter.text(t)},e.setErrors=function(t){var o=e.$el,n=e.$container,r="";switch(o.addClass(e.options.inputErrorClass),n.addClass(e.options.counterErrorClass),t){case"min":r=e.options.minimumErrorText;break;case"max":r=e.options.maximumErrorText,e.options.countOverflow&&e.setOverflowMessage()}e.options.displayErrorText&&(n.children(".error-text-"+t).length||n.append("<"+e.options.errorTextElement+' class="error-text error-text-'+t+'">'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessageClass)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),o=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(o)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var o=e.$el,n=e.$container;n.children(".error-text-"+t).remove(),0==n.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessageClass)),o.removeClass(e.options.inputErrorClass),n.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,autoCustomAttr:"counterlimit",countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessageClass:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",minDisplayCutoff:-1,maxDisplayCutoff:-1,maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(o){return this.each(function(){new t.textcounter(this,o)})}}(jQuery); \ No newline at end of file +; (function ($) { $.textcounter = function (el, options) { var base = this; base.$el = $(el); base.el = el; base.$el.data('textcounter', base); base.init = function () { base.options = $.extend({}, $.textcounter.defaultOptions, options); var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, counterNum = base.options.countDown ? base.options.max : 0, $formatted_counter_text = $('
').addClass(base.options.textCountMessageClass).attr('aria-live', 'assertive').attr('aria-atomic', 'true').html(counterText.replace('%d', '' + counterNum + '')), $count_overflow_text = $('
').addClass(base.options.countOverflowContainerClass); base.hideMessage($count_overflow_text); base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).append($formatted_counter_text).append($count_overflow_text); base.$text_counter = base.$container.find('span'); base.$el.after(base.$container); base.$el.bind('keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter', base.checkLimits).trigger('click.textcounter'); base.options.init(base.el) }; base.checkLimits = function (e) { var $this = base.$el, $countEl = base.$container, $text = $this.val(), textCount = 0, textTotalCount = 0, eventTriggered = e.originalEvent === undefined ? false : true; if (!$.isEmptyObject($text)) { textCount = base.textCount($text) } if (base.options.max == 'auto') { var max = base.$el.attr('maxlength'); if (typeof max !== 'undefined' && max !== false) { base.options.max = max } else { base.$container.text('error: [maxlength] attribute not set') } } else if (base.options.max == 'autocustom') { var max = base.$el.attr(base.options.autoCustomAttr); if (typeof max !== 'undefined' && max !== false) { base.options.max = max } else { base.$container.text('error: [' + base.options.autoCustomAttr + '] attribute not set') } } textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; base.setCount(textTotalCount); if (base.options.min > 0 && eventTriggered) { if (textCount < base.options.min) { base.setErrors('min'); base.options.minunder(base.el) } else if (textCount >= base.options.min) { base.options.mincount(base.el); base.clearErrors('min') } } if (base.options.max !== -1) { if (textCount === base.options.max && base.options.max !== 0) { base.options.maxcount(base.el); base.clearErrors('max') } else if (textCount > base.options.max && base.options.max !== 0) { if (base.options.stopInputAtMaximum) { var trimmedString = ''; if (base.options.type == "word") { var wordArray = $text.split(/[^\S\n]/g); var i = 0; while (i < wordArray.length) { if (i >= base.options.max) { break } if (wordArray[i] !== undefined) { trimmedString += wordArray[i] + ' '; i += 1 } } } else { var maxLimit = (base.options.twoCharCarriageReturn) ? base.options.max - base.twoCharCarriageReturnCount($text) : base.options.max; if (base.options.countSpaces) { trimmedString = $text.substring(0, maxLimit) } else { var charArray = $text.split(''), totalCharacters = charArray.length, charCount = 0, i = 0; while (charCount < maxLimit && i < totalCharacters) { if (charArray[i] !== ' ') { charCount += 1 } trimmedString += charArray[i++] } } } $this.val(trimmedString.trim()); textCount = base.textCount($this.val()); textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; base.setCount(textTotalCount) } else { base.setErrors('max') } } else { base.options.maxunder(base.el); base.clearErrors('max') } } if (base.options.minDisplayCutoff == -1 && base.options.maxDisplayCutoff == -1) { base.$container.show() } else if (textCount <= base.options.min + base.options.minDisplayCutoff) { base.$container.show() } else if (base.options.max !== -1 && textCount >= base.options.max - base.options.maxDisplayCutoff) { base.$container.show() } else { base.$container.hide() } }; base.textCount = function (text) { var textCount = 0; if (base.options.type == "word") { textCount = base.wordCount(text) } else { textCount = base.characterCount(text) } return textCount }; base.wordCount = function (text) { return text.trim().replace(/\s+/gi, ' ').split(' ').length }; base.characterCount = function (text) { var textCount = 0, carriageReturnsCount = 0; if (base.options.twoCharCarriageReturn) { carriageReturnsCount = base.twoCharCarriageReturnCount(text) } if (base.options.countSpaces) { textCount = text.replace(/[^\S\n|\r|\r\n]/g, ' ').length } else { textCount = text.replace(/\s/g, '').length } if (base.options.countExtendedCharacters) { var extended = text.match(/[^\x00-\xff]/gi); if (extended == null) { textCount = text.length } else { textCount = text.length + extended.length } } if (base.options.twoCharCarriageReturn) { textCount += carriageReturnsCount } return textCount }; base.twoCharCarriageReturnCount = function (text) { var carriageReturns = text.match(/(\r\n|\n|\r)/g), carriageReturnsCount = 0; if (carriageReturns !== null) { carriageReturnsCount = carriageReturns.length } return carriageReturnsCount }; base.setCount = function (count) { base.$text_counter.text(count) }; base.setErrors = function (type) { var $this = base.$el, $countEl = base.$container, errorText = ''; $this.addClass(base.options.inputErrorClass); $countEl.addClass(base.options.counterErrorClass); switch (type) { case 'min': errorText = base.options.minimumErrorText; break; case 'max': errorText = base.options.maximumErrorText; if (base.options.countOverflow) { base.setOverflowMessage() } break }if (base.options.displayErrorText) { if (!$countEl.children('.error-text-' + type).length) { $countEl.append('<' + base.options.errorTextElement + ' class="error-text error-text-' + type + '">' + errorText + '') } } }; base.setOverflowMessage = function () { base.hideMessage(base.$container.find('.' + base.options.textCountMessageClass)); base.removeOverflowMessage(); var overflowText = base.options.countOverflowText.replace('%d', base.textCount(base.$el.val()) - base.options.max).replace('%type', base.options.type + 's'); var overflowDiv = base.$container.find('.' + base.options.countOverflowContainerClass).append(overflowText); base.showMessage(overflowDiv) }, base.removeOverflowMessage = function () { base.$container.find('.' + base.options.countOverflowContainerClass).empty() }, base.showMessage = function ($selector) { $selector.css('display', 'inline') }, base.hideMessage = function ($selector) { $selector.css('display', 'none') }, base.clearErrors = function (type) { var $this = base.$el, $countEl = base.$container; $countEl.children('.error-text-' + type).remove(); if ($countEl.children('.error-text').length == 0) { base.removeOverflowMessage(); base.showMessage(base.$container.find('.' + base.options.textCountMessageClass)); $this.removeClass(base.options.inputErrorClass); $countEl.removeClass(base.options.counterErrorClass) } }; base.init() }; $.textcounter.defaultOptions = { 'type': "character", 'min': 0, 'max': 200, 'autoCustomAttr': "counterlimit", 'countContainerElement': "div", 'countContainerClass': "text-count-wrapper", 'textCountMessageClass': "text-count-message", 'textCountClass': "text-count", 'inputErrorClass': "error", 'counterErrorClass': "error", 'counterText': "Total Count: %d", 'errorTextElement': "div", 'minimumErrorText': "Minimum not met", 'maximumErrorText': "Maximum exceeded", 'displayErrorText': true, 'stopInputAtMaximum': true, 'countSpaces': false, 'countDown': false, 'countDownText': "Remaining: %d", 'countExtendedCharacters': false, 'twoCharCarriageReturn': false, 'countOverflow': false, 'countOverflowText': "Maximum %type exceeded by %d", 'countOverflowContainerClass': "text-count-overflow-wrapper", 'minDisplayCutoff': -1, 'maxDisplayCutoff': -1, 'maxunder': function (el) { }, 'minunder': function (el) { }, 'maxcount': function (el) { }, 'mincount': function (el) { }, 'init': function (el) { } }; $.fn.textcounter = function (options) { return this.each(function () { new $.textcounter(this, options) }) } })(jQuery); \ No newline at end of file From 09034d524a5b758fcd959d54af818927e5dfcb11 Mon Sep 17 00:00:00 2001 From: ractoon Date: Mon, 24 Feb 2020 20:41:01 -0700 Subject: [PATCH 31/34] Remove jQuery plugin registry file jQuery plugin registry has been made read-only. New plugin releases will not be processed. --- textcounter.jquery.json | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 textcounter.jquery.json diff --git a/textcounter.jquery.json b/textcounter.jquery.json deleted file mode 100644 index ea542f7..0000000 --- a/textcounter.jquery.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "textcounter", - "title": "jQuery Text Counter", - "description": "jQuery plugin to count text/characters in a textarea or input. Allows error notifications on minimum or maximum number of characters/words.", - "keywords": [ - "words", - "characters", - "counter", - "minimum", - "maximum" - ], - "version": "0.8.0", - "author": { - "name": "ractoon", - "url": "https://www.ractoon.com" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/ractoon/jQuery-Text-Counter/blob/master/LICENSE.md" - } - ], - "bugs": "https://github.com/ractoon/jQuery-Text-Counter/issues", - "homepage": "https://github.com/ractoon/jQuery-Text-Counter", - "docs": "https://github.com/ractoon/jQuery-Text-Counter", - "dependencies": { - "jquery": ">=1.5" - } -} \ No newline at end of file From 185744d044452706b1c2e805b0cc5881546711cb Mon Sep 17 00:00:00 2001 From: Amir Meshkin Date: Wed, 10 May 2023 14:19:22 -0400 Subject: [PATCH 32/34] Change assertive to polite, no need for option. --- textcounter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/textcounter.js b/textcounter.js index 52b3147..0a6f7af 100644 --- a/textcounter.js +++ b/textcounter.js @@ -25,7 +25,7 @@ var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, counterNum = base.options.countDown ? base.options.max : 0, $formatted_counter_text = $('
').addClass(base.options.textCountMessageClass) - .attr('aria-live', 'assertive').attr('aria-atomic', 'true') + .attr('aria-live', 'polite').attr('aria-atomic', 'true') .html(counterText.replace('%d', '' + counterNum + '')), $count_overflow_text = $('
').addClass(base.options.countOverflowContainerClass); From 0cd2baa40728a7b8a4a3fab252246fccb5089cdc Mon Sep 17 00:00:00 2001 From: ractoon Date: Wed, 10 May 2023 20:15:12 -0600 Subject: [PATCH 33/34] v0.9.1 Updates --- bower.json | 2 +- package.json | 2 +- textcounter.js | 2 +- textcounter.min.js | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bower.json b/bower.json index 6dcf984..84748bf 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-text-counter", - "version": "0.9.0", + "version": "0.9.1", "main": "textcounter.js", "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 3405281..a481955 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "minimum", "maximum" ], - "version": "0.9.0", + "version": "0.9.1", "author": { "name": "ractoon", "url": "https://www.ractoon.com" diff --git a/textcounter.js b/textcounter.js index 0a6f7af..7db2a81 100644 --- a/textcounter.js +++ b/textcounter.js @@ -1,5 +1,5 @@ /*! -* jQuery Text Counter Plugin v0.9.0 +* jQuery Text Counter Plugin v0.9.1 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon diff --git a/textcounter.min.js b/textcounter.min.js index 33267f8..f7831ef 100644 --- a/textcounter.min.js +++ b/textcounter.min.js @@ -1,8 +1,8 @@ /*! -* jQuery Text Counter Plugin v0.9.0 +* jQuery Text Counter Plugin v0.9.1 * https://github.com/ractoon/jQuery-Text-Counter * * Copyright 2014 ractoon * Released under the MIT license */ -; (function ($) { $.textcounter = function (el, options) { var base = this; base.$el = $(el); base.el = el; base.$el.data('textcounter', base); base.init = function () { base.options = $.extend({}, $.textcounter.defaultOptions, options); var counterText = base.options.countDown ? base.options.countDownText : base.options.counterText, counterNum = base.options.countDown ? base.options.max : 0, $formatted_counter_text = $('
').addClass(base.options.textCountMessageClass).attr('aria-live', 'assertive').attr('aria-atomic', 'true').html(counterText.replace('%d', '' + counterNum + '')), $count_overflow_text = $('
').addClass(base.options.countOverflowContainerClass); base.hideMessage($count_overflow_text); base.$container = $('<' + base.options.countContainerElement + '/>').addClass(base.options.countContainerClass).append($formatted_counter_text).append($count_overflow_text); base.$text_counter = base.$container.find('span'); base.$el.after(base.$container); base.$el.bind('keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter', base.checkLimits).trigger('click.textcounter'); base.options.init(base.el) }; base.checkLimits = function (e) { var $this = base.$el, $countEl = base.$container, $text = $this.val(), textCount = 0, textTotalCount = 0, eventTriggered = e.originalEvent === undefined ? false : true; if (!$.isEmptyObject($text)) { textCount = base.textCount($text) } if (base.options.max == 'auto') { var max = base.$el.attr('maxlength'); if (typeof max !== 'undefined' && max !== false) { base.options.max = max } else { base.$container.text('error: [maxlength] attribute not set') } } else if (base.options.max == 'autocustom') { var max = base.$el.attr(base.options.autoCustomAttr); if (typeof max !== 'undefined' && max !== false) { base.options.max = max } else { base.$container.text('error: [' + base.options.autoCustomAttr + '] attribute not set') } } textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; base.setCount(textTotalCount); if (base.options.min > 0 && eventTriggered) { if (textCount < base.options.min) { base.setErrors('min'); base.options.minunder(base.el) } else if (textCount >= base.options.min) { base.options.mincount(base.el); base.clearErrors('min') } } if (base.options.max !== -1) { if (textCount === base.options.max && base.options.max !== 0) { base.options.maxcount(base.el); base.clearErrors('max') } else if (textCount > base.options.max && base.options.max !== 0) { if (base.options.stopInputAtMaximum) { var trimmedString = ''; if (base.options.type == "word") { var wordArray = $text.split(/[^\S\n]/g); var i = 0; while (i < wordArray.length) { if (i >= base.options.max) { break } if (wordArray[i] !== undefined) { trimmedString += wordArray[i] + ' '; i += 1 } } } else { var maxLimit = (base.options.twoCharCarriageReturn) ? base.options.max - base.twoCharCarriageReturnCount($text) : base.options.max; if (base.options.countSpaces) { trimmedString = $text.substring(0, maxLimit) } else { var charArray = $text.split(''), totalCharacters = charArray.length, charCount = 0, i = 0; while (charCount < maxLimit && i < totalCharacters) { if (charArray[i] !== ' ') { charCount += 1 } trimmedString += charArray[i++] } } } $this.val(trimmedString.trim()); textCount = base.textCount($this.val()); textTotalCount = base.options.countDown ? base.options.max - textCount : textCount; base.setCount(textTotalCount) } else { base.setErrors('max') } } else { base.options.maxunder(base.el); base.clearErrors('max') } } if (base.options.minDisplayCutoff == -1 && base.options.maxDisplayCutoff == -1) { base.$container.show() } else if (textCount <= base.options.min + base.options.minDisplayCutoff) { base.$container.show() } else if (base.options.max !== -1 && textCount >= base.options.max - base.options.maxDisplayCutoff) { base.$container.show() } else { base.$container.hide() } }; base.textCount = function (text) { var textCount = 0; if (base.options.type == "word") { textCount = base.wordCount(text) } else { textCount = base.characterCount(text) } return textCount }; base.wordCount = function (text) { return text.trim().replace(/\s+/gi, ' ').split(' ').length }; base.characterCount = function (text) { var textCount = 0, carriageReturnsCount = 0; if (base.options.twoCharCarriageReturn) { carriageReturnsCount = base.twoCharCarriageReturnCount(text) } if (base.options.countSpaces) { textCount = text.replace(/[^\S\n|\r|\r\n]/g, ' ').length } else { textCount = text.replace(/\s/g, '').length } if (base.options.countExtendedCharacters) { var extended = text.match(/[^\x00-\xff]/gi); if (extended == null) { textCount = text.length } else { textCount = text.length + extended.length } } if (base.options.twoCharCarriageReturn) { textCount += carriageReturnsCount } return textCount }; base.twoCharCarriageReturnCount = function (text) { var carriageReturns = text.match(/(\r\n|\n|\r)/g), carriageReturnsCount = 0; if (carriageReturns !== null) { carriageReturnsCount = carriageReturns.length } return carriageReturnsCount }; base.setCount = function (count) { base.$text_counter.text(count) }; base.setErrors = function (type) { var $this = base.$el, $countEl = base.$container, errorText = ''; $this.addClass(base.options.inputErrorClass); $countEl.addClass(base.options.counterErrorClass); switch (type) { case 'min': errorText = base.options.minimumErrorText; break; case 'max': errorText = base.options.maximumErrorText; if (base.options.countOverflow) { base.setOverflowMessage() } break }if (base.options.displayErrorText) { if (!$countEl.children('.error-text-' + type).length) { $countEl.append('<' + base.options.errorTextElement + ' class="error-text error-text-' + type + '">' + errorText + '') } } }; base.setOverflowMessage = function () { base.hideMessage(base.$container.find('.' + base.options.textCountMessageClass)); base.removeOverflowMessage(); var overflowText = base.options.countOverflowText.replace('%d', base.textCount(base.$el.val()) - base.options.max).replace('%type', base.options.type + 's'); var overflowDiv = base.$container.find('.' + base.options.countOverflowContainerClass).append(overflowText); base.showMessage(overflowDiv) }, base.removeOverflowMessage = function () { base.$container.find('.' + base.options.countOverflowContainerClass).empty() }, base.showMessage = function ($selector) { $selector.css('display', 'inline') }, base.hideMessage = function ($selector) { $selector.css('display', 'none') }, base.clearErrors = function (type) { var $this = base.$el, $countEl = base.$container; $countEl.children('.error-text-' + type).remove(); if ($countEl.children('.error-text').length == 0) { base.removeOverflowMessage(); base.showMessage(base.$container.find('.' + base.options.textCountMessageClass)); $this.removeClass(base.options.inputErrorClass); $countEl.removeClass(base.options.counterErrorClass) } }; base.init() }; $.textcounter.defaultOptions = { 'type': "character", 'min': 0, 'max': 200, 'autoCustomAttr': "counterlimit", 'countContainerElement': "div", 'countContainerClass': "text-count-wrapper", 'textCountMessageClass': "text-count-message", 'textCountClass': "text-count", 'inputErrorClass': "error", 'counterErrorClass': "error", 'counterText': "Total Count: %d", 'errorTextElement': "div", 'minimumErrorText': "Minimum not met", 'maximumErrorText': "Maximum exceeded", 'displayErrorText': true, 'stopInputAtMaximum': true, 'countSpaces': false, 'countDown': false, 'countDownText': "Remaining: %d", 'countExtendedCharacters': false, 'twoCharCarriageReturn': false, 'countOverflow': false, 'countOverflowText': "Maximum %type exceeded by %d", 'countOverflowContainerClass': "text-count-overflow-wrapper", 'minDisplayCutoff': -1, 'maxDisplayCutoff': -1, 'maxunder': function (el) { }, 'minunder': function (el) { }, 'maxcount': function (el) { }, 'mincount': function (el) { }, 'init': function (el) { } }; $.fn.textcounter = function (options) { return this.each(function () { new $.textcounter(this, options) }) } })(jQuery); \ No newline at end of file +!function(t){t.textcounter=function(o,n){var e=this;e.$el=t(o),e.el=o,e.$el.data("textcounter",e),e.init=function(){e.options=t.extend({},t.textcounter.defaultOptions,n);var o=e.options.countDown?e.options.countDownText:e.options.counterText,r=e.options.countDown?e.options.max:0,i=t("
").addClass(e.options.textCountMessageClass).attr("aria-live","polite").attr("aria-atomic","true").html(o.replace("%d",''+r+"")),s=t("
").addClass(e.options.countOverflowContainerClass);e.hideMessage(s),e.$container=t("<"+e.options.countContainerElement+"/>").addClass(e.options.countContainerClass).append(i).append(s),e.$text_counter=e.$container.find("span"),e.$el.after(e.$container),e.$el.bind("keyup.textcounter click.textcounter blur.textcounter focus.textcounter change.textcounter paste.textcounter",e.checkLimits).trigger("click.textcounter"),e.options.init(e.el)},e.checkLimits=function(o){var n=e.$el,r=(e.$container,n.val()),i=0,s=0,a=void 0!==o.originalEvent;if(t.isEmptyObject(r)||(i=e.textCount(r)),"auto"==e.options.max)void 0!==(u=e.$el.attr("maxlength"))&&!1!==u?e.options.max=u:e.$container.text("error: [maxlength] attribute not set");else if("autocustom"==e.options.max){var u;void 0!==(u=e.$el.attr(e.options.autoCustomAttr))&&!1!==u?e.options.max=u:e.$container.text("error: ["+e.options.autoCustomAttr+"] attribute not set")}if(s=e.options.countDown?e.options.max-i:i,e.setCount(s),e.options.min>0&&a&&(i=e.options.min&&(e.options.mincount(e.el),e.clearErrors("min"))),-1!==e.options.max)if(i===e.options.max&&0!==e.options.max)e.options.maxcount(e.el),e.clearErrors("max");else if(i>e.options.max&&0!==e.options.max)if(e.options.stopInputAtMaximum){var c="";if("word"==e.options.type)for(var l=r.split(/[^\S\n]/g),p=0;p=e.options.max);)void 0!==l[p]&&(c+=l[p]+" ",p++);else{var m=e.options.twoCharCarriageReturn?e.options.max-e.twoCharCarriageReturnCount(r):e.options.max;if(e.options.countSpaces)c=r.substring(0,m);else{var x=r.split(""),C=x.length,f=0;for(p=0;f=e.options.max-e.options.maxDisplayCutoff?e.$container.show():e.$container.hide()},e.textCount=function(t){return"word"==e.options.type?e.wordCount(t):e.characterCount(t)},e.wordCount=function(t){return t.trim().replace(/\s+/gi," ").split(" ").length},e.characterCount=function(t){var o=0,n=0;if(e.options.twoCharCarriageReturn&&(n=e.twoCharCarriageReturnCount(t)),o=e.options.countSpaces?t.replace(/[^\S\n|\r|\r\n]/g," ").length:t.replace(/\s/g,"").length,e.options.countExtendedCharacters){var r=t.match(/[^\x00-\xff]/gi);o=null==r?t.length:t.length+r.length}return e.options.twoCharCarriageReturn&&(o+=n),o},e.twoCharCarriageReturnCount=function(t){var o=t.match(/(\r\n|\n|\r)/g),n=0;return null!==o&&(n=o.length),n},e.setCount=function(t){e.$text_counter.text(t)},e.setErrors=function(t){var o=e.$el,n=e.$container,r="";switch(o.addClass(e.options.inputErrorClass),n.addClass(e.options.counterErrorClass),t){case"min":r=e.options.minimumErrorText;break;case"max":r=e.options.maximumErrorText,e.options.countOverflow&&e.setOverflowMessage()}e.options.displayErrorText&&(n.children(".error-text-"+t).length||n.append("<"+e.options.errorTextElement+' class="error-text error-text-'+t+'">'+r+""))},e.setOverflowMessage=function(){e.hideMessage(e.$container.find("."+e.options.textCountMessageClass)),e.removeOverflowMessage();var t=e.options.countOverflowText.replace("%d",e.textCount(e.$el.val())-e.options.max).replace("%type",e.options.type+"s"),o=e.$container.find("."+e.options.countOverflowContainerClass).append(t);e.showMessage(o)},e.removeOverflowMessage=function(){e.$container.find("."+e.options.countOverflowContainerClass).empty()},e.showMessage=function(t){t.css("display","inline")},e.hideMessage=function(t){t.css("display","none")},e.clearErrors=function(t){var o=e.$el,n=e.$container;n.children(".error-text-"+t).remove(),0==n.children(".error-text").length&&(e.removeOverflowMessage(),e.showMessage(e.$container.find("."+e.options.textCountMessageClass)),o.removeClass(e.options.inputErrorClass),n.removeClass(e.options.counterErrorClass))},e.init()},t.textcounter.defaultOptions={type:"character",min:0,max:200,autoCustomAttr:"counterlimit",countContainerElement:"div",countContainerClass:"text-count-wrapper",textCountMessageClass:"text-count-message",textCountClass:"text-count",inputErrorClass:"error",counterErrorClass:"error",counterText:"Total Count: %d",errorTextElement:"div",minimumErrorText:"Minimum not met",maximumErrorText:"Maximum exceeded",displayErrorText:!0,stopInputAtMaximum:!0,countSpaces:!1,countDown:!1,countDownText:"Remaining: %d",countExtendedCharacters:!1,twoCharCarriageReturn:!1,countOverflow:!1,countOverflowText:"Maximum %type exceeded by %d",countOverflowContainerClass:"text-count-overflow-wrapper",minDisplayCutoff:-1,maxDisplayCutoff:-1,maxunder:function(t){},minunder:function(t){},maxcount:function(t){},mincount:function(t){},init:function(t){}},t.fn.textcounter=function(o){return this.each((function(){new t.textcounter(this,o)}))}}(jQuery); \ No newline at end of file From 6499d0d1a86be7326412a1a4ddae52b8b6e8adb7 Mon Sep 17 00:00:00 2001 From: ractoon Date: Wed, 10 May 2023 20:19:57 -0600 Subject: [PATCH 34/34] Update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f296fe6..d7e15c6 100644 --- a/README.md +++ b/README.md @@ -170,3 +170,4 @@ init : function(el){} // Callback: func - [trevorloflin](https://github.com/trevorloflin) - `minDisplayCutoff` and `maxDisplayCutoff` options - [t3mujin](https://github.com/t3mujin) - autocustom support (maxlength workaround), text fixes - [goranmiric ](https://github.com/goranmiric) - accessibility enhancements +- [ameshkin](https://github.com/ameshkin) - accessibility adjustments \ No newline at end of file