JS的可扩展表单字段

时间:2013-05-16 09:22:03

标签: php javascript mysql webforms expandable

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

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

1)如何使用Javascript创建可扩展的表单?我只发现了一个没有用的代码示例。 2)我应该硬编码所有选项吗?比如,现在我的代码有一个名为" ram","主板"等的选择框。我可以生成这些或者我应该继续为每个字段写出来,例如" ram1"," ram2"等?

enter image description here

3 个答案:

答案 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

...这会给你最后一个。或者更有可能的是,您有一行(trdiv包含您要复制的。不是问题,给该行一个类(比如"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。然后,您的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,我建议您阅读文档片段,这些片段更复杂但在该级别上表现更好。

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