diff --git a/README.md b/README.md index d52c9e2..b69ff3f 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Basic usage ([Interactive Demo](http://jsfiddle.net/edelman/HrnHb/)): - `fixMinHeight`: defaults to `true`. Set to `false` if you don't want the box to stop shrinking when it hits its initial size. - `cloneClass`: defaults to `'autogrowclone'`. Helper CSS class for the clone used for measuring sizes. Use this if you need to apply special rules for a textbox that is right next to the one you're autogrowing, but not exactly it so that they are identical. - `onInitialize`: defaults to `false`. Will trigger autogrow on init. + - `onResize`: defaults to `false`. Callback function, will be executed after the resize, will be passed the `event` object and the textarea object as parameters. On init, the event is undefined. If animation is enabled, it is executed after the animation completes. Example: @@ -24,5 +25,8 @@ Example: context: $('li') , animate: false , cloneClass: 'faketextarea' + , onResize: function(event, textarea) { + 'your stuff...'; + } }; $('.mytextareas').autogrow(opts); diff --git a/autogrow.js b/autogrow.js index dbbed7b..0ed7e40 100644 --- a/autogrow.js +++ b/autogrow.js @@ -10,6 +10,7 @@ , fixMinHeight: true //if you don't want the box to shrink below its initial size , cloneClass: 'autogrowclone' //helper CSS class for clone if you need to add special rules , onInitialize: false //resizes the textareas when the plugin is initialized + , onResize: false //function to call after the textarea resizes } ; opts = $.isPlainObject(opts) ? opts : {context: opts ? opts : $(document)}; @@ -54,10 +55,17 @@ , newHeight = this.scrollHeight , minHeight = box.data('autogrow-start-height') || 0 , clone + , self = this + , executeCallback = function() { + if (typeof opts.onResize === 'function') { + opts.onResize.call(this, e, self); + } + return true; + } ; if (oldHeight < newHeight) { //user is typing this.scrollTop = 0; //try to reduce the top of the content hiding for a second - opts.animate ? box.stop().animate({height: newHeight}, opts.speed) : box.innerHeight(newHeight); + opts.animate ? box.stop().animate({height: newHeight}, opts.speed, 'swing', executeCallback) : box.innerHeight(newHeight) && executeCallback(); } else if (!e || e.which == 8 || e.which == 46 || (e.ctrlKey && e.which == 88)) { //user is deleting, backspacing, or cutting if (oldHeight > minHeight) { //shrink! //this cloning part is not particularly necessary. however, it helps with animation @@ -85,7 +93,9 @@ //if user selects all and deletes or holds down delete til beginning //user could get here and shrink whole box newHeight < minHeight && (newHeight = minHeight); - oldHeight > newHeight && opts.animate ? box.stop().animate({height: newHeight}, opts.speed) : box.innerHeight(newHeight); + oldHeight > newHeight && opts.animate ? + box.stop().animate({height: newHeight}, opts.speed, 'swing', executeCallback) : + box.innerHeight(newHeight) && executeCallback(); } else { //just set to the minHeight box.innerHeight(minHeight); } diff --git a/autogrow.min.js b/autogrow.min.js index 72a60ce..b02b0ac 100644 --- a/autogrow.min.js +++ b/autogrow.min.js @@ -15,4 +15,4 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -;(function(e){e.fn.autogrow=function(t){function s(n){var r=e(this),i=r.innerHeight(),s=this.scrollHeight,o=r.data("autogrow-start-height")||0,u;if(io){u=r.clone().addClass(t.cloneClass).css({position:"absolute",zIndex:-10,height:""}).val(r.val());r.after(u);do{s=u[0].scrollHeight-1;u.innerHeight(s)}while(s===u[0].scrollHeight);s++;u.remove();r.focus();ss&&t.animate?r.stop().animate({height:s},t.speed):r.innerHeight(s)}else{r.innerHeight(o)}}}var n=e(this).css({overflow:"hidden",resize:"none"}),r=n.selector,i={context:e(document),animate:true,speed:200,fixMinHeight:true,cloneClass:"autogrowclone",onInitialize:false};t=e.isPlainObject(t)?t:{context:t?t:e(document)};t=e.extend({},i,t);n.each(function(n,r){var i,o;r=e(r);if(r.is(":visible")||parseInt(r.css("height"),10)>0){i=parseInt(r.css("height"),10)||r.innerHeight()}else{o=r.clone().addClass(t.cloneClass).val(r.val()).css({position:"absolute",visibility:"hidden",display:"block"});e("body").append(o);i=o.innerHeight();o.remove()}if(t.fixMinHeight){r.data("autogrow-start-height",i)}r.css("height",i);if(t.onInitialize&&r.length){s.call(r[0])}});t.context.on("keyup paste",r,s);return n}})(jQuery); +;(function(e){e.fn.autogrow=function(t){function s(n){var r=e(this),i=r.innerHeight(),s=this.scrollHeight,o=r.data("autogrow-start-height")||0,u,a=this,f=function(){if(typeof t.onResize==="function"){t.onResize.call(this,n,a)}return true};if(io){u=r.clone().addClass(t.cloneClass).css({position:"absolute",zIndex:-10,height:""}).val(r.val());r.after(u);do{s=u[0].scrollHeight-1;u.innerHeight(s)}while(s===u[0].scrollHeight);s++;u.remove();r.focus();ss&&t.animate?r.stop().animate({height:s},t.speed,"swing",f):r.innerHeight(s)&&f()}else{r.innerHeight(o)}}}var n=e(this).css({overflow:"hidden",resize:"none"}),r=n.selector,i={context:e(document),animate:true,speed:200,fixMinHeight:true,cloneClass:"autogrowclone",onInitialize:false,onResize:false};t=e.isPlainObject(t)?t:{context:t?t:e(document)};t=e.extend({},i,t);n.each(function(n,r){var i,o;r=e(r);if(r.is(":visible")||parseInt(r.css("height"),10)>0){i=parseInt(r.css("height"),10)||r.innerHeight()}else{o=r.clone().addClass(t.cloneClass).val(r.val()).css({position:"absolute",visibility:"hidden",display:"block"});e("body").append(o);i=o.innerHeight();o.remove()}if(t.fixMinHeight){r.data("autogrow-start-height",i)}r.css("height",i);if(t.onInitialize&&r.length){s.call(r[0])}});t.context.on("keyup paste",r,s);return n}})(jQuery)