jQuery 克隆表单增加 name、class、id、data-id ..etc 的所有属性
Posted
技术标签:
【中文标题】jQuery 克隆表单增加 name、class、id、data-id ..etc 的所有属性【英文标题】:jQuery clone form increment all attributes of name,class,id,data-id ..etc 【发布时间】:2016-03-13 20:39:43 【问题描述】:我们的表单包含多个字段,我们需要通过 jQuery 来完成
当克隆字段需要增加它的名称、类、ID、数据ID和标签时。如何增加这样的ID
block-post-order-1-select
或者这样的名字
name="xform_demo[block-post-order-1]
您可以查看此表单代码 在代码笔http://codepen.io/earngate/pen/NxPOZz/
<table id="section-table-section-start1" data-id="section-start1" class="form-table form-table-section no-border form-table-section-indented">
<tr>
<th scope="row">
<div class="xform_field_th">
Block</div>
</th>
<td>
<fieldset id="xform_demo-switch-fold-1" class=" xform-container-switch" data-id="switch-fold-1" data-type="switch">
<div class="switch-options">
<label class="cb-enable selected" data-id="switch-fold-1"><span>On</span></label>
<label class="cb-disable" data-id="switch-fold-1"><span>Off</span></label>
<input class="checkbox checkbox-input" id="switch-fold-1" name="xform_demo[switch-fold-1]" value="1" type="hidden"></div>
</fieldset></td>
</tr>
<tr class="fold">
<th scope="row">
<div class="xform_field_th">
Text logo</div>
</th>
<td>
<fieldset id="xform_demo-block-cat-title-1" class="xform-container-text " data-id="block-cat-title-1" data-type="text">
<input id="block-cat-title-1" name="xform_demo[block-cat-title-1]" value class="regular-text " type="text" size="20"></fieldset></td>
</tr>
<tr class="fold">
<th scope="row">
<div class="xform_field_th">
</div>
</th>
<td>
<fieldset id="xform_demo-block-post-order-1" class=" xform-container-select" data-id="block-post-order-1" data-type="select">
<div style="width: 40%;" id="s2id_block-post-order-1-select" class="select2-container xform-select-item select2-allowclear">
<a href="javascript:void(0)" class="select2-choice" tabindex="-1">
<span id="select2-chosen-2" class="select2-chosen">first-choise</span><abbr class="select2-search-choice-close"></abbr>
<span class="select2-arrow" role="presentation"><b role="presentation">
</b></span></a><label for="s2id_autogen2" class="select2-offscreen">
</label>
<input id="s2id_autogen2" aria-labelledby="select2-chosen-2" class="select2-focusser select2-offscreen" aria-haspopup="true" role="button" type="text" size="20">
<div class="select2-drop select2-display-none select2-with-searchbox">
<div class="select2-search">
<label for="s2id_autogen2_search" class="select2-offscreen"></label>
<input placeholder id="s2id_autogen2_search" aria-owns="select2-results-2" spellcheck="false" class="select2-input" type="text" size="20">
</div>
<ul id="select2-results-2" class="select2-results" role="listbox">
</ul>
</div>
</div>
<select title tabindex="-1" id="block-post-order-1-select" name="xform_demo[block-post-order-1]" class="xform-select-item " style="width: 40%; display: none;" rows="6">
<option></option>
<option value="Desc" selected="selected">Lates</option>
<option value="rand">Random Posts</option>
</select></fieldset></td>
</tr>
<tr style="border-bottom: medium none;" class="compiler fold">
<th scope="row">
<div class="xform_field_th">
Block Style</div>
</th>
<td>
<fieldset id="xform_demo-block_type_1" class=" xform-container-image_select" data-id="block_type_1" data-type="image_select">
<div class="xform-table-container">
<ul class="xform-image-select">
<li class="xform-image-select">
<label class=" xform-image-select-selected xform-image-select block_type_1_1" for="block_type_1_1">
<input class=" compiler noUpdate " id="block_type_1_1" name="xform_demo[block_type_1]" value="node" checked="checked" type="radio"><img src="1-3.png" class style=" width: 100%; "></label></li>
<li class="xform-image-select">
<label class=" xform-image-select block_type_1_2" for="block_type_1_2">
<input class=" compiler noUpdate noUpdate " id="block_type_1_2" name="xform_demo[block_type_1]" value="nodey" type="radio"><img src="1-4.png" class style=" width: 100%; "></label></li>
</ul>
</div>
</fieldset></td>
</tr>
<tr style="display: none;" class="xform-section-indent-start">
<th scope="row"></th>
<td></td>
</tr>
</table>
jQuery
$(document).ready(function ()
$('table#section-table-section-start1').after('<input class="add_btn" id="add_btn" type="button" value="Add New">');
$(".add_btn").click(function(e)
var avails = $(this).prevAll();
var cnt = avails.length + 1;
$('#section-table-section-start1:last').clone().insertAfter("#section-table-section-start1:last").append( $('<input class="del_btn" type="button" value="Delete this">') );
$("input.del_btn").css("float":"right","background-color":"#c00","color":"#fff");
e.preventDefault();
);
$("body").on('click',".del_btn", function()
$(this).parent().remove();
);
);
你能帮忙吗
【问题讨论】:
欢迎来到 ***!请看***.com/tour,尤其是“实用、详细的问题”部分。尝试解决您的问题,我们将帮助您解决您在途中遇到的问题。祝你好运! @MarcL。谢谢,我们编辑了完整的代码来为克隆表单添加 jquery,但仍然需要代码来增加 name data-id id 和 classes,你能帮忙 感谢您提供您的代码。为此,我会回退到像 Knockout.js 这样的 MVVM 框架,这对您的解决方案来说可能有点过头了。 @MarcL。完全没有,希望能帮到你 您是否尝试将克隆内容的每个副本包装在 div 中并检查 div 上使用的类的长度? 【参考方案1】:所以问题似乎是“如何增加多个节点的多个属性中的数量”。 我将缩小范围以增加多个属性中的 last 整数,以保持简单。
你可以创建一个简单的函数来增加一个节点的一个属性的数量,然后对你需要的元素和属性重复它:
/* Increase the last number for an attribute of an jQuery element, if possible */
function inc ( node, property ) // .prop does not work with data-id so must use .attr
var number = node.attr( property ) ? node.attr( property ).match( /\d+(?=\D*$)/ ) : null;
if ( number === null ) return; // Abort if has no attribute or no number in it
node.attr( property, node.attr( property ).replace( /\d+(?=\D*$)/, +number[0]+1 ) );
var last = $('[id^=section-table-section-start]:last'), cloned = last.clone();
// For each element with any attribute we need, including the cloned table
cloned.find( '[name],[class],[id],[data-id],[for]' ).add( cloned ).each( function()
var me = $( this );
// Loop and increment each property
$.each( [ 'name', 'className', 'id', 'data-id', 'for' ], function( i, property )
inc( me, property );
);
);
有几种方法可以进行循环。
这里我们抓取所有元素并在每个元素上循环每个属性。 如果您的属性较少,您可以为每个属性手动调用inc
而不是$.each
。
或者,您可以先循环每个属性并找到元素,这样您可以创建更多 jQ 对象但检查的属性更少。
您可能还注意到我更改了您的克隆代码,因为使用自动增加的 id 您不能再按 id 选择最后一个表。
这里是完整的代码:
$( function ()
function inc ( element, property )
var number = element.attr( property ) ? element.attr( property ).match( /\d+(?=\D*$)/ ) : null;
if ( number === null ) return;
element.attr( property, element.attr( property ).replace( /\d+(?=\D*$)/, +number[0]+1 ) );
$('table#section-table-section-start1').after('<input class="add_btn" id="add_btn" type="button" value="Add New">');
$(".add_btn").click(function(e)
var last = $('[id^=section-table-section-start]:last'), cloned = last.clone();
cloned.find( '[name],[class],[id],[data-id],[for]' ).add( cloned ).each( function()
var me = $( this );
$.each( [ 'name', 'className', 'id', 'data-id', 'for' ], function( i, property )
inc( me, property );
);
);
cloned.insertAfter( last );
if ( ! cloned.find( '.del_btn' ).length )
cloned.append(
$( '<input class="del_btn" type="button" value="Delete this">' )
.css("float":"right","background-color":"#c00","color":"#fff")
);
e.preventDefault();
);
$("body").on('click',".del_btn", function() $(this).parent().remove(); );
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<table id="section-table-section-start1" data-id="section-start1" class="form-table form-table-section no-border form-table-section-indented">
<tr>
<th scope="row">
<div class="xform_field_th">
Block</div>
</th>
<td>
<fieldset id="xform_demo-switch-fold-1" class=" xform-container-switch" data-id="switch-fold-1" data-type="switch">
<div class="switch-options">
<label class="cb-enable selected" data-id="switch-fold-1">
<span>On</span>
</label>
<label class="cb-disable" data-id="switch-fold-1">
<span>Off</span>
</label>
<input class="checkbox checkbox-input" id="switch-fold-1" name="xform_demo[switch-fold-1]" value="1" type="hidden"/>
</div>
</fieldset>
</td>
</tr>
<tr class="fold">
<th scope="row">
<div class="xform_field_th">
Text logo</div>
</th>
<td>
<fieldset id="xform_demo-block-cat-title-1" class="xform-container-text " data-id="block-cat-title-1" data-type="text">
<input id="block-cat-title-1" name="xform_demo[block-cat-title-1]" value class="regular-text " type="text" size="20"/>
</fieldset>
</td>
</tr>
<tr class="fold">
<th scope="row">
<div class="xform_field_th">
</div>
</th>
<td>
<fieldset id="xform_demo-block-post-order-1" class=" xform-container-select" data-id="block-post-order-1" data-type="select">
<div style="width: 40%;" id="s2id_block-post-order-1-select" class="select2-container xform-select-item select2-allowclear">
<a href="javascript:void(0)" class="select2-choice" tabindex="-1">
<span id="select2-chosen-2" class="select2-chosen">first-choise</span>
<abbr class="select2-search-choice-close"/>
<span class="select2-arrow" role="presentation">
<b role="presentation">
</b>
</span>
</a>
<label for="s2id_autogen2" class="select2-offscreen">
</label>
<input id="s2id_autogen2" aria-labelledby="select2-chosen-2" class="select2-focusser select2-offscreen" aria-haspopup="true" role="button" type="text" size="20"/>
<div class="select2-drop select2-display-none select2-with-searchbox">
<div class="select2-search">
<label for="s2id_autogen2_search" class="select2-offscreen"/>
<input placeholder id="s2id_autogen2_search" aria-owns="select2-results-2" spellcheck="false" class="select2-input" type="text" size="20"/>
</div>
<ul id="select2-results-2" class="select2-results" role="listbox">
</ul>
</div>
</div>
<select title tabindex="-1" id="block-post-order-1-select" name="xform_demo[block-post-order-1]" class="xform-select-item " style="width: 40%; display: none;" rows="6">
<option/>
<option value="Desc" selected="selected">Lates</option>
<option value="rand">Random Posts</option>
</select>
</fieldset>
</td>
</tr>
<tr style="border-bottom: medium none;" class="compiler fold">
<th scope="row">
<div class="xform_field_th">
Block Style</div>
</th>
<td>
<fieldset id="xform_demo-block_type_1" class=" xform-container-image_select" data-id="block_type_1" data-type="image_select">
<div class="xform-table-container">
<ul class="xform-image-select">
<li class="xform-image-select">
<label class=" xform-image-select-selected xform-image-select block_type_1_1" for="block_type_1_1">
<input class=" compiler noUpdate " id="block_type_1_1" name="xform_demo[block_type_1]" value="node" checked="checked" type="radio"/>
<img src="1-3.png" class style=" width: 100%; "/>
</label>
</li>
<li class="xform-image-select">
<label class=" xform-image-select block_type_1_2" for="block_type_1_2">
<input class=" compiler noUpdate noUpdate " id="block_type_1_2" name="xform_demo[block_type_1]" value="nodey" type="radio"/>
<img src="1-4.png" class style=" width: 100%; "/>
</label>
</li>
</ul>
</div>
</fieldset>
</td>
</tr>
<tr style="display: none;" class="xform-section-indent-start">
<th scope="row"/>
<td/>
</tr>
</table>
【讨论】:
完美的代码,但是当删除任何字段数没有减少时,我们该怎么做呢?【参考方案2】:在谈论可能的解决方案之前,我会尝试转述以确认我对问题陈述的理解是正确的......
-
您有一些 HTML 将被克隆以附加到容器中
按钮会触发追加
克隆的 HTML 上的多个属性中的计数器必须递增
OP 和我建议的解决方案都没有考虑其他常见的可能情况:
-
删除元素后必须发生的情况:
会重新计算计数器吗?
计数器之间是否允许有间隙?
等等……
无论如何,现在谈论解决方案,我不会使用OP中给出的代码。相反,我将提供一种通用方法,并将实际实施留作家庭作业:
HTML:
<!-- Container which will hold your elements -->
<div class="container">
<!-- Original element, this block will be duplicated -->
<div class="element">
<input id="input1id" class="input1class" name="input1name" />
</div>
</div>
<button type="button" id="trigger">Append Copy</button>
jQuery:
$(document).ready(function()
// HTML to copy. Used an uncommon string (@@) as place holder for actual counter
var elementCopy = '<div class="element">'+
' <input id="input@@id" class="input@@class" name="input@@name" />'+
' </div>';
$('#trigger').on('click', function()
var count = $('.element').length; // number of elements with class "element"
var counter = count + 1; // Counter to use for new element(s)
var clone = elementCopy.replace(/\@\@/g, counter); // Substitute counter for all @@ in elementCopy; note the 'g' switch (global) in regex
$('.container').append(clone); // Finally append new HTML
)
);
检查this fiddle。
【讨论】:
以上是关于jQuery 克隆表单增加 name、class、id、data-id ..etc 的所有属性的主要内容,如果未能解决你的问题,请参考以下文章
jQuery---jq操作标签文本(html(),text()),jq操作文档标签(插入,删除,修改),克隆,,jq操作属性,jq操作class属性,jq操作表单value,jq操作css,jq操作盒