2014-06-13 7 views
5

Projektuję dynamiczny formularz wejściowy, który zasadniczo działa jako GUI użytkownika do tworzenia tabel w bazie danych mysql.Zmiana atrybutu nazwy pola wejściowego/wyboru zagnieżdżonego w sklonowanej tabeli dla dynamicznego wprowadzania formularzy - JavaScript

Javascript

var counter = 0; 
function moreFields() { 
    counter++; 
    var newFields = document.getElementById('poptemplate').cloneNode(true); 
    newFields.id = ''; 
    newFields.style.display = 'block'; 
    var newField = newFields.childNodes; 
    for (var i=0;i<newField.length;i++) { 
     var fieldname = newField[i].name; 
     if (fieldname){ 
      newField[i].name = fieldname + counter; 
      } 
    } 
    var insertHere = document.getElementById('catidtable'); 
    insertHere.parentNode.appendChild(newFields); 
    } 
window.onload = moreFields; 

HTML

<div id="poptemplate" style="display: none" > 
<table border="3"> 
<tr> 
    <td>Field Name:</td> 
    <td><input class="renameme" form="catform" type="text" name="fieldname_input" /></td> 
</tr> 
<tr> 
    <td>Data Type:</td> 
    <td><?php $typedown->displayList(); ?></td> 
</tr> 
<tr> 
    <td colspan='2'><input type="button" value="Remove Field" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);" /></td> 
</tr> 
</table> 
</div> 

Problem

Problem polega na tym, że gdy nowe pola są dodawane do formularza, zachowują same nazwy desygnatorów z oryginalny klon. (Struktura klonu to "poptemplate" div w powyższym kodzie.)

Po tym, jak nauczyłem się większości swoich umiejętności rozwijania sieci od badań, zlokalizowałem ten skrypt, teraz zmodyfikowany, (oryginalne źródło: http://www.quirksmode.org/dom/domform.html) w celu sklonowania szablonu i wstawić go na stronę (z nienotowaną funkcją jquery, która wywołuje funkcję JS tylko po kliknięciu przycisku Dodaj pole).

Problem polega na tym, że JS, podczas klonowania DIV z powodzeniem i umieszcza go, zaangażowana pętla nie zagłębia się wystarczająco głęboko w strukturę węzła mojego szablonu, aby znaleźć pola wejściowe i zmienić ich nazwy.

Jedno pole wejściowe jest listą rozwijaną wypełnianą przez zapytanie mysql za pomocą php, jednak jego położenie w strukturze węzła powinno być na tym samym poziomie, co wprowadzanie tekstu. (tj <Table><tr><td><input(or/)select>)

próba ustalającym 1

function moreFields() { 
    counter++; 
    var newFields = document.getElementById('poptemplate').cloneNode(true); 
    newFields.id = ''; 
    newFields.style.display = 'block'; 
    var newField = newFields.childNodes; //Table level of poptemplate 
    if (newField.hasChildNodes()){//If the table has children, and it does, loop through them 
    for (var i=0;i<newField.length;i++) { 
     var x = newField.rows[i].cells.length; //how many cells you got in your row 
      if (x>0;){ //if its more than 0, look at the cells 
      for (var r = 0;r<x;r++) { 
       var td = newField.rows[0].cell[r]; //td is equal to the td level time to check to see if it has input or select 
        var k = td.getElementsByTagName("select"); 
        if (k.hasChildren()){ 
        k.firstChild.setAttribute(name, name + counter); 
        } 
        var p = td.getElementsByTagName("input"); 
        if (p.hasChildren()){ 
        p.firstChild.setAttribute(name, name + counter); 
        } 
            } 
        } 
             } 
}           
    var insertHere = document.getElementById('catidtable'); 
    insertHere.parentNode.appendChild(newFields); 
} 
window.onload = moreFields; 

próba FIX części 2

Po wykonaniu przez z sugestii briansol, że mają następujący zmodyfikowany skrypt java, który nadal nie działa z tym, co ma robić podczas wykonywania. Zostawiłem niepotrzebny, ale użyteczny, wiersz kodu inputs[index].value = inputs[index].name + counter; do rozwiązywania problemów.

var counter = 0; 
function moreFields() { 
    counter++; 
    var index, inputs; 
    var newFields = document.getElementById('poptemplate').cloneNode(true); 
    newFields.id = newFields.id+counter; 
    newFields.style.display = 'block'; 
    var newField = newFields.childNodes; 
    var insertHere = document.getElementById('catidtable'); 
    insertHere.parentNode.appendChild(newFields); 
    // now update it 
    container = document.getElementById(newFields.id+counter); 
    // Find its child `input` elements 
    inputs = container.getElementsByTagName('input'); 
    selects = container.getElementByTagName('select'); 
    for (index = 0; index < inputs.length; ++index) { 
     // deal with inputs[index] element. 
     inputs[index].name = inputs[index].name + counter; 
     inputs[index].value = inputs[index].name + counter; 
    } 
    for (index = 0; index < selects.length; ++index) { 
     // deal with select element 
     selects[index].name = selects[index].name + counter; 
     } 
} 
window.onload = moreFields; 

Need AKTUALIZACJA:

Obecnie Próba 2 wydaje się obiecujące, ale czegoś brakuje. Pomyślnie klonuje szablon, ale procedury przechwytywania elementów wyboru i wprowadzania nie powiodły się.

oryginalny:

szukam rozwiązania załatać już przewidziane dla pętli wniknąć głębiej, lub alternatywny kod, który nie łamie proces klonowania, ale dodatkowo zmienia atrybuty nazwy . Wszystkie moje próby modyfikacji tego kodu, aby przejść głębiej, spowodowały złamanie kodu przy wykonywaniu.

To jest mój pierwszy post tutaj, znalazłem stackoverflow, aby być niezwykle pomocny, mam nadzieję, że mój problem i jego rozwiązanie może pomóc innym lepiej się uczyć i rozumieć. Dzięki za pomoc w zaawansowanym.

Odpowiedz

1

Edytowane w celu włączenia kodu lokalnie.

Będziesz musiał sklonować nie tylko wiersze, ale także nadać każdemu produktowi unikatową nazwę formularza do opublikowania lub będziesz nadpisywać dane. Każda nazwa pola musi być unikalna.

łatwe było użycie licznika na kopii klonu.

Oto próbka:

var counter = 0; 
function moreFields() { 
while(counter<10){ 
counter++; 
var index, inputs; 
var newFields = document.getElementById('poptemplate').cloneNode(true); 
newFields.id = 'clone'+counter; 
newFields.style.display = 'block'; 
var newField = newFields.childNodes; 
var insertHere = document.getElementById('catidtable'); 
insertHere.parentNode.appendChild(newFields); 
// now update it 
container = document.getElementById('clone'+counter); 
// Find its child `input` elements 
inputs = container.getElementsByTagName('input'); 
for (index = 0; index < inputs.length; ++index) { 
    // deal with inputs[index] element. 
    inputs[index].name = inputs[index].name + counter; 
    inputs[index].value = inputs[index].name + counter; 
} 
} 
} 
window.onload = moreFields; 



<div id="poptemplate" style="display:none"> 
<table border="3" id="template"> 
<tr> 
    <td>Field Name:</td> 
    <td><input class="renameme" form="catform" type="text" name="fieldname_input" /> </td> 
</tr> 
<tr id="tr1"> 
    <td id="td1" colspan='2'><input type="button" value="Remove Field" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);" /></td> 
</tr> 
</table> 
</div> 

<br> 

<table id="catidtable"> 
</table> 
+1

tutaj jest bardzo szybkie demo, które wymaga pracy, ale robi expemplify pracę. http://jsfiddle.net/briansol/pyq8v/ umieszcza klon w domie tak jak jest, a następnie zmienia go na podstawie identyfikatora tabeli. Może to nie być tak skuteczne, ale łatwiej jest zająć się lementami, gdy już istnieją. Uruchomiłem go 10 razy, aby pokazać, że pola są aktualizowane. – briansol

+0

Czy możesz umieścić kod w odpowiedzi, a nie tylko link jsfiddle? – Barmar

1

Jestem wdzięczny za pomoc briansol na przykładzie strukturalnej. Ten kod jest funkcjonującym rozwiązaniem mojego problemu. Edycja z przykładu oryginalnego kodu briansol obejmuje usunięcie + counter z zadania container. Konsola programistyczna Firefoksa pozwoliła mi zobaczyć, że zmienna ma wartość null. Po dodaniu licznika do identyfikatora nie trzeba było go ponownie dołączać.

Rozwiązanie

var counter = 0; 
function moreFields() { 
    counter++; 
    var newFields = document.getElementById('poptemplate').cloneNode(true); 
    newFields.id = newFields.id+counter; 
    newFields.style.display = 'block'; 
    var insertHere = document.getElementById('catidtable'); 
    insertHere.parentNode.appendChild(newFields); 
    // now update it 
    var index, inputs, selects, container; 
    container = document.getElementById(newFields.id); 
    // Find its child `input` elements 
    inputs = container.getElementsByTagName('input'); 
    selects = container.getElementsByTagName('select'); 
    for (index = 0; index < inputs.length; ++index) { 
     // deal with inputs[index] element. 
     inputs[index].name = inputs[index].name + counter; 
    } 
    for (index = 0; index < selects.length; ++index) { 
     // deal with select element 
     selects[index].name = selects[index].name + counter; 
     } 
} 
window.onload = moreFields; 
+0

Cieszę się, że to się dzieje :) Walczyłem z tym po raz pierwszy ja też sklonowałem. – briansol

Powiązane problemy