我有一个需要帮助的小应用程序。
- 我有一个选择和文本输入
- 当我从选择菜单中选择一个项目时,该值将显示在文本输入字段中
- 我可以使用JQuery动态添加额外的选择和文本输入字段
- 但是,当我从新添加的字段中选择一个项目时,输入字段不会更新
如果这是您可以修复的问题,我可以向您发送源代码吗?
下面是我的代码
<!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
将保留克隆元素的数据和任何已注册事件,则第一个参数 - 第二个参数if
true
也会将数据和任何已注册的事件保留给克隆的子级
建议
不要使用#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>
- 距离
button.del
1|2最近的.row
。来自CCD_ 22|3查找.age
$(this).closest('.row').find('.age');
它看起来可能很多,但它非常灵活,而且记账#id
s很乏味,代码也很有限。
下面的示例中对详细信息进行了评论
/*
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>