无法在jquery追加后更新输入字段



我有一个需要帮助的小应用程序。

  1. 我有一个选择和文本输入
  2. 当我从选择菜单中选择一个项目时,该值将显示在文本输入字段中
  3. 我可以使用JQuery动态添加额外的选择和文本输入字段
  4. 但是,当我从新添加的字段中选择一个项目时,输入字段不会更新

如果这是您可以修复的问题,我可以向您发送源代码吗?

下面是我的代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script>
<script>
$(function() {
$(".std").change(function() {
var agenum = $(this).find(":selected").val();
// var stdID = $(this).val();
// console.log(stdID);
$(".age").html("<input type='text' class='form-control' name='age[]' readonly placeholder='Age1' value=" + agenum + ">");
});
});
</script>

</head>
<body>
<div class="container">
<h2 class="display-2">Age of Person</h2>
<form action="">
<div id="addrow">

<div class="form-row">
<div class="col mt-3">
<select class="std form-control" id="std" name="std[]" required>
<option selected disabled>Select Student</option>
<option value="1">Michael</option>
<option value="2">Bridget</option>
<option value="3">Raphael</option>
</select>
</div>
<div class="col mt-3 age" id="age">
<input type="text" class="form-control" name="age[]" placeholder="Age" readonly>
</div>
<div class="col mt-3">
<button type="button" name="add" id="addmore" class="btn btn-success">+</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<script type="text/javascript">
$(document).ready(function() {
// get button id and assign variable for autoincrement
var i = 1;
$('#addmore').click(function() {
// Increment variable by 1
i++;
//Append text field by ID
$('#addrow').append('<div class="form-row" id="addnewrow' + i + '"><div class="col mt-3"><select class = "std'+i+ '" form-control" id = "std1'+i+ '" name = "std[]" required><option selected disabled>Select Student</option><option value="1">Michael</option><option value="2">Bridget</option><option value="3">Raphael</option></select></div><div class ="col mt-3 age'+i+ '" id="age'+i+ '"><input type="text" class="form-control" name="age[]" placeholder="Age" readonly></div><div class="col mt-3"><button class="remove btn btn-danger" id=' + i + '>-</button></div>');
});

//Remove input field when Remove is clicked
$(document).on('click', '.remove', function() {
var button = $(this).attr("id");
$('#addnewrow' + button + '').remove();
});
});
</script>
</body>
</html>

在这里您可以检查解决方案https://jsfiddle.net/ywaohx8z/

这里有一个问题:

$('#addrow').append('<div class="form-row" id="addnewrow' + i + '"><div class="col mt-3"><select class = "std form-control" id = "std1'+i+ '" name = "std[]" required><option selected disabled>Select Student</option><option value="1">Michael</option><option value="2">Bridget</option><option value="3">Raphael</option></select></div><div class ="col mt-3 age" id="age'+i+ '"><input type="text" class="form-control" name="age[]" placeholder="Age" readonly></div><div class="col mt-3"><button class="remove btn btn-danger" id=' + i + '>-</button></div>');

您必须检查";i〃;例如,因为您有一个名为"的类;年龄;您添加为";年龄2";。如果您稍后搜索类";年龄";,你找不到。

另一个问题是管理变更事件。如果你这样做:

$('.std').change(onStdChange);

您正在将onStdChange函数附加到std-select上的任何更改,但仅限于当前std元素。创建另一个事件时,还必须添加更改事件。

变更功能中还有另一个问题:

var onStdChange = function() {
var select = $(this).find(":selected");
var agenum = select.val();
var ageTag = select.closest('.form-row').find('.age input');                
ageTag.val(agenum);
}

"这个";是选择。我改为搜索关闭表单行,从这一点开始,搜索您的年龄类输入。然后,我更新输入值。

问题

"但是,当我从新添加的字段中选择一个项目时,输入字段不会更新">

注意,在该示例中;点击";事件被注册到CCD_ 1而不是CCD_。

$('form').on('click', '.del', function(e) {...

所有的删除按钮都是动态添加到DOM中的,也没有静态的(即页面加载时存在的(按钮。任何动态添加的元素都不能向其注册事件。因此,通过指定一个祖先元素(如<form>(作为事件侦听器,我们可以利用事件冒泡来侦听<form>的每个子元素。我们只将事件委托给我们想要的(在本例中为button.del(,而忽略其余元素。.on()方法的第二个参数(在示例中为'.del'(是我们希望被视为this的元素的选择器。

在OP代码中,<select>也受到了不利影响。请注意,在本例中,对于动态添加的<form>0 s,没有明显的事件委派,就像对于button.del一样。原因是它们被克隆了。jQuery方法.clone()有两个布尔参数:

const row = $(this).closest('.row').clone(true, true);
  • 如果true将保留克隆元素的数据和任何已注册事件,则第一个参数
  • 第二个参数iftrue也会将数据和任何已注册的事件保留给克隆的子级

建议

不要使用#id,因为它会阻碍您的编程方式。养成使用.class的习惯,熟悉用于遍历DOM的属性和方法。在该示例中没有#id,并且频繁使用.closest()方法。.closest()方法将从一个元素开始,并向上爬DOM树,查找给定祖先的第一个实例。让我们从示例中看一个:

<section class='row'>// '.row'
<div class='col'>       // 1.↖️ $(this).closest('.row')
<select class='std'> // this   
<option val='49'>zer00ne</option>
...
</select>
</div>   
// 2.⬇️          3.↘️ .find('.age')
<div class='col'>
<input class='age'>// '.age'
</div>
</section>
  1. 距离button.del1|2最近的.row。来自CCD_ 22|3查找.age
$(this).closest('.row').find('.age');

它看起来可能很多,但它非常灵活,而且记账#ids很乏味,代码也很有限。

下面的示例中对详细信息进行了评论

/* 
This is an array of objects (typical structure of a what a 
JSON resembles. Each object represents a student and each 
student has "name", "age", "gender", "email", and "gpa" 
(only "age" is of any relevance).
*/
const students=[{name:"Lorens Ousby",age:16,gender:"Male",email:"lousby0@tamu.edu",gpa:2.1},{name:"Caria Garrigan",age:17,gender:"Female",email:"cgarrigan1@vistaprint.com",gpa:.4},{name:"Sutton Measom",age:16,gender:"Male",email:"smeasom2@networkadvertising.org",gpa:3.4},{name:"Sybila Warlow",age:17,gender:"Female",email:"swarlow3@noaa.gov",gpa:1.6},{name:"Selena Ossulton",age:15,gender:"Female",email:"sossulton4@hp.com",gpa:3.2},{name:"Trina Habbon",age:18,gender:"Bigender",email:"thabbon5@mit.edu",gpa:2.8},{name:"Carlye Ferenc",age:18,gender:"Female",email:"cferenc6@slate.com",gpa:.7},{name:"Teodor Abberley",age:15,gender:"Male",email:"tabberley7@nps.gov",gpa:1.2},{name:"Dayna Trase",age:16,gender:"Female",email:"dtrase8@miitbeian.gov.cn",gpa:2.6}];
/*
Upon page load, each student object's "name" and "age" will be 
interpolated into a htmlString of an <option> which in turn 
will be rendered within select.std.
*/
students.forEach(s => {
$('.std').append(`<option value='${s.age}'>${s.name}</option>`);
});
/* Event Handling */
// Use `.on()` method instead of `.change()` or `.click()`
/*
Whenever a "change" event fires on any .sel, the event handler
showAge(e) will be invoked.
*/ 
$('.std').on('change', showAge);
// Whenever the user clicks button.add addRow(e) is called
$('.add').on('click', addRow);
/* 
form listens for any click event on button.del (2nd param 
designates '.del' as >this<. It gets the closest section.row 
from >this< and removes it.
*/
$('form').on('click', '.del', function(e) {
$(this).closest('.row').remove();
});
/* 
The explinations above should give you a good idea of what's 
going on with the rest of the code, if not ask in comments 
*/
function showAge(e) {
const ageV = $(this).val();
const ageO = $(this).closest('.row').find('.age');
ageO.val(ageV);
}
function addRow(e) {
const row = $(this).closest('.row').clone(true, true);
row.find('button')
.replaceWith(`<button class="btn btn-danger del" type="button">-</button>`);
$('form').append(row);
row.find('.age').val('');
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<main class="container">
<form>
<!--New Rows Here-->  
<section class="row">
<div class="col mt-3">
<select class="form-control std" name="std[]">
<option selected disabled>Select Student</option>
</select>
</div>
<div class="col mt-3">
<output class="form-control age" name="age[]"></output>
</div>
<div class="col mt-3">
<button class="btn btn-success add" type="button">+</button>
</div>
</section>
</form>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

最新更新