Как переименовать все идентификаторы в клонированной форме (javascript)?
У меня есть форма (commonStuff), клонированная таким образом (и HTML-страница, созданная в jquery mobile, где форма появляется несколько раз, клонированная):
var commonClone = commonStuff.cloneNode(true);
и эта функция
function renameNodes(node) {
var i;
if (node.length) {
for (i = 0; i < node.length; i += 1) {
renameNodes(node[i]);
}
} else {
// rename any form-related elements
if (typeof node.form !== 'undefined') {
node.id = currentPrefix + '_' + node.id;
node.name = currentPrefix + '_' + node.name;
// This assumes that form elements do not have child form elements!
} else if (node.children) {
renameNodes(node.children);
}
}
}
которые добавляют префикс "form1_", "form_2" (currentPrefix) к идентификатору и именам любого элемента в форме и применяются к commonClone (и таким образом рекурсивно к его сыновьям).
renameNodes(commonClone);
Это отлично работает в случае ввода текста, таких как
<div data-role="fieldcontain" class="ui-field-contain ui-body ui-br">
<label for="foo" class="ui-input-text">Age:</label>
<input type="text" name="age" id="age" value="" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset">
</div>
Но это не на радио кнопки, как
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<legend>Address:</legend>
<input type="radio" name="radio-address" id="radio-address_female" value="1" checked="checked" />
<label for="radio-address_female">Address 1</label>
<input type="radio" name="radio-address" id="radio-address_male" value="2" />
<label for="radio-address_male">Address 2</label>
</fieldset>
</div>
применяя переименование к внешним элементам div, таким как 'fieldcontain' и 'controlgroup'. Это работает, если я удаляю эти два div, но графический эффект недопустим...
На данный момент, я понял, что проблема в последнем блоке 'else if', так как он не заботится о братьях и сестрах, но я не знаю, как это исправить. Любая идея?
РЕДАКТИРОВАТЬ: Этот код исходит из этого ответа Как создать HTML-форму с вкладками с общим div
2 ответа
Поскольку вы используете jQuery mobile, jQuery будет доступен. Я надеюсь, что этот код укажет вам правильное направление:
var i = 0;
$("form").each(function() {
$(this).find("input, select").each(function() {
$(this).attr("id", "form" + i + "_" + $(this).attr("id"));
$(this).attr("name", "form" + i + "_" + $(this).attr("name"));
});
$(this).find("label").each(function() {
$(this).attr("for", "form" + i + "_" + $(this).attr("for"));
});
i++;
});
РЕДАКТИРОВАТЬ:
Я понимаю, что ваш нынешний подход не работает с ярлыками. Подумайте, чтобы обернуть ваши элементы ввода внутри label
тег. В этом случае вам не понадобится for
атрибута по. Это в соответствии с документами: http://api.jquerymobile.com/checkboxradio/ Учтите это:
HTML
<form>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<legend>Address:</legend>
<label><input type="radio" name="radio-address" id="radio-address_female" value="1" checked="checked" />Address 1</label>
<label><input type="radio" name="radio-address" id="radio-address_male" value="2" />Address 2</label>
</fieldset>
</div>
<div data-role="fieldcontain" class="ui-field-contain ui-body ui-br">
<label><input type="text" name="age" id="age" value="" class="ui-input-text ui-body-c ui-corner-all ui-shadow-inset">Age:</label>
</div>
</form>
JQuery
var i = 0, currentPrefix = "form";
$("form").each(function() {
$(this).find("input, select").each(function() {
$(this).attr("id", currentPrefix + i + "_" + $(this).attr("id"));
$(this).attr("name", currentPrefix + i + "_" + $(this).attr("name"));
});
i++;
});
Рабочая скрипка: https://jsfiddle.net/EliteSystemer/8sx6rnwo/
Поистине, это далеко не элегантно, но, во всяком случае, решение. В любом узле это ищет вручную ввод и метки, изменяя id, имена и атрибут "для" в случае меток.
function renameNodes(node) {
var i;
if (node.length) {
for (i = 0; i < node.length; i += 1) {
renameNodes(node[i]);
}
} else {
// rename any form-related elements
if (typeof node.form !== 'undefined') {
node.id = currentPrefix + '_' + node.id;
node.name = currentPrefix + '_' + node.name;
var inputs = node.getElementsByTagName('input');
for (i = 0; i < inputs.length; ++i) {
inputs[i].id = currentPrefix + '_' + inputs[i].id;
inputs[i].name = currentPrefix + '_' + inputs[i].name;
}
var labels = node.getElementsByTagName('label');
for (i = 0; i < labels.length; ++i) {
labels[i].setAttribute('for', currentPrefix + '_' + labels[i].getAttribute("for"));
}
} else if (node.children) {
renameNodes(node.children);
}
}
}