Load content dynamically with AJAX

6

I have the following HTML code:

  <label id="meuTemplate" for="criaAssoc" class="instAssoc" style="display:none">

  <strong>ID:</strong>
    <input name="idInstrucao" type="text">
  <strong>Ordem:</strong>
    <input type="text">

  <span>
    <strong class="instTxt">Instrução:</strong>
    <textarea disabled="disabled"></textarea>
  </span>

  <img src="images/1.png" title="Remover instrução" class="botaoExcluir" >

</label>

Which has the following result as in the print below:

ThroughthisJScode(below)usingjQuerywhenIclicktheplusbuttonIcanclonethelabelpassedintheHTMLabove.

//Scriptparaadicionarlabelsvarids=1;$(".btnNewInst").click(function(){
    var novoId = "lb_" + (ids++);

    var clone = $("#meuTemplate").clone();
    clone.prop("id", novoId); // É necessário mudar o id depois que se clona
    $(".instAssoc:last").after("<br>", clone);
    clone.show();

    clone.find(".botaoExcluir").click(function() {
        clone
            .prev().remove().end() // Remove também o <br>
            .remove();
    });

});

//Disparando evento click para criar a primeira label
$(".btnNewInst").click(); 

The result of cloning is this:

HoweverIuseaJScodeusingAjaxtoreadinformationfrommydatabase.But,Icannotdothislabelalabelcanonlysucceedonthefirstlabel.ThefollowingonesthatareclonedAjaxcannotrotate.AndevenifthelabelhasalreadybeenclonedbeforetheeventthattriggersAjaxistriggered,itonlyrunsonthefirstlabel.Theinformationthatwastocomeoutintheseconddoesnotcomeout,itonlymakesclonetheinformationofthefirstlabel.Hereisaprintofthesituationdescribed.

Below is the script that AJAX is in:

//Ajax para recuperar o texto da instrução passando o ID
$("input[name='idInstrucao']").focusout(function(){

    $.ajax({
        url: 'ajax/instrucaoAjax.php',
        type: 'POST',
        data: 'idInstrucao='+$(this).val(),
        beforeSend: '',
        error: function(leitura){
            $("textarea").val(leitura);
        },
        success: function(leitura){      

            if(leitura == 1){
                $("textarea").val("Esta pergunta não existe!");    
            }else{
                $("textarea").val(leitura);
            }
        }
    });

});

Any suggestions for this BUG?

Update:
I made the changes as suggested. But, the problem persists. Now it no longer replicates the result of the first label in the second. However, it does not work on the cloned label's. Look how my script was after the changes:

//Script para adicionar labels
var ids = 1;

$(".btnNewInst").click(function(){
    var novoId = "lb_" + (ids++);

    var clone = $("#meuTemplate").clone();
    clone.prop("id", novoId); // É necessário mudar o id depois que se clona
    $(".instAssoc:last").after("<br>", clone);
    clone.show();

    $(document).on('click', '.botaoExcluir', function() {
        $(this).closest('label')
            .prev().remove().end() 
            .remove();
    });

});

//Disparando evento click para criar a primeira label
$(".btnNewInst").click(); 

//Ajax para recuperar o texto da instrução passando o ID

$("input[name='idInstrucao']").focusout(function(){

    var valor = this.value;

    var self = this;

    var textArea= $(self).closest('label').find('textarea');

    $.ajax({
        url: 'ajax/instrucaoAjax.php',
        type: 'POST',
        data: 'idInstrucao='+valor,
        beforeSend: '',
        error: function(leitura){
            alert(leitura);
        },
        success: function(leitura){      

            if(leitura == 1){
                textArea.val("Esta pergunta não existe!");    
            }else{
                textArea.val(leitura);
            }
        }
    });

});
    
asked by anonymous 30.01.2014 / 23:04

1 answer

4

I think your problem is the scope / scope of this within $.ajax that is in the wrong context, pointing to the ajax function and not to the element that triggered the event.

Try this:

$("input[name='idInstrucao']").focusout(function(){
    var valor = this.value; // ou var self = this;
    $.ajax({
        url: 'ajax/instrucaoAjax.php',
        type: 'POST',
        data: 'idInstrucao='+valor , // no caso de usar self, use 'idInstrucao='self.value

In addition, if you want to reference the correct textarea , you could do this for example:

        // antes de entrar na função ajax
        var self = this;
        var textArea= $(self).closest('label').find('textarea');

        // dentro da função sucesso do ajax:
        if(leitura == 1){
            textArea.val("Esta pergunta não existe!");    
        }else{
            textArea.val(leitura);
        }

Now, another problem, or possible optimization, is this part of your code:

clone.find(".botaoExcluir").click(function() {
    clone
        .prev().remove().end() // Remove também o <br>
        .remove();
});

That seems to me to do as below and remove it from the function that generates a new clone:

$(document).on('click', '.botaoExcluir', function() {
    $(this).closest('label')
        .prev().remove().end() 
        .remove();
});

EDIT:

Two suggestions after your corrected code:

The method .clone () accepts parameters, the first is a boolean to be able to clone the events. This was missing from my answer, because without it the new input never fires focusout . So use: var clone = $("#meuTemplate").clone(true);

The second one is repeated, take this code down out of the click function, otherwise it will add multiple events. And it does not take more than once, once you're delegated:

$(document).on('click', '.botaoExcluir', function() {
    $(this).closest('label')
        .prev().remove().end() 
        .remove();
});

Full Code here

    
30.01.2014 / 23:08