Formular dynamisch erweitern.

Sven Mintel

Mitglied
Moin Andy,

du müsstest den value des betreffenden Elementes "per Hand" löschen.

Im Falle des Textarea's sollte es mit
Code:
clone_me.getElementsByTagName('TEXTAREA')[0].value='';
gehen.
 

BQM

Grünschnabel
Hallo Sven,
vielen Dank für Deine schnelle Hilfe, funktioniert super! Danke!

Jetzt hat sich allerdings noch eine klitzekleine Frage aufgetan und zwar – ist es möglich, hier noch einen Counter einzubauen, der die Anzahl der Klon-Tabellen begrenzt? Ich stelle mir das so vor, dass nach Erreichen der z.B. zehnten Klon-Tabelle anstelle des "mehr"-Buttons der Hinweis eigeblendet wird, dass die max. Anzahl der Tabellen bzw. Artikel erreicht ist. Es müssten hier halt auch die bereits vorhanden Tabellen (Datensätze aus der DB) mit berücksichtigt werden. Das ganze mit php zu lösen wäre an sich keine große Sache, nur müsste ich hierzu das Formular jedes mal neu senden.

Vielen Dank
Andi
 

Sven Mintel

Mitglied
Jo, klar ginge das.

An die Anzahl der vorhandenen Tabellen kommst du per
Code:
document.getElementById(objid).getElementsByTagName('TABLE').length

den Button durch etwas anderes ersetzen kann man bspw. mit replaceChild()
 

BQM

Grünschnabel
Hi,

wünsche euch allen noch ein gesundes, glückliches und erfolgreiches neues Jahr und noch ein dickes Dankeschön an Sven. Leider muss ich euch nochmals um Hilfe bitten und zwar habe ich die "Klon-Tabellen" in eine weitere Tabelle gepackt, bei der man die einzelnen Zeilen nach oben bzw. nach unten verschieben kann. Man kann also die Position der geklonten Tabellen jetzt beliebig ändern. Das Ganze funktioniert soweit auch ganz gut, nur bei folgenden Dingen komm ich absolut nicht weiter:

1. Könnt ihr euch die nolink-Funktionen anschauen? Hier soll jeweils der erste "nach oben"- bzw. der letzte "nach unten"-Link in der Schleife ausgeblendet werden.

2. Bei der tr_first - u. tr_last-Funktion soll die betreffende Zeile (bzw. Tabelle) direkt an die erste bzw. letzte Position in der Schleife verschoben werden.

Und zu guter Letzt wäre da noch das Riesenproblem mit dem Text-Counter. Kann mir jemand sagen, wie ich es hinbekomme, dass alle Zeichen der "description2[]" TEXTAREAS (hier meine ich wirklich alle innerhalb der Schleife) gezählt und im input-Feld zurückgezählt werden? Beispiel: Das komp. "description2-Array" soll auf 10Tsd Zeichen beschränkt sein. Stehen nun in der Schleife 5 Klontabellen, wird das "description2-Array" ausgelesen und es sind dann sozusagen 5 d2-Textareas vorhanden. Unter jeder soll der sichtbare Zähler stehen. Wird dann z.B. in der 3. d2-Textarea was eingegeben, sollen alle d2-Zähler mit nach unten zählen, das Ganze soll also zusammengefasst sein. (Hoffe, ich hab's verständlich erklärt.)


Und ohne ScheiXX, ich sitze hier schon seit Tagen und versuche, das irgendwie hinzubekommen. Da mir allerdings nur noch zwei Tage Urlaub bleiben, überkommt mich so langsam die Panik. Wäre also wirklich SUUUPPPER, wenn ihr mir helfen könntet.


Viele Grüße

Andi


Code:
<script type="text/javascript">
<!--

function clone_this(objid){

	var clone_me = document.getElementById(objid).firstChild.cloneNode(true);
	 
	 clone_me.getElementsByTagName('TEXTAREA')[0].value='';
	 clone_me.getElementsByTagName('TEXTAREA')[1].value='';

	 document.getElementById('insert_tab').appendChild(clone_me); 

 }
 

function nolink(){

	document.getElementById('ubutt').firstChild.style.display = "none";

 }
 
 
function nolink2(){

	document.getElementById('dbutt').lastChild.style.display = "none";

 }


function tr_down(row_id){

       var table = document.getElementById('main_tab');
       var row = document.getElementById(row_id);
       var next_row = row.nextSibling;
       var next_after_row = next_row.nextSibling;
	   
       table.insertBefore(row, next_after_row);

 }
 
		
function tr_up(row_id){
				
       var table = document.getElementById('main_tab');
       var row = document.getElementById(row_id);
       var prev_row = row.previousSibling;
	   
	       while (prev_row.nodeType != 1){
		
            prev_row = prev_row.previousSilbing;
  
  			}
	   
       table.insertBefore(row, prev_row);

}


function tr_first(row_id){
				
       var table = document.getElementById('main_tab');
       var row = document.getElementById(row_id);       
       var first_row = document.getElementById(row_id).firstChild;
	   
       table.insertBefore(row, first_row);

}

function tr_last(row_id){
				
       var table = document.getElementById('main_tab');
       var row = document.getElementById(row_id);       
       var last_row = document.getElementById(row_id).lastChild.nextSibling;
       var last_after_row = last_row.nextSibling;
	   
       table.insertBefore(row, last_after_row);

}


function CountChar(desc, countfield, maxlimit){
        
        var t = document.getElementById(desc).value;
        var rest = maxlimit - t.length;
        if (t.length > maxlimit) {
          t = t.substring(0,maxlimit);}
        else
      {countfield.value = maxlimit - t.length;}
 
      }	


//-->
</script>

PHP:
$v = 0;

$form .= "<table border='1'><tbody id='main_tab'>";


for($i = 0; $i < count($description2); $i++){

$v++;


$form .= "<tr id='ctr_".$i."'><td>

<div id='new_passage'><table border='1'><tr>
	<td>Art.-Nr.: $v</td><td rowspan='2'>&nbsp;</td>
      <td><textarea name='description3a[]' rows='2'>".$description3a[$i]."</textarea></td>
	    <td rowspan='2'>
		
		<input value='Artikel löschen' onclick='op.value=\"branchartikph\";op3.value=\"del".$i."\";' type='submit'></input>
  
		<a href='#' onclick='javascript:tr_first(\"ctr_".$i."\"); nolink(); return false;' id='ubutt'>an erste Stelle</a><br>

		<a href='#' onclick='javascript:tr_last(\"ctr_".$i."\"); nolink2(); return false;' id='dbutt'>an letzte Stelle</a><br><br>		


		<a href='#' onclick='javascript:tr_up(\"ctr_".$i."\"); nolink(); return false;' id='ubutt'>nach oben</a><br>

		<a href='#' onclick='javascript:tr_down(\"ctr_".$i."\"); nolink2(); return false;' id='dbutt'>nach unten</a><br>

	</td></tr>
      <td>&nbsp;</td>
      <td><textarea cols='50' rows='5' name='description2[]' id='desc2' onkeydown='CountChar(\"desc2\",this.form.remLendesctow,10000)' onkeyup='CountChar(\"desc2\",this.form.remLendesctow,10000)'>$description2[$i]</textarea><br>Zeichen&nbsp;max.:<input class='tbox' type=box name=remLendesctow size=5 value=10000></td>
    </tr>
  </table>
</div>
  </td></tr>";
}

$form .= "</td></tr></tbody></table>

<div id='insert_tab'></div><table border='1'><tr><td>

<input value='Neuen Artikel hinzufügen' onclick='javascript:clone_this(\"new_passage\"); op.value=\"submit\";' type='submit'></input>

</td></tr></table>";
 
Zuletzt bearbeitet:
G

Gardinero

Hallo,

auf der Suche nach einem dynamischen Formular bin ich hier auf das unten stehende Skript gestossen.

Nun ist mir aufgefallen, dass es sich leider nicht so verhält, wie es soll.

Wenn man auf "weitere angeben" klickt und eine andere Gruppe auswählt, wirkt sich diese Auswahl auf den Elternknoten aus und nicht auf den Klon.

Leider bin ich noch ein absoluter Anfänger, was Javascript betrifft.

Kann mir vielleicht jemand helfen, den Fehler hier zu finden?
Oder hat jemand eine Idee, wie man ein solches Formular noch erstellen kann?

Vielleicht kennt ja einer von Euch einen Link zu einem guten Tutorial zu diesem Thema.

Vielen Dank im Voraus.

Gruß
Gardinero

Hallo zusammen!

Habe das Script mit Begeisterung gefunden und bei meinem Formular eingebaut. Nun habe ich das Problem das ich ein zweites Javascript zur dynamischen Ausgabe von weiteren Options-Feldern drin habe, welches sich nicht mit einem einfachen Clonen verträgt.

Ich werde wohl die Felder anders benennen müssen (durchnummerieren?). Hat da jemand ne Idee?:confused:

THX

HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<script type="text/javascript">

<!--

function hideSelect(obj) {

  var j;

  if ( obj.options[obj.selectedIndex].value!=0

    && document.getElementById(obj.options[obj.selectedIndex].value)

    ) {

    for (var i=0; i<obj.options.length; i++) {

      if(obj.options[i].value!=0){

        j=document.getElementById(obj.options[i].value);

        if (i == obj.selectedIndex) {

          j.style.display = 'inline';

        } else {

          if(j)

            j.style.display = 'none';

        }

      }

    }

  }

}

//-->

<!--
function clone_this(objButton)
{
if(objButton.parentNode)
    {
    tmpNode=objButton.parentNode.cloneNode(true);
    objButton.form.appendChild(tmpNode);
    for(j=0;j<objButton.form.lastChild.childNodes.length;++j)
        {
        if(objButton.form.lastChild.childNodes[j].type=='text')
            {
            objButton.form.lastChild.childNodes[j].value='';
            break;
            }
        }
    objButton.value="entfernen";
    objButton.onclick=new Function('f1','this.form.removeChild(this.parentNode)');
    }
}
//-->


</script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<style type="text/css">

body{
margin: 0;
padding: 0;
border: 0;
overflow: hidden;
height: 100%; 
max-height: 100%; 
}

#framecontent{
position: absolute; 
top: 0; 
left: 0; 
width: 100%; 
height: 130px; /*Height of frame div*/
overflow: hidden; /*Disable scrollbars. Set to "scroll" to enable*/
background-color: #FB6A00;
color: white;
}


#maincontent{
position: fixed; 
top: 130px; /*Set top value to HeightOfFrameDiv*/
left: 0;
right: 0;
bottom: 0;
overflow: auto; 
background: #fff;
}

.innertubehead{
margin: 15px; /*Margins for inner DIV inside each DIV (to provide padding)*/
font-family: Verdana, Geneva, sans-serif;
}

.innertube{
margin: 15px; /*Margins for inner DIV inside each DIV (to provide padding)*/
font-family: Verdana, Geneva, sans-serif;
font-size:12px;
}

* html body{ /*IE6 hack*/
padding: 130px 0 0 0; /*Set value to (HeightOfFrameDiv 0 0 0)*/
}

* html #maincontent{ /*IE6 hack*/
height: 100%; 
width: 100%; 
}

</style>

</head>

<body>

<div id="framecontent">
<div class="innertubehead">

<h1>TEST</h1>
</div>
</div>


<div id="maincontent">
<div class="innertube">
<form name="test" action="#" method="post">
<div>
<table width="90%" border="0" cellspacing="0" cellpadding="0">
<tr bgcolor="LightGrey">
<td>Testdaten</td>
<td>&nbsp;</td>
</tr>
  <tr>
    <td>Versicherung</td>
    <td>

  <select onchange="hideSelect(this);">

    <option value="">Bitte wählen...</option>

    <option value="gruppe1[]">G1</option>

    <option value="gruppe2[]">G2</option>

    <option value="gruppe3[]">G3</option>

  </select>

  <select id="gruppe1[]" name="gruppe1[]" style="display:none;" onchange="hideSelect(this);">

    <option value="test">test1g1</option>

    <option value="test2">test2g1</option>

    <option value="test3">test3g1</option>

  </select>

  <select id="gruppe2[]" name="gruppe2[]" style="display:none;" onchange="hideSelect(this);">

    <option value="test">test1g2</option>

    <option value="test2">test2g2</option>

    <option value="test3">test3g2</option>

  </select>

  <select id="gruppe3[]" name="gruppe3[]" style="display:none;" onchange="hideSelect(this);">

    <option value="test">test1g3</option>

    <option value="test2">test2g3</option>

    <option value="test3">test3g3</option>
  </select>
</td>
  </tr>
  <tr>
  <td>Blub</td>
  <td><select id="blub" name="blub[]">
  <option value="vid1">blub 1</option>
  <option value="vid2">blub 2</option>
  <option value="vid3">blub 3</option>
  <option value="vid4">blub 4</option>
</select>
</td>
</tr>
<tr>
<td>Kundennummer</td>
<td><input type="text" name="blubnummer[]" size="20"></td>
</tr>
<tr>
<td>
</td>
<td>&nbsp;</td>
</tr></div></div>
</table>
<input type="button" value="weiteren angeben" onclick="clone_this(this)">
</div>
</div>
</div>
da
</body>
</html>
 

metty89

Grünschnabel
Hallo zusammen,

ich hoffe, dass dieses Forum hier überhaupt noch aktiv ist, nachdem dieser Thread so lange Zeit inaktiv war. Ich habe genau das gleiche Problem wie in #70 beschrieben: Ich habe ein Webformular erstellt und einen Teil dieses Formulars geklont. Funktioniert auch super!

Nun möchte ich jedoch erreichen, dass die (eingetragenen) Inhalte des Formulars nicht mitgeklont werden, sondern die geklonten Bereiche "leer" sind. Leider hat der Vorschlag von Sven Mintel in Post #71 bei mir nicht funktioniert. Bei mir geht es nicht um Textarea-Felder, sondern mehr um "normale" Input-Felder:

<td>
<input maxlength="50" name="Telefonnummer[]" size="25" type="tel" required multiple="multiple"/>
</td>

Wie müsste ich das Script anpassen, damit die geklonten Felder nach dem klonen leer sind?

Moin Andy,

du müsstest den value des betreffenden Elementes "per Hand" löschen.

Im Falle des Textarea's sollte es mit
Code:
clone_me.getElementsByTagName('TEXTAREA')[0].value='';
gehen.
 

Quaese

Moderator
Moderator
Hi,

du kannst über alle input Felder mit dem Name Telefonnummer[] iterieren und den Wert zurücksetzen.

Beispiel:
Javascript:
Array.prototype.slice.call(clone_me.querySelectorAll('input[name="Telefonnummer[]"]')).forEach(function(input) {
    input.value = "";
})

Ciao
Quaese
 

mDie

Grünschnabel
Beispiel:
Code:
<html>
<head>
<title>Test</title>
<script type="text/javascript">
<!--
function clone_this(objButton)
{
if(objButton.parentNode)
    {
    tmpNode=objButton.parentNode.cloneNode(true);
    objButton.form.appendChild(tmpNode);
    for(j=0;j<objButton.form.lastChild.childNodes.length;++j)
        {
        if(objButton.form.lastChild.childNodes[j].type=='text')
            {
            objButton.form.lastChild.childNodes[j].value='';
            break;
            }
        }
    objButton.value="entfernen";
    objButton.onclick=new Function('f1','this.form.removeChild(this.parentNode)');
    }
}
//-->
</script>
</head>
<body>
<form>
<div>
  <input type="text"size="20"name="textfeldname[]"><br>
  <input type="button"value="noch eins"onclick="clone_this(this)">
</div>
</form>
</body>
</html>
Erläuterung:
Der Button und das Textfeld stehen in einem <div>(kann auch was anderes sein...span bspw)
Beim Aufruf wird der Funktion der Button als Objekt übergeben...dadurch hat man Zugriff auf alle seine Eigenschaften.

if(objButton.parentNode)
Abfrage, ob der Button einen Elternknoten hat...in DOM-Browsern ist dies der Fall...der Elternknoten ist das <div>

tmpNode=objButton.parentNode.cloneNode(true);
Von diesem Elternknoten wird eine Kopie erstellt

objButton.form.appendChild(tmpNode);
diese Kopie wird ans Ende des Formulars gehängt

Code:
for(j=0;j<objButton.form.lastChild.childNodes.length;++j)
        {
        if(objButton.form.lastChild.childNodes[j].type=='text')
            {
            objButton.form.lastChild.childNodes[j].value='';
            break;
            }
        }
...der Inhalt des grad erstellten Textfeldes wird gelöscht... der wurde nämlich mitgeklont :)

Danach habsch noch als Feature das Ändern des angeklickten Buttons eingefügt...sein Wert wird auf "entfernen" geändert...wenn man jetzt draufklickt, wird dieser Button incl. des dazugehörigen Textfeldes wieder gelöscht.
(kannst du natürlich rausnehmen, wenn du es nicht brauchst)

Auf das Durchnummerieren der Textfelder hab ich verzichtet....das wäre unnützer Mehraufwand.
In PHP kannst du durch die Klammer in "textfeldname[]" auch so bequem auf die Textfelddaten zugreifen.

Testbeispiel

Hallo,

ich hab bisher noch nicht so viel Erfahrung mit Java. Wenn man die input Elemente mit jeweils einem div ausgerichtet hat, funktioniert der Code leider nicht. Besteht die Möglichkeit, dass man in den Java Code nur das "Elternelement" Div anspricht? Im nachfolgenden Fall den Inhalt des div's direct nach dem form Tag.

Beispiel:

</head>
<body>
<form>
<div> //Elternelement
<div style='display:block; float:left; clear:both;'>
Eingabe:
</div>
<div style='display:block; float:left; clear:both;'>
<input type="text"size="20"name="textfeldname[]">
</div>
<div style='display:block; float:left; clear:both;'>
<input type="button"value="noch eins"onclick="clone_this(this)">
</div>
</div>
</form>
</body>
</html>
 

Quaese

Moderator
Moderator
Hi,

wenn du deinem Elternelement eine Klasse spendierst, kannst du es über diese ermitteln.
HTML:
<form>
  <div class="parentNode">
    <div style='display:block; float:left; clear:both;'>
      Eingabe:
    </div>
    <div style='display:block; float:left; clear:both;'>
      <input type="text" size="20" name="textfeldname[]">
    </div>
    <div style='display:block; float:left; clear:both;'>
      <input type="button" value="noch eins" onclick="clone_this(this)">
    </div>
  </div>
</form>

Das Javascript erweiterst du wie folgt:
Javascript:
var getParent = function(node) {
    var parent = node.parentNode,
      className = "parentNode";

    while (parent.parentNode && !parent.classList.contains(className)) {
      parent = parent.parentNode;
    }

    return parent === document ? null : parent;
  },

  clone_this = function(objButton) {
    var parent = getParent(objButton),
      tmpNode,
      children;

    if (parent) {
      tmpNode = parent.cloneNode(true);
      objButton.form.appendChild(tmpNode);
      children = objButton.form.lastChild.querySelectorAll('input');

      for (j = 0; j < children.length; ++j) {
        if (children[j].type == 'text') {
          children[j].value = '';
          break;
        }
      }

      objButton.value = "entfernen";
      objButton.onclick = function() {
        this.form.removeChild(parent);
      }
    }
  };

Ciao
Quaese
 

Neue Beiträge