Reputation: 11352
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, '<')
.replace(/>/g, '>')
.replace(/&/g, '&')
.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
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
Reputation: 28701
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
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, '<')
.replace(/>/g, '>')
.replace(/&/g, '&')
.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
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() {
.
$('.liveText').on('click', function() {
$('<textarea />').appendTo('#copy').autogrow();
});
Upvotes: 1