Form-Input-Array hinzufügen

Mark

Cinema4D
Hi Ihr Lieben!

Ich habe eine Form, erzeugt mithilfe von Smarty, die mehrere Datensätze mit jeweils mehreren Daten anzeigt. Die Daten werden dabei einem zweidimensionalen Array zugewiesen, z.B.:
HTML:
{foreach from=$media item=med name=media}
<input type="hidden" name="media[{$med.id}][id]" value="{$med.id}" />
<input type="text" name="media[{$med.id}][titel]" value="{$med.titel}" />
{/foreach}
Nun möchte ich weitere Felder mittels Javascript hinzufügen können. Dies geschieht über appendChild der obigen Input-Felder.
Nun haben diese Felder aber ja noch keine id für die erste Dimension des Arrays.
Frage: wie kann ich "on the fly" multidimensionale Arrays erzeugen lassen?
Mein Wunsch:
HTML:
<input type="hidden" name="media[][id]" value="" />
<input type="text" name="media[][titel]" value="" />

<input type="hidden" name="media[][id]" value="" />
<input type="text" name="media[][titel]" value="" />
...also pro Datensatz wird ein Array erzeugt, Input-Name stellt die zweite Dimension dar. Beim Beispiel wird allerdings die erste Dimension des Arrays ja bei jedem Input erweitert: media[0][id], media[1][title], media[2][id], media[3][titel]. Ich hätte gerne media[0][id], media[0][title], media[1][id], media[1][titel].
Oder stelle ich mir das zu einfach vor?!

Verzeiht, wenn ich das alles so kompliziert beschreibe, mir fehlen nach wie vor noch die Fachbegriffe ;)
Vielen Dank schon mal für jegliche Hilfe,
Liebe Grüße,
Mark.

//edit: um Mißverständnisse auszuschließen: neben dem "titel" gibt es noch mehr Input-Felder, ansonsten wäre ja ein eindimensionales Array ausreichend ;)
 
Wozu überhaupt zusätzlich die ID übergeben, wenn sie entweder noch gar nicht feststeht (neuer Datensatz) oder bereits durch den Schlüssel übergeben wird?
 
Hi Gumbo!
Wozu überhaupt zusätzlich die ID übergeben, wenn sie entweder noch gar nicht feststeht (neuer Datensatz) oder bereits durch den Schlüssel übergeben wird?
Das ergab sich beim Finden einer Lösung für die "Array-Erweiterung".
Ich möchte per
Code:
foreach($_POST["media"] as $media)" jeden Datensatz und folgend "$media["id"], $media["titel"]
verwenden können.
Dabei benötige ich die id nicht als erste Dimension des Arrays. Ich weiß aber nicht, wie ich in der Form nur die erste Dimension pro Datensatz erweitere (siehe oben zweiter Html-Code), deshalb der Weg über "die id als erst 1.Dimension" ... mir wäre es wurscht ;)

Grüße,
Mark.
 
Vielleicht hast du meine Aussage etwas missverstanden. Wenn es nur jeweils ein Formularelement gibt, wird keine ID zur Identifizierung von zusammengehörigen Elementen benötigt, da die Gruppe ja nur aus jeweils einem Wert bestünde.
Wenn es jedoch mehrere Formularelemente sind, die es zu gruppieren gilt, müsstest du mit einem zusätzlichen künstlichen Schlüssel arbeiten.
 
Hi Gumbo!
Wenn es jedoch mehrere Formularelemente sind, die es zu gruppieren gilt, müsstest du mit einem zusätzlichen künstlichen Schlüssel arbeiten.
Ja, und eben diesen zusätzlichen künstlichen Schlüssel hätte ich gerne "on the fly", einem "push" ähnlich ;)
Mit "<input type='text' name='test[]' />" wird doch das Array 'test' bei jedem 'input' um einen Eintrag erweitert. Genau das hätte ich nun gerne für ein zweidimensionales Array, wobei das Array 'media' zunächst erweitert wird (media[]) und folgend mit den Daten eines Datensatzes als Unterarray befüllt wird (media[][title], media[][nochwas], media[][undnochetwas]).
"On the fly" deshalb, da per Javascript weitere leere Datensätze hinzugefügt werden können und ich mich dort nicht um den Schlüssel des Hauptarrays kümmern möchte.

Wahrscheinlich verlange ich da aber zuviel und so scheint mir die einzige Möglichkeit zu sein: den Hauptschlüssel mittels Javascript jeweils zu eruiren, daß JS z.B. "<input type='text' name='media[neu1][titel]' />", ..., "<input type='text' name='media[neu2][titel]' />" generiert... :(

...oder habe ich Dich immer noch mißverstanden? :(

Liebe Grüße,
Mark.
 
Wahrscheinlich verlange ich da aber zuviel und so scheint mir die einzige Möglichkeit zu sein: den Hauptschlüssel mittels Javascript jeweils zu eruiren, daß JS z.B. "<input type='text' name='media[neu1][titel]' />", ..., "<input type='text' name='media[neu2][titel]' />" generiert... :(

Nicht die einzigste Möglichkeit, aber eine, und wahrscheinlich eine sinnvolle, falls die IDs der vorhandenen Elemente numerisch sind(was ich mal annehme)...und du nicht Gefahr laufen willst, dass durch einen neuen Datensatz ein vorhandener überschrieben wird.

Hier mal nen Beispiel:
PHP:
<html>
<head>
<title>Test</title>
<script type="text/javascript">
<!--
j=0;
function clone(o,p)
{
    n=o.cloneNode(true);
    a=o.getElementsByTagName('INPUT');
    for(e=0;e<a.length;++e)
      {
        
        a[e].setAttribute('name',String(a[e].name).replace(/media\[[^\]]+\]/g,'media['+p+j+']'));
        a[e].value='';
      }
    j++;
    o.parentNode.insertBefore(n,o); 
}
//-->
</script>
</head>
<body>
<?php
if(isset($_POST['media']))
  {
    echo '<pre>'.print_r($_POST['media'],true).'</pre>';
  }
?>
<form method="post">
  <div>
    <input type="hidden" name="media[0815][id]" value="0815" />
    <input type="text" name="media[0815][titel]" value="der Titel" />
  </div>
  <input type="button" onclick="clone(this.previousSibling,'neuerDatensatz_')" value="neuer Datensatz">
  <input type="submit">
</form>

</body>
</html>

Eine andere Variante wäre dies(wahrscheinlich das, worauf du hinauswolltest):
Code:
  <div>
    <input type="hidden" name="media[id][]" value="eine ID" />
    <input type="text" name="media[titel][]" value="ein Titel" />
  </div>
<!-- neue Datensätze ->
  <div>
    <input type="hidden" name="media[id][]" value="" />
    <input type="text" name="media[titel][]" value="" />
  </div>
  <div>
    <input type="hidden" name="media[id][]" value="" />
    <input type="text" name="media[titel][]" value="" />
  </div>
<!-- ...uswusf  ->
Da läufst du keine Gefahr, etwas Vorhandenes zu überschreiben, da die ID unabhängig vom Namen der übermittelten Formularfelder ist...du musst den Array beim Verarbeiten nur etwas anders durchlaufen.....könnte dann bspw. so aussehen:
PHP:
<html>
<head>
<title>Test</title>
<script type="text/javascript">
<!--
j=0;
function clone(o)
{
    n=o.cloneNode(true);
    a=o.getElementsByTagName('INPUT');
    for(e=0;e<a.length;++e)
      {
        a[e].value='';
      }
    o.parentNode.insertBefore(n,o); 
}
//-->
</script>
</head>
<body>
<?php
if(isset($_POST['media']))
  {
    foreach($_POST['media']['id'] as $k=>$v)
    {
      echo '<br>#'.$k.':['.((empty($_POST['media']['id'][$k]))?'neu':$_POST['media']['id'][$k]).']=&gt;'.htmlentities($_POST['media']['titel'][$k]);
    }
  }
?>
<form method="post">
  <div>
    <input type="hidden" name="media[id][]" value="eine ID" />
    <input type="text" name="media[titel][]" value="ein Titel" />
  </div><input type="button" onclick="clone(this.previousSibling)" value="neuer Datensatz">
  <input type="submit">
</form>

</body>
</html>
 
Hi Sven!

Yeeehawww! :) Genau darum ging es mir! :)

Die zweite Variante hatte ich ausprobiert und mich da total vertüdelt :(
Nun hatte ich bereits mit der ersten Variante begonnen, kämpfte aber noch mit JS und dessen Nodes. Mit Deinem sooo wunderbaren Beispiel, komme ich nun aber ohne weitere Probleme klar! :)

Ich danke Dir vielmals: You made my day! :)
Dir, Gumbo, natürlich auch vielen Dank, daß Du Dich meinen cryptischen Texten angenommen hast ;)

Liebe Grüße & tausend Dank,
Mark.
 
Hi Sven!
Pass auf bei meinen Beispielen...der Button, der die Funktion aufruft, muss sich direkt hinter dem zu Clonenden Container befinden, selbst ein Leerzeichen dazwischen verhindert bei Geckos schon, dass sie den rechten Knoten finden ;)
... Du meinst, Du übernimmst keine Haftung?! :eek: ;)

Zum einen bin ich in der glücklichen Lage, entscheiden zu können, auf welchen Browsern das ganze rennen können soll (reines Admin-Ding, nix für die Öffentlichkeit) und zum anderen ist mein Ansatz auch ein wenig anders: Ich clone einen zusätzlichen, unsichtbaren div-Container anhand seiner Id, der die Inputs enthält und durchlaufe dessen Inputs und Selects zwecks Umbenennung.
Aber: alles rennt bereits superbrav auf'm Firefox und mehr brauche ich nicht! :)

Nochmals vielen Dank! :)

Liebe Grüße,
Mark.
 
Zurück