Расширяемые поля формы с JS


Возможно, я просто ищу в Google по неправильным ключевым словам, но мне очень не везет в поиске информации о создании расширяемых полей формы. У меня есть форма ввода, в которой пользователь может перечислить все запасы, назначенные узлу сервера, но хотел бы, чтобы они могли добавлять дополнительные элементы, если это необходимо. Пример в форме показывает возможность добавления (1) диска, но они могут щелкнуть символ + и добавить больше.

Я уже создал 8 строк MYSQL для каждого типа, такого как disk1, диск2 и т.д. чтобы можно было хранить значительное количество. Однако меня беспокоит то, что у этого получается МНОГО вариантов.

1) Как я могу использовать Javascript для создания расширяемых форм? Я нашел только один пример кода, который не сработал. 2) Должен ли я жестко кодировать все параметры? Например, прямо сейчас в моем коде есть поле выбора "оперативная память", "материнская плата" и т. Д. Могу ли я сгенерировать их или мне следует продолжить и записать их для каждого поля, такого как "ram1", "ram2" и т. Д.?

enter image description here

Author: T.J. Crowder, 2013-05-16

3 answers

Клонировать поле в 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 или 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, и т.д., Потому что это усложняет запросы по этим полям и, конечно, ограничивает максимальное количество, которое вы можете иметь (при условии, что вы, вероятно, захотите все равно ограничьте это). (Наличие этих столбцов в одной строке называется "денормализацией" базы данных.)

Обычный способ сделать это при проектировании БД - создать вторую таблицу со списком жестких дисков, где ключ в этой второй таблице ("внешний ключ") ссылается на вашу основную таблицу. (Дополнительную информацию см. в разделе "нормализация базы данных".)

Таким образом, ваша основная таблица может иметь идентификатор записи, скажемSystemID. Ваша таблица жестких дисков будет содержать столбец SystemID и столбец HDD, в котором может быть много строк для одного и того же SystemID.

Вот полный пример бита формы: Живая копия | Живой источник

<!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>

Некоторые полезные ссылки:

 2
Author: T.J. Crowder, 2013-05-16 10:13:57

Попробуйте создать общую таблицу DEVICE_DETAIL со столбцами для ТИПА и СВЕДЕНИЙ. Затем вы можете удерживать произвольное число и добавлять новые типы в будущем.

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

Преимущество этого заключается в том, что вам не нужны отдельные таблицы для жесткого диска, IP-адресов, оперативной памяти или широкого спектра будущих возможностей. Вам просто нужна пара столбцов, в которых могут содержаться детали - и для большинства вещей будет достаточно одной строки.

Добавление и отображение новых полей в пользовательском интерфейсе по мере заполнения пользователем предыдущих те.

 0
Author: Thomas W, 2013-05-16 09:32:01

Самый простой способ сделать это - зарегистрировать обработчик щелчков "Добавить поле" и использовать его для создания нового поля в 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, я бы рекомендовал ознакомиться с фрагментами документов, которые являются более сложными, но будут работать лучше на этом уровне масштаба.

Надеюсь, это было полезно, пожалуйста, прокомментируйте, если мой ответ неясен.

 0
Author: Dan M, 2013-05-16 10:14:16