Antworten auf deine Fragen:
Neues Thema erstellen

Antworten zum Thema „JavaSript - cloneNode und Werte ändern“

Isometric

Powerproster

Ich kopiere die Zeile einer Tabelle
HTML:
<tr><td><input type="text" name="article_field[]" value="variable"></td>
<td><button type="button" title="Eintrag kopieren" onclick="ARTICLE.add(this)"><img  src="add.gif"></button></td>
</tr>
mit folgender Funktion:

Code:
    add: function (button) {
        var row = this.rowOf(button);

        row.parentNode.insertBefore(row.cloneNode(true), row);
    }

Wie kann ich an den Wert von "value" einen String anhängen, z.B. "_copy" um Duplikate zu vermeiden?
 

Myhar

Hat es drauf

Indem du zuerst die row dupliziert, dann die Werte änderst und dann erst einfügst.
Code:
var superTestVariable = row.cloneNode(true);
//superTestVariable kannst du nun nach belieben ändern
row.parentNode.insertBefore(superTestVariable, row );
 

Isometric

Powerproster

Das hatte ich auch schon probiert, allerdings weiß ich nicht, wie ich den Wert von value ändere. Ich hatte versucht einfach ein "_copy" hintendran zu hängen, aber dass kann ja nicht klappen. :eek:
 

Isometric

Powerproster

var superTestVariable = row.cloneNode(true);
//superTestVariable kannst du nun nach belieben ändern

und so wollte ich die Supertestvariable ändern, aber die hat Superkräfte :ciao:
Code:
var superTestVariable = row.cloneNode(true);
superTestVariable.setAttribute('value', 'copy');
row.parentNode.insertBefore(superTestVariable, row );

oder so:
Code:
var superTestVariable = row.cloneNode(true).setAttribute('value', 'copy');
row.parentNode.insertBefore(superTestVariable, row );
 

mindraper

me[code].Java(Script)

moinsen,

tablerow elemente kennen das value-attribut nicht. aus diesem grund funktioniert "setAttribute" hier nicht. es gibt hier mehrere lösungen, im folgenden beschrieben von "sauberste" zu "unsauberste":
  1. eines der globalen html-attribute verwenden. beispielsweise "title", "class", "data-xxx" oder sonstige der verfügbaren. eine übersicht gibt's hier:
    https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes
  2. bereits geklonte tr-elemente als referenzvariablen in einem array oder object cachen und vor dem erzeugen eines neuen klons abgleichen, ob schon eine kopie erzeugt wurde. in javascript werden dom-elemente by-reference verglichen, nicht by-value, so dass ein bereits erzeugter klon faktisch immer eindeutig ist und per striktem vergleich (===) abgeglichen werden kann.
    Code:
    // contains every tr which has already been cloned
    var cloned = [];
    
    var isAlreadyCloned = function (node) {
        // iterator function to check if the given
        // node has already been cloned
        return function (cloned) {
            return cloned === node;
        }
    }
    
    var makeClone = function (clonable) {
        // clonable = row, tr = superTestVariable
        var tr;
        if (!cloned.some(isAlreadyCloned(clonable))) {
            // if clonable has not been cloned,
            // add it to the cloned collection and
            // make a clone which is added to the DOM
            tr = clonable.cloneNode(true);
            clonable.parentNode.insertBefore(tr, clonable);
    
            cloned.push(clonable);
            cloned.push(tr);
        }
    }
    
    makeClone(row);

  3. setAttribute() nicht verwenden und "value" direkt setzen. das funktioniert zwar, allerdings ist damit das erzeugte markup nicht mehr valide.
    Code:
    var tr = row.cloneNode(true);
    tr.value = 'copy';
    tr.parentNode.insertBefore(tr, row);
persönlich würde ich variante (1) nutzen, die macht vermutlich am wenigsten arbeit und ist genauso valide wie variante (2). beispiel:
Code:
var isCloned = function (node) {
    return (/\s?copy\b/g).test(node.className);
}

var makeClone = function (clonable) {
    var tr, classes;
    if (!isCloned(clonable)) {
        // if clonable has not been cloned,
        // clone it, split (maybe) existend classnames into a array,
        // add the 'copy' class and concatenate them to a string
        // which is the new classname and add the clone to
        // the DOM
        tr = clonable.cloneNode(true);
        classes = tr.className.split(' ');
        classes.push('copy');
        tr.className = classes.join(' ');
        clonable.parentNode.insertBefore(tr, clonable);
    }
}

makeClone(row);

hoffe das hilft
 
Zuletzt bearbeitet:

Isometric

Powerproster

@mindrapper: :danke:danke für deinen Ansatz, aber ich glaube ich habe dich auf die falsche Fährte geführt.

Ich möchte nicht dem tablerow-Element ein neues value-Attribut zuweisen, sondern dem weiter unten versteckten input-Feld.

Hier noch mal der komplette Code:
HTML:
<form>
<table>
<tr>
   <td><input value="test"></td>
   <td><button type="button" title="Eintrag kopieren" onclick="TEST.copy(this)"> + </button></td>
</tr>
</table>
</form>

<script type="text/javascript">
/* <![CDATA[ */
var TEST = {
  copy: function (button) {
  var row = this.rowOf(button);
     var copynode = row.cloneNode(true);
     var anzeige = "Knoten " + copynode.firstChild.nodeName;
     alert (anzeige);
   
     var elems = row.childNodes;
     var text = "";
     for (var i=0; i<elems.length; i++) {
      text = text + elems[i].nodeName + "\n";
     }
     alert (text);
   
  row.parentNode.insertBefore(copynode, row);
  },

  rowOf: function (button) {
  var row = button;
  while (row.tagName.toLowerCase() !== "tr") {
  row = row.parentNode;
  }
  return row;
  }
}
/* ]]> */
</script>

Nach dem Kopieren soll in dem neuen Feld stehen: "test_copy"

Edit 1: code korrigiert

Edit 2: so, ich glaube ich habe es:

Code:
        var copynode = row.cloneNode(true);
        var anzeige = "Knoten vor Änderung:  " + copynode.firstChild.firstChild.getAttribute('value');
        alert (anzeige);
        var nodevalue = copynode.firstChild.firstChild.getAttribute('value');
        copynode.firstChild.firstChild.setAttribute('value', nodevalue + '_copy');
        anzeige = "Knoten nach Änderung: " + copynode.firstChild.firstChild.getAttribute('value');
        alert (anzeige);
 
Zuletzt bearbeitet:

mindraper

me[code].Java(Script)

moinsen,

ok, der bisher gezeigte code hat versucht, ein value-attribut auf den tabellenzeilen zu setzen, daher (und weil ich nicht richtig gelesen habe :rolleyes:) die verwechselung.

um den prozess abzukürzen habe ich ein funktionierendes fiddle für dich erstellt:
http://jsfiddle.net/urbandrone/u2Z9R/3/

der einzige wirkliche unterschied zu deiner version ist, dass dort keine inline eventhandler gesetzt sind (ist eh "bäh"), sondern diese am ende des javascripts gesetzt werden.

hoffe das hilft
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Neueste Themen & Antworten

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
175.158
Beiträge
2.581.869
Mitglieder
67.223
Neuestes Mitglied
Desiree
Oben