2010-12-15 137 views
0

J'ai un formulaire qui s'ouvre dans une boîte de dialogue jquery-ui, soumet via ajax, lit les données mises à jour au format json et met à jour la page. Tout fonctionne bien la première fois. Lors des exécutions suivantes, les données sont correctement mises à jour dans la base de données, mais les mises à jour sur la page sont appliquées à la même cellule que la première exécution. En utilisant "View Generated Source" dans la barre d'outils Web Developer, je peux voir que l'ancien formulaire est toujours dans le DOM. Donc, je soupçonne que ce $("form#hostEdit").find("input#id").val() soit trouve toujours la première forme, ou est en cours d'évaluation qu'une seule fois. Je suis assez nouveau à jQuery si je ne suis pas sûr de ce qu'il faut faire à ce sujet. Est-ce que ce formulaire devrait toujours être dans le DOM? Dois-je utiliser un sélecteur différent? Quelque chose d'autre complètement?problème avec la mise à jour ajax sur les utilisations suivantes

$("table.hostgrid a.new").click(function() { 
    var id = this.id.substring(3); 
    var $dialog = $('<div></div>') 
    .load('/hosts/new?byte1=${network.byte1}&byte2=${network.byte2}&byte3=${network.byte3}&byte4=' + id); 
    var getHostAction = #{jsAction @NetworkHosts.view(':id') /} 

    $dialog.dialog({ 
    autoOpen: false, 
    title: 'New host at ${network.byte1}.${network.byte2}.${network.byte3}.' + id, 
    width: 500, 
    buttons: { 
     "Create": function() { 
     $.ajax({ 
      async: true, 
      type: 'post', 
      url: '/hosts/create', 
      data: $("form#hostNew").serialize(), 
      success: function(response) { 
      $dialog.html(response); 
      if ($("div.flashSuccess") != null) { 
       $dialog.dialog('destroy'); 
       $.ajax({ 
       url: getHostAction({'id': $("form#hostEdit").find("input#id").val()}), 
       dataType: 'json', 
       success: function(data) { 
        updateHost(data); 
       }, 
       error: function(data, msg, exception) { 
        alert("Error during request: " + msg); 
       }, 
       });     
      } 
      } 
     }); 
     } 
    } 
    }); 
    $dialog.dialog('open'); 

    return false; 
}); 

fonction qui applique les mises à jour:

function updateHost(host) { 
    var cell = $("td#dot"+host.byte4); 
    cell.fadeOut("fast", function() { 
    cell.find("span.hostname").text(host.hostname).attr("title", host.description); 
    cell.removeClass().addClass(host.agegroup); 
    if (host.type) 
     cell.addClass(host.type.toLowerCase()); 
    if (host.is_dhcp) 
     cell.addClass("dhcp"); 
    if (host.is_service) 
     cell.addClass("service"); 

    cell.fadeIn("fast"); 
    }); 
} 
+0

Avez-vous une chance de reformater votre code pour n'utiliser que deux espaces pour la taille de retrait afin de le rendre plus lisible? –

+0

@Chris - c'était un peu excessif pour une raison quelconque. Mise à jour –

+0

où mettre à jour $ ("form # hostEdit"). Find ("input # id") valeur? – ifaour

Répondre

1

Vos soupçons sont corrects, $("form#hostEdit") trouve en effet le premier formulaire que vous avez chargé, ceci à cause du comportement du widget de dialogue.

Lorsque vous faites ceci: $dialog.html(response);, vous chargez cette réponse HTML dans le DOM, où l'élément de dialogue (la <div> vous avez créé) est, et quand vous faites ceci: $dialog.dialog('destroy'); vous détruisez le widget dialogue , pas le contenu dedans ... il est encore dans le DOM juste ne pas enveloppé dans ces éléments de conteneur de dialogue plus.

Pour ce que vous voulez, vous devez explicitement .remove() que le contenu vous avez chargé ainsi, comme ceci:

$dialog.dialog('destroy').remove(); 

Alors vous obtiendrez le comportement attendu, car il n'y a pas un élément avec ce double ID toujours dans le DOM.

+0

Je suppose qu'il devrait enregistrer le $ ("form # hostEdit"). Find ("entrée # id"). Val() avant de supprimer complètement le dialogue ... non? – ifaour

0

Sans voir ce que vous Updatehost fonction() le fait, il va être vraiment difficile de déterminer ce qui va mal. Y a-t-il un lien vers une version fonctionnelle sur le web?

En général, en ce qui concerne les formulaires, vous devez utiliser un ID pour vous assurer que vous avez toujours affaire à la bonne, surtout si vous en avez plus d'une sur la page. Deuxièmement, si vous essayez de remplacer le contenu de ce formulaire, alors non, vous ne devriez probablement pas en avoir deux sur la page. Vous devrez supprimer le premier et le remplacer par les données renvoyées par votre deuxième appel AJAX.

Je dois définitivement vous demander pourquoi vous avez besoin de deux appels AJAX pour accomplir tout ce que vous faites. Le backend ne devrait-il pas être en mesure d'effectuer toutes les tâches que vous effectuez dans le frontend et de simplement retourner l'information finale? De plus, si vous remplacez votre formulaire, vous devrez relier l'événement click au nouvel objet DOM en utilisant quelque chose comme live ou livequery. Les événements ne sont liés que lorsque la page est chargée.

Espérons que l'une de ces suggestions aide.

+0

J'ai posté la source de updateHost, mais c'est juste en appliquant les données json retournées, donc je ne pense pas que le problème est là. Puisque $ dialog.dialog ('destroy') 'ne supprime pas le contenu de la boîte de dialogue du DOM, y a-t-il autre chose que je devrais faire pour ne pas avoir plusieurs copies avec le même ID? –

0

Maintenant, vous pouvez créer une instance de dialogue et simplement mettre à jour son contenu ou avec votre approche après avoir détruit votre boîte de dialogue:

var id = $("form#hostEdit").find("input#id").val(); 
$dialog.remove(); 

Et puis utilisez la variable identifiant dans la prochaine demande de paiement ajax.