动态更新输入标记的属性"Title"



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进行一些小修改后,例如:-

  1. data-type属性添加到反映要添加的标题类型的两个div.addSections容器中
  2. 从这些相同的div元素中删除了毫无意义且无效的name属性
  3. 创建了一个新的SVG,在文档底部有一个defs部分,以便path元素可以存储在那里,分配ID,并使用use元素在HTML中引用,以避免不必要地复制SVG内容

有了这些微小的更改,一个静态渲染的示例在上面命名的DIV元素中复制了3个动态添加的元素。示例HTML没有写入任何title属性-这些title属性仅在此处动态写入,以方便复制用户添加新内容时可能发生的情况。

这些标题属性的deletere-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();

你可能会发现它更容易:

  1. 使用委托的事件侦听器,而不是单独向每个图标添加onclick
  2. 使用node.closest(expr)来确定合适的父元素

最新更新