2009-06-18 6 views
0

J'ai un problème ..jQuery: comment conserver les fonctions de l'élément, même lorsque l'élément a été supprimé et recréé?

J'utilise le plugin autocomplete, que j'édite pour faire disparaître le texte d'entrée lorsque l'utilisateur fait le choix.

Donc, mon objectif est, lorsque l'utilisateur de sélectionner une ligne dans la liste de saisie semi-automatique:

  1. Une requête Ajax récupérerait informations supplémentaires sur la ligne sélectionnée (pas de problème ici)
  2. Une forme automatique remplir avec ces informations supplémentaires (ok ici)
  3. Le texte d'entrée avec la saisie semi-automatique disparaît, et à cet endroit je place 2 div, une avec un X à l'intérieur (pour 'désélectionner' la sélection previus), et une autre avec un peu court info sur la sélection elle-même (pas de problème ici)
  4. Si l'utilisateur cliquez sur la div X, tout doit être renvoyé comme le début, avec le texte d'entrée avec saisie semi-automatique.

Qu'arrive t-il à moi, est-ce au point 4, tout fonctionne très bien, mais quand l'entrée de texte avec saisie semi-automatique est recréée par

$("div#contact-list-container").html('<input type="text" name="contact-list" id="contact-list" value="" />'); 

l'habitude autocomplete fonctionne plus! Donc, comment puis-je joindre la fonction de saisie semi-automatique au champ quand il est recréé? Afin de laisser l'utilisateur sélectionner et désélectionner plusieurs fois. Je sais que je pourrais simplement cacher la div avec le texte d'entrée et montrer celui avec le X, mais je préférerais garder le balisage html minimal et ne pas déranger avec les divs cachés. Si c'est possible, je vais changer l'innerHTML à chaque sélection et réassocier la fonction de saisie semi-automatique.

est comment mon cose est maintenant:

$(document).ready(function(){ 
    $('input#contact-list').autocomplete('test-db.php', { 
     multiple: false, 
     dataType: "json", 
     width: 400, 
     scrollHeight: 300, 
     max: 5, 
     parse: function(data) { 
      return $.map(data, function(row) { 
       return { 
        data: row, 
        value: row.azienda, 
        //result that will be used in the text field, while selected 
        result: row.code + ' - ' + row.company + ' | ' + row.name + ', ' + row.surname 
       } 
      }); 
     }, 
     formatItem: function(item) { 
      return item.code + ' - ' + item.company + '<br />' + item.name + ', ' + item.surname + '<br />' + item.email; 
     } 
    }).result(function(e, item) { 
     //this will be triggered when the selection has made 
     $.ajax({ 
      type: "POST", 
      cache: false, 
      data: "idCompany=" + item.id_company + "&idUser=" + item.id_user, 
      url: "test-db-02.php", 
      success: function(message){ 
       $("input[rel='ship']").attr("readonly", true).css("background-color", "#DFDFDF"); 
       $("input[rel='company']").attr("readonly", true).css("background-color", "#DFDFDF"); 
       var rd = json_parse(message); 

       $("input#ship-nome-referente").val(rd.company.nome); 
       $("input#ship-cognome-referente").val(rd.company.cognome); 
       //[... and so on, i change the val of many fields..] 
       //REPLACE THE INPUT-TEXT WITH THE DIVS 
       $("div#contact-list-container").html('<div id="deselect-contact">X</div><div id="selected-contact">' + rd.company.code + ' - ' + rd.company.company + ' | ' + rd.company.name + ', ' + rd.company.surname + '</div>'); 

       $("div#deselect-contact").click(function(){ 
       //REPLACE THE DIVS WITH THE INPUT-TEXT.. HOW TO REASSOCIATE THE AUTOCOMPLETE? 
        $("div#contact-list-container").html('<input type="text" name="contact-list" id="contact-list" value="" />'); 
        $("input[rel='ship']").attr("readonly", false).css("background-color", "#FFFFFF").val(''); 
        $("input[rel='company']").attr("readonly", false).css("background-color", "#FFFFFF").val(''); 
       }); 
      } 
     }); 
    }); 
}); 

Répondre

1

Depuis jQuery 1.3 l'événement live() a eu la fonctionnalité requise, ce qui vous permet de lier de façon persistante les événements aux poignées, même si les poignées sont détruites et recréées. Edit: live a été abandonné dans jQuery 1.7 et supprimé en 1.9, alors maintenant vous devriez utiliser on() à la place pour obtenir le même résultat. Pour plus de détails, voir http://api.jquery.com/on/ pour plus de détails.

1

J'ai écrit une fonction, qui associe l'autocomplétion onfocus. Ainsi, lorsque vous avez votre entrée comme ceci:

<input type="text" onfocus="attach(this);"/> 

Ou dans votre cas, ajoutez la partie onfocus à votre injection de champ de saisie:

$("div#contact-list-container").html('<input type="text" name="contact-list" id="contact-list" value="" onfocus="attach(this);"/>'); 

vous pouvez utiliser une fonction comme celle-ci, pour fixer le plugin de saisie semi-automatique. (Remarque, je définir un attribut pour éviter plusieurs pièces jointes)

function attach(element){ 

    var $element = jQuery(element); 

    // check if autocomplete was already attached 
    if($element.attr("autocomplete.attached")){ 
     return; 
    } 

    // attach autocomplete 
    $element.autocomplete(...); 

    // set a marker 
    $element.attr("autocomplete.attached", true); 
} 

Ce que je ne comprends pas: pourquoi vous ne voulez pas cacher et montrer la div?Et qu'est-ce que tu veux dire par "gâcher avec des divs cachés"?

+0

premier était becose j'ai une marge beaucoup plus complexe, et je préfère remplacer les éléments existants au lieu de changer theyr propriété ... maintenant, je compris que je suis confondais et peut-être que je vais prendre le chemin cacher/show. – Strae

0

Vous pouvez également supprimer le <input> seulement de DOM mais sans en utilisant la méthode remove() de jQuery. Cette fonction supprime l'élément de DOM mais supprime également les gestionnaires d'événements et les données attachés.

Cependant, ne pas oublier de garder référence à DIV après leur suppression. Quelque chose comme ceci:

var theField = document.getElementById('contact-list'); 
// remove it only from DOM 
theField.parentNode.removeChild(theField); 

// ... 

// and later when you want to bring the field back into the game 
$('#contact-list-container').append(theField); 

N.B. cela introduit des fuites de mémoire dans IE. Vous pouvez utiliser la fonction remove() de jQuery à la page de déchargement ou afficher et masquer le champ. Ce dernier est de loin la solution la plus propre et je ne vois pas pourquoi vous le trouvez "désordonné".

+0

Ehm ... je n'utilise pas le remove mothod, je change simplement le html dans le div avec $ ('div # mydiv'). Html (''); ;) – Strae

+0

Mais vous ne gardez pas la référence à la zone de saisie, n'est-ce pas? Le fait est que vous le réinsérez, pas en créer un nouveau –

Questions connexes