denislexic
denislexic

Reputation: 11352

A live autogrow textarea?

I'm also trying to understand how to make a live jquery plugin in general, and I thought this would be a good example.

This plugin that I'm trying to develop is a sort of autoGrow for textarea, which works great so far, but it won't work on live content.

http://jsfiddle.net/denislexic/cPBgG/10/

I'm guessing it's because of the each which isn't live, but I don't know how to go around it. I've been running into this problem on a regular basis and I can't find a solution.

Any help appreciated, thanks.

Here is the code

$.fn.autogrow = function(options) {
this.filter('textarea').each(function() {

    var $this       = $(this),
        minHeight   = $this.height(),
        lineHeight  = $this.css('lineHeight');

    $(this).css('height','hidden');

    var duplicate = $('<div></div>').css({
        position:   'absolute',
        top:        -10000,
        left:       -10000,
        width:      $(this).width(),
        fontSize:   $this.css('fontSize'),
        fontFamily: $this.css('fontFamily'),
        lineHeight: $this.css('lineHeight'),
        resize:     'none'
    }).appendTo(document.body);

    var update = function() {

        var val = this.value.replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/&/g, '&amp;')
            .replace(/\n/g, '<br/>');

        duplicate.html(val);
        $(this).css('height', Math.max(duplicate.height() + 20, minHeight));
    }

    $(this).change(update).keyup(update).keydown(update);

    update.apply(this);

});

return this;

}

Upvotes: 2

Views: 1683

Answers (4)

Gaucho_9
Gaucho_9

Reputation: 265

I did it this method, in jQuery.

$(name_textarea).css('overflow','hidden');

setInterval(function(){
    $(name_textarea).css('height', $(name_textarea)[0].scrollHeight+2+'px')
},100);

Try it, you can play with de number behind scrollHeight to obtain best results.

Upvotes: 0

scottm
scottm

Reputation: 28701

http://jsfiddle.net/cPBgG/18/

You should just iterate the jQuery object and not reselect it from the DOM. Also, you weren't calling autogrow() for your new text area.

Edit

You could always bind to DOMNodeInserted something like this (completely untested.):

$(document).on('DOMNodeInserted', function(e) { 
  if(e.target.classname == 'autogrow') { 
    $(e.target).autogrow();
  }
});

The point is, you are going to have to call autogrow() for your new text area.

Upvotes: 1

Marian Zburlea
Marian Zburlea

Reputation: 9427

$('.liveText').live('click',function(){
    $('<textarea />').appendTo('#copy');
    $('textarea').autogrow(); // This line was added
});

(function($) {

    $.fn.autogrow = function(options) {

        this.filter($(this).selector).each(function() {

            var $this       = $(this),
                minHeight   = $this.height(),
                lineHeight  = $this.css('lineHeight');

            $(this).css('height','hidden');

            var duplicate = $('<div></div>').css({
                position:   'absolute',
                top:        -10000,
                left:       -10000,
                width:      $(this).width(),
                fontSize:   $this.css('fontSize'),
                fontFamily: $this.css('fontFamily'),
                lineHeight: $this.css('lineHeight'),
                resize:     'none',
                'word-wrap':'break-word',
                'white-space':'pre-wrap'
            }).appendTo(document.body);

            var update = function() {

                var val = this.value.replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/&/g, '&amp;')
                    .replace(/\n/g, '<br/>');

                duplicate.html(val);
                $(this).css('height', Math.max(duplicate.height() + 20, minHeight));
            }

            $(this).change(update).keyup(update).keydown(update);

            update.apply(this);

        });

        return this;

    }

})(jQuery);
    $('textarea').autogrow()

Upvotes: 1

j08691
j08691

Reputation: 207901

I would do two things. First, apply the plugin to the newly created textareas and two, change the this.filter('textarea').each(function() { line to $(this).each(function() {.

jsFiddle example.

$('.liveText').on('click', function() {
    $('<textarea />').appendTo('#copy').autogrow();
});

Upvotes: 1

Related Questions