2009-10-23 3 views
5

Je commence par ce balisage:Annexer plusieurs éléments à l'aide jQuery

<div> 
    <span> 
    <label for="Item[0]">Item #1</label> 
    <input type="text" value="" name="Item" id="Item[0]"/> 
    </span> 
</div> 

Sur chaque cliquez sur le bouton Je veux ajouter une autre section exactement comme celle ci-dessus mais avec un indice incrémentée.

<div> 
    <span> 
    <label for="Item[0]">Item #1</label> 
    <input type="text" value="" name="Item" id="Item[0]"/> 
    </span> 
</div> 
<div> 
    <span> 
    <label for="Item[1]">Item #2</label> 
    <input type="text" value="" name="Item" id="Item[1]"/> 
    </span> 
</div> 

Je suis en train d'utiliser ce javascript:

$(document).ready(function(){ 

    var count = <%= Items.Count - 1 %>; 

    $('#AddItem').click(function(e) { 
     e.preventDefault(); 
     count++; 

     var tb = $('#Item[0]').clone().attr('id', 'Item[' + count + ']'); 

     var label = document.createElement('label') 
     label.setAttribute('For', 'Item[' + count + ']') 

     $('#ItemFields').append(label); 
     $('#ItemFields').append(tb); 
    }); 
}); 

donc quelques questions:

Concaténer les œuvres d'étiquettes, mais mon clone textbox ne fonctionne pas.

L'étiquette n'a pas de texte. Je n'arrive pas à trouver la propriété pour ça. Quelqu'un peut-il me dire ce que c'est?

Je n'arrive pas à comprendre comment envelopper l'étiquette et la zone de texte ensemble dans un div et span. Si j'essaie

$('#ItemFields').append('<div><span>' + label + tb + '</span></div>'); 

il génère [objet HTMLLabelElement] au lieu de l'étiquette réelle. Si j'essaie de les diviser en plusieurs instructions append, il se termine automatiquement par div et span. Je suis nouveau à jQuery/Javascript, donc je ne suis pas sûr de ce que je fais mal.

Répondre

3

Exemple clonant le bloc entier (mais l'ajout d'une classe d'élément) parce que je pense qu'il est plus solide pour l'avenir (si vous modifiez le code HTML pour un élément, par exemple) et la manipulation du texte de l'étiquette:

<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    <title>Demo</title> 
    <script type="text/javascript" src="jquery-1.3.2.min.js"></script> 
    <script type="text/javascript"> 
    $(document).ready(function(){ 
    $('#AddItem').click(function(e) { 
     e.preventDefault(); 

     var count = $('.item').length; 
     var id = 'Item[' + count + ']'; 
     var item = $('.item:first').clone(); 
     item.find('input:first').attr('id', id); 
     item.find('label:first').attr('for', id) 
      .html('Item #' + (1+count)); 
     item.appendTo('#ItemFields'); 
    }); 
    }); 
    </script> 
</head> 
<body> 
    <input type="button" id="AddItem" value="Add" /> 
    <div id="ItemFields"> 
    <div class="item"> 
     <span> 
     <label for="Item[0]">Item #1</label> 
     <input type="text" value="" name="Item" id="Item[0]"/> 
     </span> 
    </div> 
    </div> 
</body> 
</html> 
+0

Cela fonctionne très bien, sauf que le nombre ne s'incrémente pas. – Brandon

+0

Oups, rien à faire. Utilisé un identifiant au lieu d'une classe sur la div. Fonctionne bien maintenant. Merci. – Brandon

+1

Oui, le nombre est le nombre d'élément avec la classe 'item'. –

5

Je pense que je trouverais un moyen d'extraire le prochain numéro à partir des numéros existants dans la marque plutôt que de compter sur la synchronisation variable. En outre, je pense que vous devez simplement imbriquer vos ajouts correctement pour obtenir le confinement que vous voulez.

$(document).ready(function(){ 

    $('#AddItem').click(function(e) { 
     var count = $('[name=Item]:last').attr('id').replace(/Item\[/,'').replace(/\]/,''); 
     count = Number(count) + 1; 

     var newItemID = 'Item[' + count + ']'; 

     var tb = $('#Item[0]').clone(); 
     tb.attr('id', newItemID); 

     var label = $('<label for="' + newItemID + '">Item #' + count + '</label>'); 

     var container = $('<div></div>'); 

     $('<span></span>').append(label) 
          .append(tb) 
          .appendTo(container); 

     $('#ItemFields').append(container); 
     return false; 
    }); 
}); 
+0

Merci pour la réponse. J'ai essayé votre code, mais il génère le balisage:

Il a une durée d'auto-terminaison et pas de zone de texte. – Brandon

+0

En outre, le compteur n'incrémente pas. Les premiers arguments du .replace devraient-ils également avoir des guillemets? – Brandon

+0

Je n'y ai pas pensé en ajoutant l'étiquette et l'entrée après la durée. J'ai mis à jour pour séparer la création de la div et span et les combiner dans le bon ordre. – tvanfosson

3

Pour commencer par « ce qui ne va pas, » vous mixez les appels DOM natifs, jQuery, et quelque chose d'autre (je n'ai aucune idée ce que <%= Items.Count - 1 %> est - PHP, peut-être). Je vais laisser ce dernier seul, car il semble que cela fonctionne pour vous. Sinon, si vous utilisez jQuery, essayez de vous en tenir à utiliser ses méthodes autant que possible. La "propriété" pour le texte de l'étiquette est juste la valeur obtenue par la méthode jQuery value().

Pour ajouter l'étiquette, je vous recommande de le faire comme:

$('#ItemFields').append('<label for=Item["' + count + ']">'+ '</label>') 

Je sais que append peut prendre du texte, un objet jQuery, ou un élément DOM, mais personnellement, je préfère tout faire avec cordes. Si vous préférez ne pas, vous pouvez le faire:

$('#ItemFields').append($('<label></label>') 
    .attr('for', 'Item["' + count + ']') 
    .value('your label text here')); 

et ainsi de suite.

La raison pour laquelle

$('#ItemFields').append('<div><span>' + label + tb + '</span></div>'); 

ne pas vous donner ce que vous voulez est que vous concaténez objets Javascript avec des cordes, qui (comme Java) permet de convertir automatiquement les objets à cordes avant concaténer.

Je laisse le reste de cette réponse incomplète puisque la réponse de tvanfosson devrait le couvrir.

+0

Merci pour la réponse. Je ne savais pas que je ne devais pas mélanger DOM natif avec Jquery, je suivais en fait cette autre question SO http://stackoverflow.com/questions/953415/how-to-dynamically-add-a-div-using -jquery en guise de guide, il utilisait Jquery mais créait les éléments en javascript régulier. – Brandon

+0

Oh, et le quelque chose d'autre était en réalité C#. – Brandon

+0

Ce n'est pas vraiment une chose "non supposée". Rien ne va vraiment casser. Cependant, il est préférable de ne pas mélanger les appels provenant de deux API différentes qui fournissent des fonctionnalités qui se chevauchent. Et si vous utilisez déjà jQuery, pourquoi ne pas le prendre aussi loin que vous le pouvez? Re: le "quelque chose d'autre" - prenez conseil de tvanfosson et calculez la valeur de 'count' en utilisant Javascript. –

1

Utilisez une fonction pour créer votre code HTML; si la structure est simple, l'assemblage comme une chaîne est plus facile:

$(document).ready(function(){ 

    var count = <%= Items.Count - 1 %>; 

    $('#AddItem').click(function(e) { 
     e.preventDefault(); 
     count++; 

     $('#ItemFields').append(create_item(count)); 
    }); 


    function create_item(i) { 
     return $(['<div><span>' 
       ,'<label for="Item[', i, ']">Item #', i, '</label>' 
       ,'<input type="text" value="" name="Item" id="Item[', i ,']"/>' 
      ,'</span></div>'].join(''), document); 
    }; 
}); 
1
var oldDiv = $('whatever');//Get div here somehow 
var newHTML = $(oldDiv).html(); 
newHTML.replace(/\[[0-9]+\]/g, '['+count+']'); 
newHTML.replace(/#[0-9]+/g, '#'+(count+1));  
var newDiv = $('<div></div>').html(newHTML); 

Cela va créer une nouvelle div, saisir le code HTML oldDiv, et effectuer deux regex remplace le [index] et #number zones. Je ne l'ai pas testé, mais il devrait fonctionner avec quelques modifications.

Questions connexes