Created
June 13, 2014 16:14
-
-
Save dacur/feb7304f183aec72b731 to your computer and use it in GitHub Desktop.
Autogrow.js allows a textbox to grow in size vertically instead of populating a scroll bar and hiding text while you continue to type. Example below is used in conjunction with Bootstrap and AJAX. The last few lines of code reset the box size each time "submit" button is clicked; otherwise, the text box remains the last (larger) size after click…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function($){ | |
| //pass in just the context as a $(obj) or a settings JS object | |
| $.fn.autogrow = function(opts) { | |
| var that = $(this).css({overflow: 'hidden', resize: 'none'}) //prevent scrollies | |
| , selector = that.selector | |
| , defaults = { | |
| context: $(document) //what to wire events to | |
| , animate: true //if you want the size change to animate | |
| , speed: 200 //speed of animation | |
| , 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 | |
| } | |
| ; | |
| opts = $.isPlainObject(opts) ? opts : {context: opts ? opts : $(document)}; | |
| opts = $.extend({}, defaults, opts); | |
| that.each(function(i, elem){ | |
| var min, clone; | |
| elem = $(elem); | |
| //if the element is "invisible", we get an incorrect height value | |
| //to get correct value, clone and append to the body. | |
| if (elem.is(':visible') || parseInt(elem.css('height'), 10) > 0) { | |
| min = parseInt(elem.css('height'), 10) || elem.innerHeight(); | |
| } else { | |
| clone = elem.clone() | |
| .addClass(opts.cloneClass) | |
| .val(elem.val()) | |
| .css({ | |
| position: 'absolute' | |
| , visibility: 'hidden' | |
| , display: 'block' | |
| }) | |
| ; | |
| $('body').append(clone); | |
| min = clone.innerHeight(); | |
| clone.remove(); | |
| } | |
| if (opts.fixMinHeight) { | |
| elem.data('autogrow-start-height', min); //set min height | |
| } | |
| elem.css('height', min); | |
| }); | |
| opts.context | |
| .on('keyup paste', selector, resize) | |
| ; | |
| function resize (e){ | |
| var box = $(this) | |
| , oldHeight = box.innerHeight() | |
| , newHeight = this.scrollHeight | |
| , minHeight = box.data('autogrow-start-height') || 0 | |
| , clone | |
| ; | |
| 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); | |
| } else if (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 | |
| //since the only way to cleanly calculate where to shrink the box to is to incrementally | |
| //reduce the height of the box until the $.innerHeight() and the scrollHeight differ. | |
| //doing this on an exact clone to figure out the height first and then applying it to the | |
| //actual box makes it look cleaner to the user | |
| clone = box.clone() | |
| .addClass(opts.cloneClass) //add clone class for extra css rules | |
| .css({position: 'absolute', zIndex:-10}) //make "invisible" | |
| .val(box.val()) //populate with content for consistent measuring | |
| ; | |
| box.after(clone); //append as close to the box as possible for best CSS matching for clone | |
| do { //reduce height until they don't match | |
| newHeight = clone[0].scrollHeight - 1; | |
| clone.innerHeight(newHeight); | |
| } while (newHeight === clone[0].scrollHeight); | |
| newHeight++; //adding one back eliminates a wiggle on deletion | |
| clone.remove(); | |
| //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); | |
| } else { //just set to the minHeight | |
| box.innerHeight(minHeight); | |
| } | |
| } | |
| } | |
| } | |
| })(jQuery); | |
| $('textarea#comment_comment').autogrow(); //This line calls autogrow on the textbox | |
| //This code below resets the textbox height to 50px after each click/submit of comment/holler | |
| //Without this code, the textbox does not reset size and remains the larger size (whatever size | |
| //it 'autogrew' to be while you type the comment). Comments are added to page via AJAX call. | |
| $(document).ready(function() { | |
| function textarea_reset() { | |
| $('textarea#comment_comment').attr("style", "height: 50px") | |
| } | |
| $('#btn-holler').on('click', textarea_reset); | |
| }); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment