2

我可能只是使用错误的关键字搜索 Google,但我很难找到有关创建可扩展表单字段的信息。我有一个输入表单,用户可以在其中列出分配给服务器节点的所有库存,但希望他们能够在需要时添加其他项目。例如,表单显示了 (1) 要添加的磁盘的选项,但他们可以单击 + 符号并添加更多。

我已经为每种类型创建了 8 个 MYSQL 行,例如 disk1、disk2 等,以允许存储大量数据。但是,我担心的是,这有很多选择。

1) 如何使用 Javascript 创建可扩展的表单?我只发现了一个不起作用的代码示例。2)我应该对所有选项进行硬编码吗?例如,现在我的代码有一个名为“ram”、“motherboard”等的选择框。我可以生成这些,还是应该继续为每个字段写出来,例如“ram1”、“ram2”等?

在此处输入图像描述

4

3 回答 3

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

select可以在任何现代浏览器上使用 CSS 选择器和document.querySelector(获取第一个匹配项)或(获取所有匹配项的列表)来获取对现有项的引用document.querySelectorAll,例如:

var list = document.querySelectorAll('select[name="hdd"]');
var existingSelect = list[list.length - 1]; // Get the last one

...这会给你最后一个。或者更有可能的是,您有一行包含您想要复制的内容(atr或 a 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 方面,最好不要有 , 等列hdd1hdd2因为它会使对这些字段的查询变得复杂,并且当然会限制您可以拥有的最大数量(当然,您可能想要限制反正)。(将这些列放在一行中称为“非规范化”数据库。)

在 DB 设计中执行此操作的常用方法是创建第二个表,列出 HDD,其中第二个表中的键(“外键”)链接回您的主表。(有关更多信息,请参阅“数据库规范化”。)

所以你的主表可能有一个记录ID,比如说SystemID。然后,您的 HDDs 表将有一个SystemID列和一个HDD列,其中它可以有许多相同的行SystemID

这是表单位的完整示例: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>

一些有用的参考:

于 2013-05-16T09:31:04.867 回答
0

尝试创建一个通用的 DEVICE_DETAIL 表,其中包含 TYPE 和 DETAILS 列。然后您可以持有任意数字并在将来添加新类型。

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 或各种未来可能性提供单独的表。您只需要几列可以保存详细信息——对于大多数情况,一行就足够了。

在用户填写之前的字段时,在 UI 中添加和显示新字段。

于 2013-05-16T09:32:01.157 回答
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,我建议您阅读 Document Fragments,它更复杂但在该规模级别上表现更好。

希望这对您有所帮助,如果我的答案不清楚,请发表评论。

于 2013-05-16T10:14:16.957 回答