2012-11-08 2 views
7

Ich muss eine "Neue Zeile hinzufügen" -Funktion in einem Formular zu implementieren. Die Struktur der Form ist so etwas wie:Klonen Sie eine <tr> und auch das Attribut name der Elemente innerhalb von 1

<table> 
<tr> 
    <td><input type="text" name="v1[label]" /></td> 
    <td><input type="text" name="v1[observation]" /></td> 
    <td><input type="text" name="v1[remarks]" /></td> 
</tr> 
<tr> 
    <td><input type="text" name="v2[label]" /></td> 
    <td><input type="text" name="v2[observation]" /></td> 
    <td><input type="text" name="v2[remarks]" /></td> 
</tr> 
<tr> 
    <td colspan="3"> 
     <input type="button" id="addrow" value="Add One More Row">&nbsp; 
     <input type="submit" name="proceed" value="Submit" /> 
    </td> 
</tr> 
</table> 

Wie zu sehen ist, wobei jede Reihe, gibt es eine Zunahme in v[] Nummer. v1, v2..and so weiter

WAS ICH SUCHE NACH

Wenn 'Add One More Row' Schaltfläche geklickt wird, sollten folgende Dinge passieren

  • Eine neue Zeile wird eingefügt über der letzten Zeile (die Zeile mit Buttons)
  • Der Name Attributwert erhöht sich um 1 (dh v2 [Label] wird v3 [Label], v2 [Beobachtung] wird v3 [Beobachtung] und so weiter) in dass Zeile

WAS habe ich versucht,

Der nächstgelegene ich kam war jQuery'sclone() verwenden. Dies fügt die Zeile perfekt hinzu. Aber ich finde es schwierig, einen Weg zu finden, den Wert des name-Attributs bei jedem Klick auf die Schaltfläche um 1 zu erhöhen.

JQuery WERDEN DERZEIT USED

$('input:button[id="addrow"]').click(function(){ 

    var secondlast = $('table tr:last').prev('tr'); 
    secondlast.clone().insertBefore(secondlast); 

}); 

Wenn ich die Taste zweimal auf, ich bin die folgende HTML immer

hinzugefügt
<tr> 
    <td><input type="text" name="v2[label]" /></td> 
    <td><input type="text" name="v2[observation]" /></td> 
    <td><input type="text" name="v2[remarks]" /></td> 
</tr> 

<tr> 
    <td><input type="text" name="v2[label]" /></td> 
    <td><input type="text" name="v2[observation]" /></td> 
    <td><input type="text" name="v2[remarks]" /></td> 
</tr> 

So eine Zeile hinzugefügt wird, aber der Name Das Attribut bleibt bei v2, während es für die dritte und vierte Zeile v3 und v4 sein sollte. Ich verstehe, clone() kann das nicht tun, und deshalb suche ich nach einer Alternative.

+0

Haben Sie versucht, den Klon Verarbeitung vor dem Einsetzen? Mit etwas wie zum Beispiel, secondlast.clone(). Jeder ('input') ', den Namen analysieren und die Nummer ersetzen? – Eregrith

+0

Hmm ..Das macht Sinn. Ich werde versuchen und sehen, ob ich das erreichen kann – asprin

+0

@Eregrith Ich bin kristallklar mit der Logik, aber es schwer zu finden, das in Programmier-Syntax zu konvertieren :( – asprin

Antwort

6
$('input:button[id="addrow"]').click(function(){ 
    var secondlast = $('table tr:last').prev('tr'); 
    var newClone = secondlast.clone(); 
    // find all the inputs within your new clone and for each one of those 
    newClone.find('input').each(function() { 
     var currentNameAttr = $(this).attr('name'); // get the current name attribute 
     // construct a new name attribute using regular expressions 
     // the match is divided into three groups (indicated by parentheses) 
     // p1 will be 'v', p2 will be the number, p3 will be the remainder of the string 
     var newNameAttr = currentNameAttr.replace(/^(v)(\d+)(.*)$/, function(match, p1, p2, p3) { 
      return p1+(parseInt(p2)+1)+p3; 
     }); 
     $(this).attr('name', newNameAttr); // set the incremented name attribute 
    }); 
    // insert after is I assume what you want 
    newClone.insertAfter(secondlast); 
}); 

bearbeiten

// you could also simply increment any digit you find as Batman indicated 
var newNameAttr = currentNameAttr.replace(/\d+/, function(match) { 
    return (parseInt(match)+1); 
}); 
+0

Dies funktioniert wie vorgesehen.Bitte geben Sie mir eine Sekunde, um damit herumspielen.Ich muss es auch mit Auswahlboxen – asprin

+0

Yep.Wir funktionieren perfekt wie vorgesehen.Ich gerade Ersetzte 'newClone.find ('input'). je (function()' with 'newClone.find ('input, select'). je (function()'. +1 und accepting as answer. Schätzen Sie auch die gelieferten Kommentare mit Ihrem Code xD – asprin

+2

+1 für die Eleganz in der Lösung. Allerdings, eine große Einschränkung zu bestätigen: [Ändern des Namens attr des geklonten Eingabeelements in jQuery funktioniert nicht in IE6/7] (http://stackoverflow.com/q/2094618/122005)? – chridam

0

Wenn Sie die Daten in diesen Eingaben an einen Server senden müssen, ist es schwierig zu bestimmen, wie viele v * Sie benötigen ... Stattdessen empfehle ich Ihnen, [] zu verwenden, um Zeilen in den Arrays hinzuzufügen.

<table> 
<tr> 
    <td><input type="text" name="v[label][]" /></td> 
    <td><input type="text" name="v[observation][]" /></td> 
    <td><input type="text" name="v[remarks][]" /></td> 
</tr> 
<tr> 
    <td><input type="text" name="v[label][]" /></td> 
    <td><input type="text" name="v[observation][]" /></td> 
    <td><input type="text" name="v[remarks][]" /></td> 
</tr> 
<tr> 
    <td colspan="3"> 
     <input type="button" id="addrow" value="Add One More Row">&nbsp; 
     <input type="submit" name="proceed" value="Submit" /> 
    </td> 
</tr> 
</table> 

Die Post Variable wird einzigartig:

Ihre HTML so aussehen würde v und es wird eine Schleife einfach durch sie die Daten zu packen, hier ist ein PHP-exemple. Diese

foreach($_POST['v']['label'] as $k=>$v){ 
    $_POST['v']['label'][$k]; // label 
    $_POST['v']['observation'][$k]; // label 
    $_POST['v']['remarks'][$k]; // label 
} 

ermöglicht eine unbegrenzte Anzahl von Eingängen, ohne Verarbeitung und Neuformatierung des Namen für jeden Klon und einfacher zu bedienen.

+0

Eigentlich der Grund, warum ich den Wert jedes Mal um 1 erhöhen möchte, ist, weil ich das Formular auf eine ähnliche Weise bearbeiten möchte, die von Ihnen aufgeführt wird. Ich werde diese als die letzte Option behalten, wenn nichts Kommt – asprin

+0

+1 das ist die gute Wahl für Probleme wie diese – amd

Verwandte Themen