let addMoreInputs = document.querySelectorAll('.addMoreInputs')
let addSections = document.querySelectorAll('.addSections')
let fieldTags = ['Second', 'Third', 'Fourth', 'Fifth', 'Sixth']
for (let addMore of addMoreInputs) {
let counter = -1
addMore.onclick = () => {
counter = counter + 1
let inputType = addMore.parentElement.childNodes[1].childNodes[1]
let moreDetails = inputType.parentElement.parentElement.parentElement.childNodes[3];
let moreStartDate = `
<input type="date" placeholder="Start Date" name="dates" aria-autocomplete="none" autocomplete="off" id="startDate" title=" ${ fieldTags[ counter ] } Start Date" class="startDate placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest"
/>
`
let moreDayInput = `
<select name="aptDay" id="aptDay" title="${ fieldTags[ counter ] } Appointment Start Day"
class="aptDay placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest">
<option value="" class="text-xs md:font-semibold md:text-xs">
Pick a day
</option>
<option value="Monday" class="text-xs md:font-semibold md:text-xs">
Monday
</option>
<option value="Tuesday" class="text-xs md:font-semibold md:text-xs">
Tuesday
</option>
<option value="Wednesday" class="text-xs md:font-semibold md:text-xs">
Wednesday
</option>
<option value="Thursday" class="text-xs md:font-semibold md:text-xs">
Thursday
</option>
<option value="Friday" class="text-xs md:font-semibold md:text-xs">
Friday
</option>
<option value="Saturday" class="text-xs md:font-semibold md:text-xs">
Saturday
</option>
<option value="Sunday" class="text-xs md:font-semibold md:text-xs">
Sunday
</option>
</select>
`
let inputWrapper = document.createElement('div')
inputWrapper.classList.add('relative', 'flex', 'items-center', 'w-full')
let inputHolder = document.createElement('div')
inputHolder.classList.add('w-full')
let deleteDateInput = document.createElement('span')
deleteDateInput.innerHTML = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 p-1 rounded-full text-rose-600 ml-2 deleteExtraDateInput cursor-pointer ease-in-out duration-300">
<path fill-rule="evenodd" d="M16.5 4.478v.227a48.816 48.816 0 013.878.512.75.75 0 11-.256 1.478l-.209-.035-1.005 13.07a3 3 0 01-2.991 2.77H8.084a3 3 0 01-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 01-.256-1.478A48.567 48.567 0 017.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 013.369 0c1.603.051 2.815 1.387 2.815 2.951zm-6.136-1.452a51.196 51.196 0 013.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 00-6 0v-.113c0-.794.609-1.428 1.364-1.452zm-.355 5.945a.75.75 0 10-1.5.058l.347 9a.75.75 0 101.499-.058l-.346-9zm5.48.058a.75.75 0 10-1.498-.058l-.347 9a.75.75 0 001.5.058l.345-9z" clip-rule="evenodd" />
</svg>
`
if (inputType.getAttribute('id') === 'startDate') {
inputHolder.innerHTML = moreStartDate
}
if (inputType.getAttribute('id') === 'aptDay') {
inputHolder.innerHTML = moreDayInput
}
if (inputType.getAttribute('id') === 'aptTimeSlot') {
inputHolder.innerHTML = moreTimeSlotInput
}
inputWrapper.appendChild(inputHolder)
inputWrapper.appendChild(deleteDateInput)
moreDetails.appendChild(inputWrapper)
let deleteExtraDateInput = document.querySelectorAll('.deleteExtraDateInput')
for (let delDateTag of deleteExtraDateInput) {
delDateTag.onclick = () => {
counter = -1
let parentElement = delDateTag.parentElement.parentElement.parentElement;
parentElement.lastElementChild.remove();
}
}
}
}
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<div class="categoryFields md:grid md:grid-cols-1 md:gap-x-10">
<!-- Start Date -->
<div class="relative h-fit flex flex-col startDateWrapper">
<div class="default w-full flex items-center">
<div class="grow relative">
<input type="date" placeholder="Start Date" name="dates" aria-autocomplete="none" autocomplete="off" id="startDate" title="Appointment Start Date" class="aptStartDate placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest"
/>
</div>
<div class="addMoreInputs ml-5 cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 text-indigo-600">
<path fill-rule="evenodd"
d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zM12.75 9a.75.75 0 00-1.5 0v2.25H9a.75.75 0 000 1.5h2.25V15a.75.75 0 001.5 0v-2.25H15a.75.75 0 000-1.5h-2.25V9z"
clip-rule="evenodd" />
</svg>
</div>
</div>
<div class="additionalDates addSections grid grid-cols-1 gap-x-10" name="Appointment Start Date">
</div>
</div>
<!-- Start Day -->
<div class="relative h-fit flex flex-col">
<div class="default w-full flex items-center">
<div class="grow relative">
<select name="days" id="aptDay" title="Appointment Start Day" class="aptDay placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest">
<option value="" class="text-xs md:font-semibold md:text-xs">
Pick a day
</option>
<option value="Monday" class="text-xs md:font-semibold md:text-xs">
Monday
</option>
<option value="Tuesday" class="text-xs md:font-semibold md:text-xs">
Tuesday
</option>
<option value="Wednesday" class="text-xs md:font-semibold md:text-xs">
Wednesday
</option>
<option value="Thursday" class="text-xs md:font-semibold md:text-xs">
Thursday
</option>
<option value="Friday" class="text-xs md:font-semibold md:text-xs">
Friday
</option>
<option value="Saturday" class="text-xs md:font-semibold md:text-xs">
Saturday
</option>
<option value="Sunday" class="text-xs md:font-semibold md:text-xs">
Sunday
</option>
</select>
</div>
<div class="addMoreInputs ml-5 cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 text-indigo-600">
<path fill-rule="evenodd"
d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zM12.75 9a.75.75 0 00-1.5 0v2.25H9a.75.75 0 000 1.5h2.25V15a.75.75 0 001.5 0v-2.25H15a.75.75 0 000-1.5h-2.25V9z"
clip-rule="evenodd" />
</svg>
</div>
</div>
<div class="additionalDay addSections grid grid-cols-1 gap-x-10" name="Appointment Start Day">
</div>
</div>
</div>
我有一个表单,其中有一个日期输入标记,可以通过在表单中添加日期输入标记来添加多个日期。所有新添加的日期标记都有动态类和标题。
添加动态类和标题工作正常。
然而,假设我在表单中又添加了3个日期标签,它们有自己的类和标题,如secondDate、thirdDate和fourthDate。
但当我删除thirdDate输入标记时,剩余日期标记的类和标题应更新为secondDate和thirdDate(thirdDate标签的类和名称应更新为thirdDate)
我尝试添加一个计数器来更新计数,但当我删除日期标记时,它不起作用。
当删除特定的日期标记并再次添加时,如何更新类名和标题,以确保顺序正确?
编辑:添加了代码段。
对原始HTML进行一些小修改后,例如:-
- 将
data-type
属性添加到反映要添加的标题类型的两个div.addSections
容器中 - 从这些相同的div元素中删除了毫无意义且无效的
name
属性 - 创建了一个新的
SVG
,在文档底部有一个defs
部分,以便path
元素可以存储在那里,分配ID,并使用use
元素在HTML中引用,以避免不必要地复制SVG内容
有了这些微小的更改,一个静态渲染的示例在上面命名的DIV元素中复制了3个动态添加的元素。示例HTML没有写入任何title
属性-这些title
属性仅在此处动态写入,以方便复制用户添加新内容时可能发生的情况。
这些标题属性的delete
和re-sequence
是这个答案的焦点,因此下面没有描述add
元素的原始代码,也没有描述图标或原始形式元素。
为了观察效果,在&在从DOM中删除之后。每次元素&它的子元素被移除,从而正确地反映顺序位置。
const fieldTags = ['Second', 'Third', 'Fourth', 'Fifth', 'Sixth'];
const suffix=' Appointment Start ';
/**************************************************
This ONLY adds the title to the input or select
to replicate(!) what would happend when a user
clicks on the "Add" button/icon.
This is for setup here only!!!
Mouseover each of the 3 items in each `addSections`
div to view the title assigned. Note they are named
as per the fieldTags variable for that item's DOM
position index & array position.
*/
document.querySelectorAll('.addSections').forEach(div=>{
div.querySelectorAll('input[type="date"],select').forEach( (n,index)=>{
let type=div.dataset.type;
let title=fieldTags[ index ] + suffix + type;
n.title=title;
})
});
/*************************************************
To re-sequence the names of dynamically added
content when the `delete` svg icon is clicked
this queries the DOM after the input element
& it's parent have been removed from the DOM
using `querySelectorAll`
The nodelist is iterated through using `forEach`
which can take 3 arguments, the second of which
is the elements index within the nodelist.
This index is used to build the new title based
upon the fieldTags array.
The event listener is a delegated listener bound
to the document ( or suitable parent container )
and responds ONLY to clicks on the delete SVG.
*/
document.addEventListener('click',e=>{
if( e.target.hasAttribute('href') || e.target.querySelector('use').hasAttribute('href') ){
let parent=e.target.closest('div.relative');
let section=parent.closest('.addSections');
parent.parentNode.removeChild( parent );
section.querySelectorAll('div.relative').forEach( ( div, index )=>{
div.querySelector('input,select').title=fieldTags[ index ] + suffix + section.dataset.type;
})
}
});
.addSections{
margin:3rem 0;
border:1px dotted grey;
padding:1rem
}
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<!-- example rendered HTML -->
<!-- additional start dates -->
<div class='addSections' data-type='Date'>
<div class='relative flex items-center w-full'>
<div class='w-full'>
<input type='date' placeholder='Start Date' name='dates' aria-autocomplete='none' autocomplete='off' class='startDate placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest'>
</div>
<span>
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor' class='w-6 h-6 p-1 rounded-full text-rose-600 ml-2 deleteExtraDateInput cursor-pointer ease-in-out duration-300'>
<use href="#trash" />
</svg>
</span>
</div>
<div class='relative flex items-center w-full'>
<div class='w-full'>
<input type='date' placeholder='Start Date' name='dates' aria-autocomplete='none' autocomplete='off' class='startDate placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest'>
</div>
<span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 p-1 rounded-full text-rose-600 ml-2 deleteExtraDateInput cursor-pointer ease-in-out duration-300">
<use href="#trash" />
</svg>
</span>
</div>
<div class='relative flex items-center w-full'>
<div class='w-full'>
<input type='date' placeholder='Start Date' name='dates' aria-autocomplete='none' autocomplete='off' class='startDate placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest'>
</div>
<span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 p-1 rounded-full text-rose-600 ml-2 deleteExtraDateInput cursor-pointer ease-in-out duration-300">
<use href="#trash" />
</svg>
</span>
</div>
</div>
<!-- additional start days -->
<div class='addSections' data-type='Day'>
<div class='relative flex items-center w-full'>
<div class='w-full'>
<select name='aptDay' class='aptDay placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest'>
<option selected hidden disabled class='text-xs md:font-semibold md:text-xs'>Pick a day
<option value='Monday' class='text-xs md:font-semibold md:text-xs'>Monday</option>
<option value='Tuesday' class='text-xs md:font-semibold md:text-xs'>Tuesday
<option value='Wednesday' class='text-xs md:font-semibold md:text-xs'>Wednesday
<option value='Thursday' class='text-xs md:font-semibold md:text-xs'>Thursday
<option value='Friday' class='text-xs md:font-semibold md:text-xs'>Friday
<option value='Saturday' class='text-xs md:font-semibold md:text-xs'>Saturday
<option value='Sunday' class='text-xs md:font-semibold md:text-xs'>Sunday
</select>
</div>
<span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 p-1 rounded-full text-rose-600 ml-2 deleteExtraDateInput cursor-pointer ease-in-out duration-300">
<use href="#trash" />
</svg>
</span>
</div>
<div class='relative flex items-center w-full'>
<div class='w-full'>
<select name='aptDay' class='aptDay placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest'>
<option selected hidden disabled class='text-xs md:font-semibold md:text-xs'>Pick a day
<option value='Monday' class='text-xs md:font-semibold md:text-xs'>Monday</option>
<option value='Tuesday' class='text-xs md:font-semibold md:text-xs'>Tuesday
<option value='Wednesday' class='text-xs md:font-semibold md:text-xs'>Wednesday
<option value='Thursday' class='text-xs md:font-semibold md:text-xs'>Thursday
<option value='Friday' class='text-xs md:font-semibold md:text-xs'>Friday
<option value='Saturday' class='text-xs md:font-semibold md:text-xs'>Saturday
<option value='Sunday' class='text-xs md:font-semibold md:text-xs'>Sunday
</select>
</div>
<span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 p-1 rounded-full text-rose-600 ml-2 deleteExtraDateInput cursor-pointer ease-in-out duration-300">
<use href="#trash" />
</svg>
</span>
</div>
<div class='relative flex items-center w-full'>
<div class='w-full'>
<select name='aptDay' class='aptDay placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest'>
<option selected hidden disabled class='text-xs md:font-semibold md:text-xs'>Pick a day
<option value='Monday' class='text-xs md:font-semibold md:text-xs'>Monday</option>
<option value='Tuesday' class='text-xs md:font-semibold md:text-xs'>Tuesday
<option value='Wednesday' class='text-xs md:font-semibold md:text-xs'>Wednesday
<option value='Thursday' class='text-xs md:font-semibold md:text-xs'>Thursday
<option value='Friday' class='text-xs md:font-semibold md:text-xs'>Friday
<option value='Saturday' class='text-xs md:font-semibold md:text-xs'>Saturday
<option value='Sunday' class='text-xs md:font-semibold md:text-xs'>Sunday
</select>
</div>
<span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 p-1 rounded-full text-rose-600 ml-2 deleteExtraDateInput cursor-pointer ease-in-out duration-300">
<use href="#trash" />
</svg>
</span>
</div>
</div>
<svg>
<defs>
<path id="plus" fill-rule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75
9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zM12.75
9a.75.75 0 00-1.5 0v2.25H9a.75.75 0 000 1.5h2.25V15a.75.75 0 001.5
0v-2.25H15a.75.75 0 000-1.5h-2.25V9z"
clip-rule="evenodd" />
<path id="trash" fill-rule="evenodd" d="M16.5 4.478v.227a48.816 48.816 0
013.878.512.75.75 0 11-.256 1.478l-.209-.035-1.005 13.07a3 3 0 01-2.991
2.77H8.084a3 3 0 01-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 01-.256-1.478A48.567
48.567 0 017.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 013.369
0c1.603.051 2.815 1.387 2.815 2.951zm-6.136-1.452a51.196 51.196 0 013.273 0C14.39
3.05 15 3.684 15 4.478v.113a49.488 49.488 0 00-6 0v-.113c0-.794.609-1.428
1.364-1.452zm-.355 5.945a.75.75 0 10-1.5.058l.347 9a.75.75 0
101.499-.058l-.346-9zm5.48.058a.75.75 0 10-1.498-.058l-.347 9a.75.75
0 001.5.058l.345-9z"
clip-rule="evenodd" />
</defs>
</svg>
看了上面的Javascript之后的一个观察,你有:
delDateTag.parentElement.parentElement.parentElement;
parentElement.lastElementChild.remove();
你可能会发现它更容易:
- 使用委托的事件侦听器,而不是单独向每个图标添加
onclick
- 使用
node.closest(expr)
来确定合适的父元素