我内置了一个Web简历生成器,以学习如何为Web开发。我制作了一个HTML表单,用户可以添加更多字段来添加有关他的更多信息。示例:他具有多个专业经验,但是该表格以一个prof-exp字段开头。因此,他单击“添加新exp”按钮,然后JS为此创建了一个新字段。我使用了jQuery的clone()
方法来执行此操作,但这使我遇到了下面列出的问题。另外,这是我编写的代码:
var index = 0;
$(document).ready(() => {
$("#add-exp").click(() => {
$("#professional").clone().attr("id", "professional" + index++).
appendTo("#professional-info").find("select, input, textarea").val("");
})
})
<!DOCTYPE html>
<html>
<body>
<form action="" method="GET" id="main">
<fieldset id="professional-info">
<legend><h2>professional experience</h2></legend>
<div id="professional">
<label for="level">Nível: <select name="level" id="level" >
<option value="empty">Selecione</option>
<option value="estagio">Estágio</option>
<option value="junior-trainee">Junior/Trainee</option>
<option value="aux-opera">Auxiliar/Operacional</option>
<option value="pleno">Pleno</option>
<option value="senior">Sênior</option>
<option value="sup-coord">Supervisão/Coordenação</option>
<option value="gerencia">Gerência</option>
</select></label>
<label for="position"> Cargo: <input type="text" name="carrer" id="carrer" ></label><br>
<label for="company"> Empresa: <input type="text" name="company" id="company" ></label><br>
<label for="begin"> Início: <input type="month" name="begin" id="begin" ></label>
<label for="break"> Término: <input type="month" name="break" id="break" ></label>
<label for="stl-work"><input type="checkbox" name="stl-work" id="stl-work" >Ainda trabalho aqui</label><br>
<label for="job-desc"> Descrição: <textarea name="job-desc" id="job-desc" placeholder="Conte um pouco sobre o que você fazia lá." cols="40" rows="1"></textarea></label>
<button type="button" id="remove-exp" >Remove this professional xp</button>
</div>
<button type="button" form="main" id="add-exp">Add other professional exp</button>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>
问题是:
只有div具有动态ID,这会导致以下两个其他问题;
我不知道如何实现删除按钮逻辑,因为我无法区分第一个按钮和其他div中的其他按钮;
由于标签使用其对应的输入ID进行引用,因此当用户单击标签时,它们将指向第一个字段输入;
我希望你们能理解我的问题并帮助我。另外,对不起我的英语-我也在学习。谢谢你们!
答案 0 :(得分:0)
如果您已经将输入内容包装在标签中,则不再需要ID,
并且您可以将this
用作删除按钮的参数,以便可以使用它来删除您的区块。
请检查以下示例
$(function(){
// keep the first block hidden as an empty template
$('.form-row:first').hide();
// trigger add new item
AddItem();
})
function AddItem(){
var container = $('#container');
// clone the form, show it & append before add button
var cloned = $('.form-row:first').clone().show().insertBefore($('#addBtn'));
}
function RemoveItem(elm){
// get form element & remove it
$(elm).closest('.form-row').remove()
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style type="text/css">
.form-row {border:1px solid #ccc; margin:5px 0;padding:10px;}
</style>
<div id="container">
<div class="form-row">
<!-- wrap your input inside label tag to avoid using id as reference -->
<label>Field 1 : <input type="text" name="field1"></label>
<label>Field 2 : <input type="text" name="field2"></label>
<input type="button" value="Remove this item" onclick="RemoveItem(this)">
</div>
<input id="addBtn" type="button" value="Add new item" onclick="AddItem()">
</div>
答案 1 :(得分:0)
如建议的那样,Vue.js很酷,但是 jQuery 也具有一些被遗忘的功能。
而且,由于您是动态创建元素的,因此请勿使用ID。
然后将您的体验以数组[]
的形式提交给后端:即name="carrer[]"
,name="company[]"
等。在后端循环上,这些数据数组可以检索所有用户体验。
const new_exp = () => $('<div>', {
'class': 'professional-exp',
html: `
<label>Nível:
<select name="level[]">
<option value="empty">Selecione</option>
<option value="estagio">Estágio</option>
<!-- etc... -->
</select>
</label>
<label>Cargo: <input type="text" name="carrer[]"></label><br>
<label>Empresa: <input type="text" name="company[]"></label><br>
<label>Início: <input type="month" name="begin[]"></label>
<label>Término: <input type="month" name="break[]" ></label>
<label><input type="checkbox" name="stl-work[]"> Ainda trabalho aqui</label><br>
<label>Descrição: <textarea name="job-desc[]" placeholder="Conte um pouco sobre o que você fazia lá." cols="40" rows="1"></textarea></label><br>
`,
append: $('<button>', {
type: 'button',
text: 'Remove',
click() {
$(this).closest('.professional-exp').remove();
}
}),
appendTo: '#professional',
});
jQuery($ => { // DOM ready and $ alias in scope
new_exp(); // On init (Create first exp)
$("#new_exp").on('click', new_exp); // On click
});
.professional-exp {
padding: 10px;
margin-bottom: 10px;
background: #eee;
}
<form action="" method="POST" id="main">
<fieldset>
<legend>
<h2>Professional experience</h2>
</legend>
<div id="professional"></div>
<button type="button" id="new_exp">+ Add more</button>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
上面我们在模板中定义了Remove的button动作,但是如果您愿意,还可以将按钮硬编码到模板中,并创建动态点击处理程序(使用jQuery的.on()
),如下所示:
const exp_new = () => $('<div>', {
'class': 'professional-exp',
html: `
<label>Nível:
<select name="level[]">
<option value="empty">Selecione</option>
<option value="estagio">Estágio</option>
<!-- etc... -->
</select>
</label>
<label>Cargo: <input type="text" name="carrer[]"></label><br>
<label>Empresa: <input type="text" name="company[]"></label><br>
<label>Início: <input type="month" name="begin[]"></label>
<label>Término: <input type="month" name="break[]" ></label>
<label><input type="checkbox" name="stl-work[]"> Ainda trabalho aqui</label><br>
<label>Descrição: <textarea name="job-desc[]" placeholder="Conte um pouco sobre o que você fazia lá." cols="40" rows="1"></textarea></label><br>
<button class="exp_delete">REMOVE</button>
`,
appendTo: '#professional',
});
jQuery($ => { // DOM ready and $ alias in scope
exp_new(); // On init (Create first exp)
$("#exp_new").on('click', exp_new); // and on click.
$('#main').on('click', '.exp_delete', ev => $(ev.target).closest('.professional-exp').remove());
});
.professional-exp {
padding: 10px;
margin-bottom: 10px;
background: #eee;
}
<form action="" method="POST" id="main">
<fieldset>
<legend>
<h2>Professional experience</h2>
</legend>
<div id="professional"></div>
<button type="button" id="exp_new">+ Add more</button>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
答案 2 :(得分:0)
演示代码的详细信息在代码本身中进行了注释。 <fieldset>
和<button>
的某些类进行了较小的更改。结构有所更改,因此请记住这一点。 jQuery是通用的,它允许您泛化DOM操作并消除对id的依赖-仅使用类是很有可能的。
注册到动态标签的事件将失败,除非您委派事件。要将click事件委托给当前和将来存在的所有按钮,请注册一个按钮通常共享的祖先标记(例如#main
)。然后在第二个参数(事件数据)中分配按钮的选择器:
$('#main').on('click', '.add, .remove', function(e) {...
关于通过单击嵌套按钮来删除a的方法-$(e.target)
和$(this)
可用于引用当前单击的按钮。当您需要找到单击按钮的合适祖先(例如.professional
)时,请使用.closest()
方法,如下所示:
$(e.target).closest('.professional').remove();
let index = 0;
// Hide the first .remove button
$('#remove').hide();
/*
Register the form to the click event
Event data directs .add and .remove buttons
*/
$("#main").on('click', '.add, .remove', function(e) {
// if the clicked button has .add
if ($(this).hasClass('add')) {
/*
clone the first .professional
increment counter
Reference all form controls of the clone
on each form control modify its id
*/
const dupe = $(".professional:first").clone(true, true);
index++;
const formControls = dupe.find('select, button, input, textarea');
formControls.each(function() {
let ID = $(this).attr('id');
$(this).attr('id', ID + index);
});
/*
Remove the legend from clone
Show the .add and .remove on clone
Hide the clicked button
Add clone to form
Stop event bubbling
*/
dupe.find('legend').remove();
dupe.find('.add, .remove').show();
$(e.target).hide();
$('#main').append(dupe);
e.stopPropagation();
// Otherwise if clicked button has .remove...
} else if ($(e.target).hasClass('remove')) {
/*
Find clicked button ancestor .professional and remove
it.
Hide all .add buttons
Show the last .add
Stop event bubbling
*/
$(e.target).closest('.professional').remove();
$('.add').hide();
$('.add:last').show();
e.stopPropagation();
} else {
// Otherwise just stop event bubbling
e.stopPropagation();
}
});
:root {
font: 400 14px/1 Consolas
}
fieldset {
width: fit-content
}
legend {
margin-bottom: -15px
}
label {
display: block
}
input,
select,
button {
display: inline-block;
font: inherit;
height: 3ex;
line-height: 3ex;
vertical-align: middle
}
.text input {
width: 24ch
}
select {
line-height: 4ex;
height: 4ex;
}
label b {
display: inline-block;
width: 7.5ch;
}
button {
position: absolute;
display: inline-block;
height: initial;
margin: 0;
}
.add {
position: absolute;
right: 0;
}
[for=level] b {
width: 6ch
}
.btn-grp {
position: relative;
width: 97%;
min-height: 26px;
padding: 0
}
<!DOCTYPE html>
<html>
<head></head>
<body>
<form action="" method="GET" id="main">
<fieldset class="professional">
<legend>
<h2>Professional Experience</h2>
</legend>
<label for="level">
<b>Nível: </b>
<select name="level" id="level">
<option value="empty">Selecione</option>
<option value="estagio">Estágio</option>
<option value="junior-trainee">
Junior/Trainee
</option>
<option value="aux-opera">
Auxiliar/Operacional
</option>
<option value="pleno">Pleno</option>
<option value="senior">Sênior</option>
<option value="sup-coord">
Supervisão/Coordenação
</option>
<option value="gerencia">
Gerência
</option>
</select>
</label>
<fieldset class='text'>
<label for="carrier"><b>Cargo: </b>
<input type="text" name="carrer" id="carrer">
</label>
<label for="company"><b>Empresa: </b>
<input type="text" name="company" id="company">
</label>
<label for="begin"><b>Início: </b>
<input type="month" name="begin" id="begin">
</label>
<label for="break"><b>Término: </b>
<input type="month" name="break" id="break">
</label>
</fieldset>
<label for="stl-work">
<input type="checkbox" name="stl-work" id="stl-work" >Ainda trabalho aqui
</label>
<label for="job-desc"><b>Descrição: </b></label>
<textarea name="job-desc" id="job-desc" placeholder="Conte um pouco sobre o que você fazia lá." cols="35" rows="1"></textarea>
<fieldset class='btn-grp'>
<button type="button" id='remove' class='remove'>Remove</button>
<button type="button" id='add' class="add">Add</button>
</fieldset>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>
答案 3 :(得分:-1)
将新的“删除”按钮与其“专业” div相连的一种方法是在事件处理程序中添加一条额外的语句,以将其id与新div的id并行更新,例如:
let lastIndex = index - 1;
$("#professional" + lastIndex).find("button").attr("id", "add-exp" + lastIndex);
(此代码可能没有正确的语法-我不太使用jQuery-但您可以看到这个主意。)
更好的方法可能是,当单击“删除”按钮时,不要根据ID删除,而是找到closest祖先div并删除该div。
对于标签,您应该省略id
(因为同一页面上的两个元素都不应具有相同的id
)。并且由于输入嵌套在标签中,因此您还应该能够省去for
属性并使关联隐式。 (请参见https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label。)