我可能只是使用错误的关键字搜索Google,但我很难找到有关创建可扩展表单字段的信息。我有一个输入表单,用户可以列出分配给服务器节点的所有库存,但希望他们能够在需要时添加其他项目。作为表单的示例显示了(1)要添加的磁盘的选项,但是他们可以单击+符号并添加更多。
我已经为每种类型创建了8个MYSQL行,例如disk1,disk2等,以允许存储相当大的数量。但是,我担心的是,这可能是很多选择。
1)如何使用Javascript创建可扩展的表单?我只发现了一个没有用的代码示例。 2)我应该硬编码所有选项吗?比如,现在我的代码有一个名为" ram","主板"等的选择框。我可以生成这些或者我应该继续为每个字段写出来,例如" ram1"," ram2"等?
答案 0 :(得分:2)
在JavaScript中克隆字段很简单。说你有:
<select name="hdd"><!-- ...options here...--></select>
然后,一旦你获得了对DOM中现有元素的引用(见下文),你就可以这样做:
var newSelect = existingSelect.cloneNode(true);
newSelect.selectedIndex = -1; // To clear any existing selection
existingSelect.parentNode.insertBefore(newSelect, existingSelect.nextSibling);
可以使用CSS选择器和any modern browser(以获得第一个匹配项)或select
({}获得对现有document.querySelectorAll
的引用所有匹配的列表),例如:
var list = document.querySelectorAll('select[name="hdd"]');
var existingSelect = list[list.length - 1]; // Get the last one
...这会给你最后一个。或者更有可能的是,您有一行(tr
或div
)包含您要复制的。不是问题,给该行一个类(比如"hdd"
),并克隆整个事物(这里我克隆最后一行并将其添加到最后一行):
var list = document.querySelectorAll('.hdd');
var existingRow = list[list.length - 1]; // Get the last one
var newRow = existingRow.cloneNode(true); // Clone it
newRow.querySelector('select[name="hdd"]').selectedIndex = -1; // Clear selected value
existingRow.parentNode.insertBefore(newRow, existingRow.nextSibling);
在MySQL方面,最好不来设置hdd1
,hdd2
等列,因为它会使这些字段的查询变得复杂,当然,限制你可以拥有的最大数量(授予你可能还想限制它)。 (将这些列放在一行中称为“非正规化”DB。)
在数据库设计中执行此操作的常用方法是使用第二个表,列出HDD,其中第二个表中的键(“外键”)链接回主表。 (有关详细信息,请参阅“数据库规范化”。)
所以你的主表可能有一个记录ID,比如SystemID
。然后,您的HDD表格会有一个SystemID
列和一个HDD
列,其中可能有相同SystemID
的多行。
以下是表单位的完整示例:document.querySelector
| Live Copy
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Add Form Field Example</title>
</head>
<body>
<div class="hdd">
<label>HDD: <select name="hdd">
<option>--choose--</option>
<option>80GB</option>
<option>500GB</option>
<option>1TB</option>
<option>2TB</option>
</select></label></div>
<input type="button" id="theButton" value="Add Row">
<script>
(function() {
document.getElementById("theButton").addEventListener("click", addRow, false);
function addRow() {
var list = document.querySelectorAll('.hdd');
var existingRow = list[list.length - 1]; // Get the last one
var newRow = existingRow.cloneNode(true); // Clone it
newRow.querySelector('select[name="hdd"]').selectedIndex = -1; // Clear selected value
existingRow.parentNode.insertBefore(newRow, existingRow.nextSibling);
}
})();
</script>
</body>
</html>
一些有用的参考资料:
答案 1 :(得分:0)
尝试创建一个通用的DEVICE_DETAIL表,其中包含TYPE和DETAILS列。然后你可以保持一个任意数字&amp;将来添加新类型。
create table DEVICE (
ID integer not null,
..
primary key (ID)
);
create table DEVICE_DETAIL (
ID integer not null,
FK_DEVICE integer not null,
"TYPE" varchar(24), -- type code; defined internally.
CONFIG varchar(200),
NOTES clob, -- if necessary?
.. more columns if useful
primary key (ID)
);
这样做的好处是,您不需要为HDD,IP地址,RAM或各种未来可能性提供单独的表。您只需要几个可以保存详细信息的列 - 对于大多数情况,一行就足够了。
添加&amp;在UI中显示新字段,因为用户填写了以前的字段。
答案 2 :(得分:0)
执行此操作的最简单方法是注册“添加字段”单击处理程序,并使用它在Javascript中创建新字段。我已经汇总了一个快速示例,向您展示如何使用输入字段执行此操作。
这是HTML:
<form id='form'>
<div>
<label for='input0'>Field 0</label>
<input name='input0' type='text'></input>
</div>
</form>
<a id='moreLink' href='#'>Add Field</a>
这是Javascript:
var inputIndex = 0;
document.getElementById('moreLink').addEventListener('click', function() {
var form = document.getElementById('form'),
newLabel = document.createElement('label'),
newInput = document.createElement('input'),
newDiv = document.createElement('div'),
inputId
;
inputIndex++;
inputId = 'input' + inputIndex;
newLabel.htmlFor = inputId;
newLabel.innerHTML = 'Field ' + inputIndex;
newInput.name = inputId;
newInput.type = 'text';
newDiv.appendChild(newLabel);
newDiv.appendChild(newInput);
form.appendChild(newDiv);
});
这是一个指向JSFiddle的链接,以便您可以看到它的实际效果:http://jsfiddle.net/tpmet/
这是一个非常天真的解决方案,但它会表现良好,可以在任何浏览器中使用,至少可以追溯到IE6。
如果您的标记变得更复杂,您应该考虑在启动时创建一次模板并在单击处理程序中克隆该模板。如果您计划添加整个表单或其他大量的DOM,我建议您阅读文档片段,这些片段更复杂但在该级别上表现更好。
希望这有帮助,如果我的答案不清楚,请发表评论。