【问题标题】:Html clone in JavascriptJavascript 中的 Html 克隆
【发布时间】:2017-08-31 23:02:20
【问题描述】:

我有这个 HTML 代码

<div class="render-form-editlayout-10">
  <div class="formeo-render formeo" id="formeo-rendered-1">
    <div class="f-stage" id="afd81782-0230-4bbf-a39d-774ba6b3f6cf">
      <div class="f-row" id="78501c81-ce36-4703-ae99-7e086a95c0d7">
        <div class="f-render-column" id="71dac9e6-03ed-4294-b60f-8d2466d1aa17" style="width: 100%;">
          <h1 id="5baec553-c31c-4d0b-a138-6d338deb1f4b">Contact</h1></div>
      </div>
      <div class="f-row" id="44a64baa-64e5-44ad-af51-bed0a0abf3ae">
        <div class="f-render-column" id="95128be9-b2cb-4c82-aea2-4dd84b247ac4" style="width: 50%;">
          <div class="f-field-group">
            <label for="293053b9-9769-4b06-8156-01d7a15995b3">First name</label>
            <input type="text" name="contact_first_name" id="293053b9-9769-4b06-8156-01d7a15995b3">
          </div>
        </div>
        <div class="f-render-column" id="17193931-bd81-452e-95ba-591f2246eb37" style="width: 50%;">
          <div class="f-field-group">
            <label for="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">Sur Name</label>
            <input type="text" name="contact_sur_name" id="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">
          </div>
        </div>
      </div>
      <div class="f-row" id="9ba99767-5ea4-40b2-b0a4-df252b210a3c">
        <div class="f-render-column f-render-column f-render-column" id="4fe9abe0-6944-4504-896b-44adfa58ade8" style="width: 100%;">
          <div class="f-field-group">
            <label for="8379e16f-f468-47c4-8149-ba606d4310ad">Email</label>
            <input type="text" name="contact_email" id="8379e16f-f468-47c4-8149-ba606d4310ad">
          </div>
        </div>
      </div>
      <div class="f-row" id="e5bd3083-fb17-4453-a875-b6024db9461f">
        <div class="f-render-column f-render-column f-render-column" id="b87b0913-9286-4233-afcb-e568e3017092" style="width: 100%;">
          <div class="f-field-group">
            <label for="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">Phone</label>
            <input type="number" class="form-control" name="contact_phone" id="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
<div class="render-form-editlayout-10">
  <div class="formeo-render formeo" id="formeo-rendered-1">
    <div class="f-stage" id="afd81782-0230-4bbf-a39d-774ba6b3f6cf">
      <div class="f-row" id="44a64baa-64e5-44ad-af51-bed0a0abf3ae">
        <div class="f-render-column" id="95128be9-b2cb-4c82-aea2-4dd84b247ac4" style="width: 50%;">
          <div class="f-field-group">
            <label for="293053b9-9769-4b06-8156-01d7a15995b3">First name</label>
            <input type="text" name="contact_first_name" id="293053b9-9769-4b06-8156-01d7a15995b3">
          </div>
        </div>
        <div class="f-render-column" id="17193931-bd81-452e-95ba-591f2246eb37" style="width: 50%;">
          <div class="f-field-group">
            <label for="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">Sur Name</label>
            <input type="text" name="contact_sur_name" id="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">
          </div>
        </div>
      </div>
      <div class="f-row" id="9ba99767-5ea4-40b2-b0a4-df252b210a3c">
        <div class="f-render-column f-render-column f-render-column" id="4fe9abe0-6944-4504-896b-44adfa58ade8" style="width: 100%;">
          <div class="f-field-group">
            <label for="8379e16f-f468-47c4-8149-ba606d4310ad">Email</label>
            <input type="text" name="contact_email" id="8379e16f-f468-47c4-8149-ba606d4310ad">
          </div>
        </div>
      </div>
      <div class="f-row" id="e5bd3083-fb17-4453-a875-b6024db9461f">
        <div class="f-render-column f-render-column f-render-column" id="b87b0913-9286-4233-afcb-e568e3017092" style="width: 100%;">
          <div class="f-field-group">
            <label for="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">Phone</label>
            <input type="number" class="form-control" name="contact_phone" id="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
<button class="btn btn-success cloneMe " data-id="10">+</button>

Js Fiddle 以上代码

因此,当您单击 + 按钮时,它应该克隆 html。

现在当它被克隆时,我想让它看起来像这样

Js Fiddle

catch 是输入类型的名称应该是递增的,如 , name_1 , name_2

我真的很困惑如何做到这一点

更新

正如下面的答案之一所述,可以使用按钮的data-id 访问 div 的 ID。那么我的问题是?是否可以只获取输入类型并在那里更改名称+数据ID并附加?

【问题讨论】:

  • pff 这不可能:)
  • 您的 ID 重复...
  • 为什么不用jquery来手动迭代修改呢?
  • @gaetanoM 我的意思是,可以改变结构,但我需要实际复制这些字段
  • @MateiMihai 我如何将 html 作为对象并对其进行迭代以查看我需要的内容,然后将其添加回来,看起来令人困惑,但你能给我一些其他的想法吗?\

标签: javascript jquery html


【解决方案1】:

这是对模板文字的公然滥用,但这里有一个简化版本,只是为了好玩 - 作为一般做法,我倾向于使用实际的模板库来处理这类事情(例如,Underscore 有一个相当简单的模板函数)。

addSubform = (function(){
  n = 0
  container = $('#container')
  return function(){
    n += 1
    container.append(`<div class="subform" id="subform${n}">
First Name: <input type="text" id="fname_${n}" name="fname_${n}" /><br />
Surname: <input type="text" id="sname_${n}" name="sname_${n}" /><br />
<hr />
</div>`)
  }
})()

$(document).ready(function(){
  addSubform()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">

</div>
<button onclick="addSubform()">+</button> 

如果您有任何可行的替代方案,我通常不会推荐另一个选项,但它使用正则表达式来查找名称属性并附加后缀。它并没有按预期工作,但我认为它足以说明这个概念。如果您使用开发工具进行检查,您会发现名称属性正在递增。

我在两个示例中都使用了闭包来管理范围。这是个人喜好,对于解决您的特定问题并不重要。

//I would probably not put this in a global,
//but since it's unclear it's being determined client-side,
//I'm considering that concern out of scope for this question.
//var formNum 

buildForm = function(formNum) {
  /*A lot going on in this line - call the Array's slice method
  against the HTML element collection matching the class name "f-row",
  supplying an index (zero-based) of 1 for the start. This effectively
  removes the first element. Then use .reduce to convert the HTML of
  the remaining elements to a string.
  */
  var base = Array.prototype.slice.call(
    document.getElementsByClassName('render-form-editlayout-' + formNum)[0].getElementsByClassName('f-row'), 1)
    .reduce(function(b,e){return b += e.outerHTML},"")
  
  var suffix = 0
  return function() {
    suffix += 1
    return base.replace(/name="([a-z_]+)"/gm,'name="$1_' + suffix + '"')
  }
}

addForm = function(formNum, builder){
  var container = document.getElementsByClassName('render-form-editlayout-' + formNum)[0].getElementsByClassName('f-stage')[0]
  return function() {
    container.innerHTML += builder()
  }
}

makeCloneEvent = function(num) {
	return addForm(num, buildForm(num))
}

$('.cloneMe').each(
	function() {
    el = $(this)
    el.on('click', makeCloneEvent(el.data('id')))
  }
)
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="form_container">
<div class="render-form-editlayout-10 form-model">
  <div class="formeo-render formeo" id="formeo-rendered-1">
    <div class="f-stage" id="afd81782-0230-4bbf-a39d-774ba6b3f6cf">
      <div class="f-row" id="78501c81-ce36-4703-ae99-7e086a95c0d7">
        <div class="f-render-column" id="71dac9e6-03ed-4294-b60f-8d2466d1aa17" style="width: 100%;">
          <h1 id="5baec553-c31c-4d0b-a138-6d338deb1f4b">Contact</h1></div>
      </div>
      <div class="f-row" id="44a64baa-64e5-44ad-af51-bed0a0abf3ae">
        <div class="f-render-column" id="95128be9-b2cb-4c82-aea2-4dd84b247ac4" style="width: 50%;">
          <div class="f-field-group">
            <label for="293053b9-9769-4b06-8156-01d7a15995b3">First name</label>
            <input type="text" name="contact_first_name" id="293053b9-9769-4b06-8156-01d7a15995b3">
          </div>
        </div>
        <div class="f-render-column" id="17193931-bd81-452e-95ba-591f2246eb37" style="width: 50%;">
          <div class="f-field-group">
            <label for="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">Sur Name</label>
            <input type="text" name="contact_sur_name" id="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">
          </div>
        </div>
      </div>
      <div class="f-row" id="9ba99767-5ea4-40b2-b0a4-df252b210a3c">
        <div class="f-render-column f-render-column f-render-column" id="4fe9abe0-6944-4504-896b-44adfa58ade8" style="width: 100%;">
          <div class="f-field-group">
            <label for="8379e16f-f468-47c4-8149-ba606d4310ad">Email</label>
            <input type="text" name="contact_email" id="8379e16f-f468-47c4-8149-ba606d4310ad">
          </div>
        </div>
      </div>
      <div class="f-row" id="e5bd3083-fb17-4453-a875-b6024db9461f">
        <div class="f-render-column f-render-column f-render-column" id="b87b0913-9286-4233-afcb-e568e3017092" style="width: 100%;">
          <div class="f-field-group">
            <label for="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">Phone</label>
            <input type="number" class="form-control" name="contact_phone" id="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">
          </div>
        </div>
      </div>
    </div>
 </div>
 <button  class="cloneMe" data-id='10'>Add +</button>

【讨论】:

  • 我喜欢第二个答案,但是当我克隆所有内容时有一个小问题得到克隆按钮并且标题也有办法解决这个问题吗?
  • @Vikram 更改我分配给base 变量的选择器应该可以做到。理想情况下,您只需将表单字段包装在某种元素中 - 可能是 div。如果这不可能,我认为需要更多的创造力。
  • 看看答案之一new_form.find('.f-row:first').remove();中提到的这行代码我试图在你的代码中实现这个,但它不起作用
  • 如果它有效,它会在每次创建新表单时添加额外的操作。我认为我们更愿意做相反的事情:选择所有的 f-row 元素 except 第一个。我还需要几个小时才能开始工作,但我想我看到了解决办法。
  • @Vikram Header/button 现在应该在第二个 sn-p 中正常工作。
【解决方案2】:

Updated fiddle.

使用[] 将字段命名为数组会更有效:

<div class="render-form-editlayout-10 form-model">
  <div class="formeo-render formeo" id="formeo-rendered-1">
    <div class="f-stage" id="afd81782-0230-4bbf-a39d-774ba6b3f6cf">
      <div class="f-row" id="78501c81-ce36-4703-ae99-7e086a95c0d7">
        <div class="f-render-column" id="71dac9e6-03ed-4294-b60f-8d2466d1aa17" style="width: 100%;">
          <h1 id="5baec553-c31c-4d0b-a138-6d338deb1f4b">Contact</h1></div>
      </div>
      <div class="f-row" id="44a64baa-64e5-44ad-af51-bed0a0abf3ae">
        <div class="f-render-column" id="95128be9-b2cb-4c82-aea2-4dd84b247ac4" style="width: 50%;">
          <div class="f-field-group">
            <label for="293053b9-9769-4b06-8156-01d7a15995b3">First name</label>
            <input type="text" name="contact_first_name[]" id="293053b9-9769-4b06-8156-01d7a15995b3">
          </div>
        </div>
        <div class="f-render-column" id="17193931-bd81-452e-95ba-591f2246eb37" style="width: 50%;">
          <div class="f-field-group">
            <label for="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">Sur Name</label>
            <input type="text" name="contact_sur_name[]" id="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">
          </div>
        </div>
      </div>
      <div class="f-row" id="9ba99767-5ea4-40b2-b0a4-df252b210a3c">
        <div class="f-render-column f-render-column f-render-column" id="4fe9abe0-6944-4504-896b-44adfa58ade8" style="width: 100%;">
          <div class="f-field-group">
            <label for="8379e16f-f468-47c4-8149-ba606d4310ad">Email</label>
            <input type="text" name="contact_email[]" id="8379e16f-f468-47c4-8149-ba606d4310ad">
          </div>
        </div>
      </div>
      <div class="f-row" id="e5bd3083-fb17-4453-a875-b6024db9461f">
        <div class="f-render-column f-render-column f-render-column" id="b87b0913-9286-4233-afcb-e568e3017092" style="width: 100%;">
          <div class="f-field-group">
            <label for="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">Phone</label>
            <input type="number" class="form-control[]" name="contact_phone" id="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
<button class="btn btn-success cloneMe " data-id="10">+</button>

然后通过向主 div 示例 form-model 添加一个类,您可以通过将点击事件附加到按钮来克隆表单,例如:

$('.cloneMe').click(function(){
  var new_form = $('.form-model').clone(true); //Clone form

  new_form.find('.f-row:first').remove(); //Remove title 'Contact' from the clone

  $('.form-model').append(new_form); //append new form
});

注意:唯一的问题是 id 属性应该是唯一的时重复的 id,所以如果您可以避免在原始 HTML 代码中使用 id,最好验证您的 HTML。 p>

希望这会有所帮助。

【讨论】:

  • 实际上它是一个生成表单的表单生成器,我正在尝试添加我自己的 hack 以添加一些功能:'(
  • 这样你就可以调整生成的表单(将[]添加到名称并删除id),然后在点击时克隆它。
  • 如果我添加 [] 然后在后端我必须更改 api 以及接受完整表单为 Json ,并创建一个表,输入类型的名称作为表头和值作为价值
  • Aaah 那你真的需要像你说的那样调整它们,检查这个jsfiddle.net/56sfx5ur/7
【解决方案3】:

我的建议是:

  • 克隆 render-form-editlayout-10 div
  • 为每个具有 id 的子克隆元素添加一个后缀,使用按钮 data-id
  • 增加按钮数据ID

$('.cloneMe').on('click', function (e) {
    var idToAppend = $(this).data('id');
    $(this).data('id', idToAppend + 1);
    $('div.render-form-editlayout-10:first').clone().find('[id]').attr('id', function (idx, val) {
        var newId = (this.name == undefined) ? val + idToAppend : this.name + '_' + idToAppend;
        if ((this.name != undefined)) {
            $(this).attr('name', newId);
            console.log('For elements with name the new ID is: ' +
                    newId + ' new Name is: ' + newId);
        }
        return newId;
    }).closest('div.render-form-editlayout-10').insertBefore(this);
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<div class="render-form-editlayout-10">
    <div class="formeo-render formeo" id="formeo-rendered-1">
        <div class="f-stage" id="afd81782-0230-4bbf-a39d-774ba6b3f6cf">
            <div class="f-row" id="78501c81-ce36-4703-ae99-7e086a95c0d7">
                <div class="f-render-column" id="71dac9e6-03ed-4294-b60f-8d2466d1aa17" style="width: 100%;">
                    <h1 id="5baec553-c31c-4d0b-a138-6d338deb1f4b">Contact</h1></div>
            </div>
            <div class="f-row" id="44a64baa-64e5-44ad-af51-bed0a0abf3ae">
                <div class="f-render-column" id="95128be9-b2cb-4c82-aea2-4dd84b247ac4" style="width: 50%;">
                    <div class="f-field-group">
                        <label for="293053b9-9769-4b06-8156-01d7a15995b3">First name</label>
                        <input type="text" name="contact_first_name" id="293053b9-9769-4b06-8156-01d7a15995b3">
                    </div>
                </div>
                <div class="f-render-column" id="17193931-bd81-452e-95ba-591f2246eb37" style="width: 50%;">
                    <div class="f-field-group">
                        <label for="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">Sur Name</label>
                        <input type="text" name="contact_sur_name" id="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">
                    </div>
                </div>
            </div>
            <div class="f-row" id="9ba99767-5ea4-40b2-b0a4-df252b210a3c">
                <div class="f-render-column f-render-column f-render-column" id="4fe9abe0-6944-4504-896b-44adfa58ade8" style="width: 100%;">
                    <div class="f-field-group">
                        <label for="8379e16f-f468-47c4-8149-ba606d4310ad">Email</label>
                        <input type="text" name="contact_email" id="8379e16f-f468-47c4-8149-ba606d4310ad">
                    </div>
                </div>
            </div>
            <div class="f-row" id="e5bd3083-fb17-4453-a875-b6024db9461f">
                <div class="f-render-column f-render-column f-render-column" id="b87b0913-9286-4233-afcb-e568e3017092" style="width: 100%;">
                    <div class="f-field-group">
                        <label for="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">Phone</label>
                        <input type="number" class="form-control" name="contact_phone" id="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<button class="btn btn-success cloneMe" data-id="10">+</button>

【讨论】:

  • 你能把它加到名字中吗?就像一个新名字contact_first_name_1,contact_first_nname_2
  • 是的,差不多了,但是下次克隆时,它会克隆所有现有的而不是一个,就像如果有两个,那么下一个克隆它变成 4 它应该是 3 对
  • 您可以简单地添加 :first 选择器以便只克隆第一个。这不是那么难。感谢分享。
  • $('.cloneMe').on('click', function(e) { var idToAppend = $(this).data('id'); $(this).data('id', idToAppend + 1); $('div.render-form-editlayout-10').clone(":first").find('[id]').attr('id', function(idx, val) { var newId = (this.name == undefined) ? val + idToAppend : this.name + '_' + idToAppend; if ((this.name != undefined)) { $(this).attr('name', newId);console.log('For elements with name the new ID is: ' +newId + ' new Name is: ' + newId);}return newId; }).closest('div.render-form-editlayout-10').insertBefore(this);}) 我厌倦了这个它不起作用
  • @Vikram 对不起。 :first 选择器只出现在此处:$('div.render-form-editlayout-10:first')。片段更新。让我知道。谢谢
【解决方案4】:

我对您的代码做了一些小改动以使其正常工作。我希望你不要介意。请根据需要进行更改。

JSfiddle

      <div class="render-form-editlayout-10">
        <div class="formeo-render formeo" id="formeo-rendered-1">

          <div class="f-stage" id="afd81782-0230-4bbf-a39d-774ba6b3f6cf">
            <div class="f-row" id="78501c81-ce36-4703-ae99-7e086a95c0d7">
              <div class="f-render-column" id="71dac9e6-03ed-4294-b60f-8d2466d1aa17" style="width: 100%;">
                <h1 id="5baec553-c31c-4d0b-a138-6d338deb1f4b">Contact</h1></div>
            </div>

            <div id="cloneme">
            <div class="f-row" id="44a64baa-64e5-44ad-af51-bed0a0abf3ae">
              <div class="f-render-column" id="95128be9-b2cb-4c82-aea2-4dd84b247ac4" style="width: 50%;">
                <div class="f-field-group">
                  <label for="293053b9-9769-4b06-8156-01d7a15995b3">First name</label>
                  <input type="text" name="contact_first_name" id="293053b9-9769-4b06-8156-01d7a15995b3">
                </div>
              </div>
              <div class="f-render-column" id="17193931-bd81-452e-95ba-591f2246eb37" style="width: 50%;">
                <div class="f-field-group">
                  <label for="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">Sur Name</label>
                  <input type="text" name="contact_sur_name" id="3d276a4f-1dff-4594-8fe8-56ac1acf58e4">
                </div>
              </div>
            </div>
            <div class="f-row" id="9ba99767-5ea4-40b2-b0a4-df252b210a3c">
              <div class="f-render-column f-render-column f-render-column" id="4fe9abe0-6944-4504-896b-44adfa58ade8" style="width: 100%;">
                <div class="f-field-group">
                  <label for="8379e16f-f468-47c4-8149-ba606d4310ad">Email</label>
                  <input type="text" name="contact_email" id="8379e16f-f468-47c4-8149-ba606d4310ad">
                </div>
              </div>
            </div>
            <div class="f-row" id="e5bd3083-fb17-4453-a875-b6024db9461f">
              <div class="f-render-column f-render-column f-render-column" id="b87b0913-9286-4233-afcb-e568e3017092" style="width: 100%;">
                <div class="f-field-group">
                  <label for="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">Phone</label>
                  <input type="number" class="form-control" name="contact_phone" id="a54606a2-679b-4e9c-8b90-f5f2c6e79ef0">
                </div>
              </div>
            </div>
            </div>
          </div>
        </div>
      </div>

<button id= "clone" class="btn btn-success cloneMe " data-id="10">+</button>


    $(document).ready(function(){
        $("#clone").click(function(){
            $("#cloneme").clone().appendTo("#afd81782-0230-4bbf-a39d-774ba6b3f6cf");
        });
    });

【讨论】:

  • 关键是输入类型的名称应该是递增的,比如,name_1,name_2这是哪里?
  • 正如我所说,这只是一个基本的想法,应该如何完成。还提到“请根据需要更改”。除非他想让我们做这份工作..
【解决方案5】:

在我看来,如果您不能使用先前答案中建议的 name='something[]' 模式,最好的方法是执行以下操作:

  1. 拥有您要克隆的所有表单元素的模板(所有标记)
  2. 在此标记中有一个字符串,每次克隆时都应将其替换为增量索引。 (例如&lt;input name="firstname__index__" ... /&gt;
  3. 每次您想要克隆时,只需在您的 HTML 中搜索并替换所有 __index__ 实例,然后再将新 HTML 附加到您的页面。

考虑这样的事情:

$clonedForm.find('input').each(function (i, ele) {
    var $input = $(ele);
    var name = $input.attr('name').replace('__index__', increment);
    $input.attr('name', name);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 2013-12-26
    • 2013-01-03
    • 2015-02-12
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    相关资源
    最近更新 更多