Dynamic textarea when editing form

Asked

Viewed 104 times

0

I’ll try to explain my problem. Initially I consult the information, where the textarea automatically adjusts the size according to the text that returns from the database. I’m doing it this way:

$(".area").on('keyup input keypress keydown change', function(e) {
    var tamanhoMin =  $(this).attr('rows') * $(this).css('line-height').replace(/[^0-9\.]+/g, '');
    $(this).css({'height': 'auto'});
    var novoTamanho = this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"));
    if (tamanhoMin > novoTamanho) novoTamanho = tamanhoMin;
    $(this).css({'height': novoTamanho});
}).css({
    'overflow':'hidden', 
    'resize':'none'
}).delay(0).show(0, function() {
    var el = $(this);
    setTimeout(function () {
        el.trigger('keyup');
    }, 100);        
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="modal-header">   
<h4 class="modal-title">IDENTIFICAÇÃO</h4>  
<a style="float:right" type="button" name="edit" id="'.$row["codigo"].'" data-toggle="modal" href="#ad_Modaleditar" class="btn btn-primary edit_anamnese">Editar</a>					
</div>  
<form id="insert_form1">
<div class="row clearfix">
<div class="col_half">
<label>O que pode Despoletar a Crise/Descompensação</label>
<div class="textarea_field"> <span><i aria-hidden="true" class="fa fa-comment"></i></span>
<textarea style="padding-left:35px" class="form-control area" readonly="true">1
1
1
1
1
1
1
1
</textarea>
</div>
</div>
</div>
</form>

So far so good.

Then when I click the edit button opens a new form, which receives the information to be edited, but here the textarea does not automatically adjust:

<div class="col_half">
<label>O que pode Despoletar a Crise/Descompensação</label>
<div class="textarea_field"> <span><i aria-hidden="true" class="fa fa-comment"></i></span>
<textarea style="padding-left:35px" class="form-control area1" id="Despoletar" name="Despoletar"></textarea>
</div>
</div>

js:

$(".area1").on('keyup input keypress keydown change', function(e) {
var tamanhoMin1 =  $(this).attr('rows') * $(this).css('line-height').replace(/[^0-9\.]+/g, '');
$(this).css({'height': 'auto'});
var novoTamanho1 = this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"));
if (tamanhoMin1 > novoTamanho1) novoTamanho1 = tamanhoMin1;
$(this).css({'height': novoTamanho1});
}).css({
    'overflow':'hidden', 
    'resize':'none'
}).delay(0).show(0, function() {
    var el1 = $(this);
    setTimeout(function () {
        el1.trigger('keyup');
    }, 100);        
});

and stay that way:

inserir a descrição da imagem aqui

Can help identify the problem?

  • Use $(document).on('keyup input keypress keydown change', '.area1', function(e) {. I think that’s the problem. If it’s not that, give a warning here.

  • @Sam changing the line you indicated I get the error Uncaught TypeError: Cannot read property 'display' of undefined

  • True. I’ll take a look here. But, apart from this error, the textarea worked as expected?

  • @Sam, yes textarea works like mirror, but does not adjust in height

1 answer

2


The problem is that elements dynamically added to the DOM are not listened to by events already created.

You will have to use the delegated form of events through the object document:

$(document)
.on('keyup input keypress keydown change', '.area1', function(e) {
// resto do código

With this, you should use another selector with the class .area1 to fire the delay and the show:

$(".area1")
.delay(0)
.show(0, function() {
    var el1 = $(this);
    setTimeout(function () {
        el1.trigger('keyup');
    }, 100);        
});

This passage doesn’t make much sense:

.css({
    'overflow':'hidden', 
    'resize':'none'
})

Or you put it right into the CSS:

.area1{
   display: none;
   overflow: hidden;
   resize: none;
}

Or on the second dial I put up:

$(".area1")
.css({
   'overflow':'hidden', 
   'resize':'none'
})
.delay(0)
.show(0, function() {
    var el1 = $(this);
    setTimeout(function () {
        el1.trigger('keyup');
    }, 100);        
});

Only if you put in the selector, the new elements with .area1 nay will be affected. So it’s best to put right into the CSS.

The complete code will look like this:

CSS (part of .area1):

.area1{
   display: none;
   overflow: hidden;
   resize: none;
}

JS:

$(document)
.on('keyup input keypress keydown change', '.area1', function(e) {
   var tamanhoMin1 =  $(this).attr('rows') * $(this).css('line-height').replace(/[^0-9\.]+/g, '');
   $(this)
   .css({'height': 'auto'});

   var novoTamanho1 = this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"));
   if (tamanhoMin1 > novoTamanho1) novoTamanho1 = tamanhoMin1;
   $(this).css({'height': novoTamanho1});
});

$(".area1")
.delay(0)
.show(0, function() {
    var el1 = $(this);
    setTimeout(function () {
        el1.trigger('keyup');
    }, 100);        
});

Detail

When creating new textareas it is necessary to trigger the event keyup with $(".area1:last").trigger('keyup'); (fires the event in the last created textarea).

  • gets a problem, stays like the image I put in the question: link. Only adjust the textarea after having an action within the textarea, for example: click enter or put a letter. When having this action the textarea adjusts, but should adjust immediately when opening

  • Got it. You need to fire the Trigger as soon as the new textarea is added.

  • in this case how can I fire Rigger at the time I open the new form

  • Place at the end of the function that opens the new form a $(".area1:last").trigger('keyup');

Browser other questions tagged

You are not signed in. Login or sign up in order to post.