jquery 如何从动态标签中获取数组数据并删除当前标签

How to get array data from dynamic tabs and delete current tabs by jquery

我正在创建动态标签。我目前面临两个问题:

  1. 当我点击跨度 x 删除当前标签时,它会删除我所有的标签。
  2. 当我获取数组数据时,它总是只获取第一个选项卡数据。

谁能帮我解决这个问题?我尝试了很多方法,但仍然无法获得我想要的结果。这是我的 fiddle Dynamic Tabs.

当前,当有两个选项卡“2023”和“2025”时,第二个问题的数组结果如下所示:

[{
  February: "1",
  January: "1",
  Year: "2023"
}, {
  February: "1",
  January: "1",
  Year: "2023"
}]

我的预期结果是:

[{
  February: "1",
  January: "1",
  Year: "2023"
}, {
  February: "1",
  January: "1",
  Year: "2025"
}]

$(document).ready(function() {
  addTab();
});

$('#add_tab').click(function() {
  addTab()
});

//delete current tab
$(".nav-tabs").on("click", "span", function() {
  var anchor = $(this).siblings('a');
  console.log(anchor)
  $(anchor.attr('href')).remove();
  $(this).parent().remove();
  $(".nav-tabs").children('a').first().click();
});

function addTab() {
  var nextTab = $(".nav-tabs").children().length;
  var date = new Date().getFullYear() + nextTab;

  // create the tab
  $('<a class="nav-link" href="#tab-' + date + '" data-toggle="tab">' + date + '</a><span> x </span>').appendTo('#tabs');

  // create the tab content
  var html = "";
  html += '<div class="tab-pane monthSettings" id="tab-' + date + '">';
  html += '<label><b>Year: </b></label>';
  html += '<input class="txtYear" type="text" value="' + date + '">';
  html += '<label><b>January: </b></label>';
  html += '<input class="txtJanuary" type="number" value="1">';
  html += '<label><b>February: </b></label>';
  html += '<input class="txtFebruary" type="number" value="1">';
  html += '</div>';

  //append to tab-content
  var test = $(html).appendTo('.tab-content');

  // make the new tab active
  $('#tabs a:last').tab('show');
}

//get array
$(document).on('click', '#btnGetArray', function(e) {
  var array = []
  $(".monthSettings").each(function() {
    let detail = {
      Year: $(".txtYear").val() || 0,
      January: $(".txtJanuary").val() || 0,
      February: $(".txtFebruary").val() || 0,
    }
    array.push(detail)
    console.log(array)
  });
});
@import url('http://getbootstrap.com/2.3.2/assets/css/bootstrap.css');
.container {
  margin-top: 10px;
}

.nav-tabs>a {
  display: inline-block;
  position: relative;
  margin-right: 10px;
}

.nav-tabs>a>span {
  display: none;
  cursor: pointer;
  position: absolute;
  right: 6px;
  top: 8px;
  color: red;
}

.nav-tabs>a>span {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="https://getbootstrap.com/2.3.2/assets/js/bootstrap.js"></script>
<link rel="stylesheet" type="text/css" href="https://getbootstrap.com/2.3.2/assets/css/bootstrap.css">

<div class="bg-gray-300 nav-bg">
  <nav class="nav nav-tabs" id="tabs">
    <a href="#" class="add-contact" id="add_tab">+ Add Year</a>
  </nav>
</div>
<div class="card-body tab-content"></div>

<button id="btnGetArray">GetData</button>

问题是因为您用于检索 .txtYear.txtJanuary.txtFebruary 的选择器只会查看 first 的值集合中的元素,无论它找到多少。

要更正此问题,您可以使用父元素中的 find()(您可以从 each() 循环中引用)来检索该迭代中的子元素。

更进一步,您可以通过使用 map() 而不是 each() 来构建数组来简化逻辑,但 find() 的使用保持不变。

此外,还可以对代码进行一些其他改进,例如确保所有事件处理程序都在 document.ready 内,并使用模板文字使 HTML 字符串连接更易于阅读.

jQuery($ => {
  $('#add_tab').on('click', addTab);

  addTab();

  $(".nav-tabs").on("click", "span", function() {
    var anchor = $(this).siblings('a');
    console.log(anchor)
    $(anchor.attr('href')).remove();
    $(this).parent().remove();
    $(".nav-tabs").children('a').first().click();
  });

  $(document).on('click', '#btnGetArray', e => {
    var array = $(".monthSettings").map((i, container) => ({
      Year: $(container).find('.txtYear').val() || 0,
      January: $(container).find('.txtJanuary').val() || 0,
      February: $(container).find('.txtFebruary').val() || 0,
    })).get();
    
    console.log(array);
  });
});

function addTab() {
  var nextTab = $(".nav-tabs").children().length;
  var date = new Date().getFullYear() + nextTab;

  $(`<a class="nav-link" href="#tab-${date}" data-toggle="tab">${date}</a><span> x </span>`).appendTo('#tabs');

  var html = `
    <div class="tab-pane monthSettings" id="tab-${date}">
      <label><b>Year: </b></label>
      <input class="txtYear" type="text" value="${date}" />
      <label><b>January: </b></label>
      <input class="txtJanuary" type="number" value="1" />
      <label><b>February: </b></label>
      <input class="txtFebruary" type="number" value="1" />
    </div>`
  var test = $(html).appendTo('.tab-content');

  // make the new tab active
  $('#tabs a:last').tab('show');
}
@import url('http://getbootstrap.com/2.3.2/assets/css/bootstrap.css');
.container {
  margin-top: 10px;
}

.nav-tabs>a {
  display: inline-block;
  position: relative;
  margin-right: 10px;
}

.nav-tabs>a>span {
  display: none;
  cursor: pointer;
  position: absolute;
  right: 6px;
  top: 8px;
  color: red;
}

.nav-tabs>a>span {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="https://getbootstrap.com/2.3.2/assets/js/bootstrap.js"></script>
<link rel="stylesheet" type="text/css" href="https://getbootstrap.com/2.3.2/assets/css/bootstrap.css">

<div class="bg-gray-300 nav-bg">
  <nav class="nav nav-tabs" id="tabs">
    <a href="#" class="add-contact" id="add_tab">+ Add Year</a>
  </nav>
</div>
<div class="card-body tab-content"></div>

<button id="btnGetArray">GetData</button>