简体   繁体   English

更改嵌套在克隆表中的输入/选择字段的名称属性,以进行动态表单输入 - Javascript

[英]Change name attribute of input/select field nested in a cloned table for dynamic form entry - Javascript

I'm designing a dynamic input form that essentially acts as a user GUI for creating tables in a mysql database. 我正在设计一个动态输入表单,它实际上充当用户GUI,用于在mysql数据库中创建表。

The 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;

The HTML 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>

The Problem 问题

The problem is that when new fields are added to the form, they retain the same name designators from the original clone. 问题是,当新字段添加到表单时,它们将保留原始克隆中的相同名称标识符。 (Clone structure is 'poptemplate' div in code above.) (克隆结构在上面的代码中是'poptemplate'div。)

Having taught myself most of my web developing skills from research, I have located this script, now modified, (original source: http://www.quirksmode.org/dom/domform.html ) in order to clone the template and insert it into the page (with an unshown jquery function that merely calls the JS function when the Add Field button is clicked). 我从研究中自学了大部分的网络开发技巧后,我找到了这个现在修改过的脚本(原始来源: http//www.quirksmode.org/dom/domform.html ),以便克隆模板并插入它进入页面(带有未示出的jquery函数,仅在单击“添加字段”按钮时调用JS函数)。

The problem is, the JS, while it clones the DIV successfully and places it, the loop involved does not delve deep enough into the node structure of my template to find the input fields and change their names. 问题是,JS在成功克隆DIV并放置它时,所涉及的循环没有深入到我的模板的节点结构中以找到输入字段并更改它们的名称。

One input field is a drop-down list that is populated through a mysql query with php, however its location in the node structure should be at the same level as the text input. 一个输入字段是一个下拉列表,通过带有php的mysql查询填充,但是它在节点结构中的位置应该与文本输入处于同一级别。 (ie <Table><tr><td><input(or/)select> ) (即<Table><tr><td><input(or/)select>

The Attempt At Fixing Part 1 尝试修复第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;

Attempt At The Fix Part 2 尝试修复第2部分

After following through with a suggestion from briansol , I have the following modified java script that still does not follow through with what it is supposed to do on execution. 在完成了briansol的建议briansol ,我有了以下修改过的java脚本,它仍然没有贯彻执行它应该做的事情。 I have left the unnecessary, however useful, line of code inputs[index].value = inputs[index].name + counter; 我留下了不必要但有用的代码行inputs[index].value = inputs[index].name + counter; for troubleshooting purposes. 用于故障排除。

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;

The Need UPDATED: 需要更新:

Currently, Attempt 2 seems promising but there is something missing. 目前,尝试2似乎很有希望,但有些东西缺失。 It successfully clones the template, but the procedures to capture the select and input elements is not succeeding. 它成功克隆了模板,但捕获select和input元素的过程没有成功。

ORIGINAL: 原版的:

I'm looking for a solution to patch the already provided for loop to delve deeper, or alternative code that doesn't break the cloning process, but additionally changes the name attributes. 我正在寻找一个解决方案来修补已经提供的for循环来深入研究, 或者替代代码不会破坏克隆过程,但是还会更改名称属性。 All of my attempts to modify this code to traverse deeper have resulted in the code breaking on execution. 我尝试修改此代码以进行更深入的尝试导致代码在执行时中断。

This is my first post here, I have found stackoverflow to be incredibly helpful, I hope my problem and its solution can help others learn and understand better. 这是我在这里的第一篇文章,我发现stackoverflow非常有用,我希望我的问题及其解决方案可以帮助其他人更好地学习和理解。 Thanks for assistance in advanced. 感谢先进的帮助。

Edited to include code locally. 编辑为在本地包含代码。

You'll need to clone not only the rows, but also give each item a unique name for the form to post or you'll over-write data. 您不仅需要克隆行,还需要为每个项目指定要发布的表单的唯一名称,否则您将覆盖数据。 Each field name must be unique. 每个字段名称必须是唯一的。

easy was is to use a counter on the clone copy. 容易就是在克隆副本上使用计数器。

Here's a sample: 这是一个示例:

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>

I'm indebted to briansol for helping with the structural example. 我非常感谢briansol帮助结构化的例子。 This code is a functioning solution to my problem. 此代码是我的问题的功能解决方案。 Edits from briansol's original code example includes removal of + counter from the container assignment. briansol原始代码示例的编辑包括从container分配中删除+ counter Firefox's developer console allowed me to see that the variable was coming up null. Firefox的开发者控制台让我看到该变量即将出现。 Once the counter had been added to the ID, there was no need to append it again. 将计数器添加到ID后,无需再次附加。

The Solution 解决方案

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM