在我在项目表中创建的搜索栏中,当
<td>
是表的最后一行时,它工作正常并且不显示我为这种情况设置的错误消息,但是当 <td
> 值不在最后一行,例如,在我搜索结束前的行中,并显示一条错误消息。如何使用 JavaScript 为搜索栏编写更好的代码?
function search() {
let input, filter, table, tr, td, txtValue;
input = document.getElementById("search");
filter = input.value;
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (let i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.indexOf(filter) > -1) {
tr[i].classList.remove("hidden");
document.getElementById("error-message").classList.add("hidden");
}
else {
document.getElementById("error-message").classList.remove("hidden");
tr[i].classList.add("hidden");
}
}
}
}
html 代码:
@model IEnumerable<ProvinceLevel>
@{
ViewData["Title"] = "مدیریت - نمایش سطح استان";
}
<div class="btn btn-outline-primary btn-sm my-1 mx-3">نمایش سطح استان</div>
<div class="row m-0 p-0">
<div class="col-md-5 p-0 ml-3">
<input type="search" id="search" class="form-control w-100" placeholder="نام کاربری" maxlength="10" />
</div>
<div class="col-md-2">
<button class="btn btn-info mx-1" onclick="search()">جست و جو</button>
</div>
</div>
<table id="myTable" class="table border table-striped table-bordered mt-2 mx-auto table-custom--2">
<thead>
<tr>
<th>نام کاربری</th>
<th>رمز عبور</th>
<th>نام</th>
<th>نام خانوادگی</th>
<th>نفش</th>
<th>جنسیت</th>
<th>وضعیت استخدامی</th>
<th>کارکرد</th>
<th>بیمه</th>
<th>امتیاز</th>
<th>شماره تماس</th>
<th>وضعیت تاهل</th>
<th>آدرس محل سکونت</th>
<th>حذف</th>
<th>ویرایش</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.nationalCode</td>
<td>@item.userPass</td>
<td>@item.fName</td>
<td>@item.lName</td>
<td>@item.role</td>
<td>@item.gender</td>
<td>@item.employmentStatus</td>
<td>@item.workingStatus</td>
<td>@item.insuranceStatus</td>
<td>@item.score</td>
<td>@item.tel</td>
<td>@item.maritalStatus</td>
<td>@item.address</td>
<td><a><img src="~/icons/clear-icon.png" /></a></td>
<td><a><img src="~/icons/edit-icon.png" /></a></td>
</tr>
}
</tbody>
</table>
<div class="mx-auto my-5 w-25 hidden" id="error-message">
<div class="alert alert-warning text-center border border-warning">کاربر مورد نظر یافت نشد</div>
</div>
没有找到搜索结果时显示错误信息,其他情况不显示
一种做法如下,代码中有说明注释:
// a named Arrow function, which takes one argument - passed automatically
// from the EventTarget.addEventListener() method:
const search = (evt) => {
// initialising a reference to the <input> element, retrieved
// via its id:
let input = document.getElementById('search'),
// retrieving the current value of the <input> element,
// using document.querySelector and using
// String.prototype.trim() to remove leading, and
// trailing white-space from the value:
value = input.value.trim(),
// using document.querySelector() to retrieve the first
// element on the page matching the supplied CSS selector
// (this will return null if no element is found):
tableBody = document.querySelector('#myTable tbody'),
// retrieving the rows collection within the tableBody
// element, and using an Array-literal and spread-
// syntax to convert the iterable collection to
// an Array of <tr> element-nodes:
rows = [...tableBody.rows];
// iterating over the Array of nodes, using
// Array.prototype.forEach(), passing a
// reference to the current <tr> element to
// the function body:
rows.forEach(
(row) => {
// caching a reference to the firstElementChild:
let firstCell = row.firstElementChild,
// using String.prototype.includes() to determine
// whether the <tr> element's textContent
// property includes the entered value; if
// included this evaluates to true, if not
// included this evaluates to false:
included = firstCell.textContent.includes(value);
// if the value was/is included we wish to retain
// the visibility of the current <tr>, therefore we
// invert the Boolean using the not operator so that
// rows containing the value are retained, and not hidden
// while those rows not containing the value (in which
// 'included' would be false) is hidden:
row.hidden = !included;
});
// here we use the rows Array, using Array.prototype.filter()
// to retain only those <tr> elements that are hidden:
let hiddenRows = rows.filter((r) => r.hidden === true),
// and here we compare the Array of <tr> elements to see
// if it's exactly equal to the number of rows that
// are hidden:
allHidden = rows.length === hiddenRows.length;
// here we retrieve the element with the id of 'error-message',
// and update its "hidden" property to be the inverse of the
// allHidden Boolean value; so that if all rows are hidden
// the "not found" message is visible:
document.getElementById('error-message').hidden = !allHidden;
}
// finding the the first <button> element on the page, and using
// EventTarget.addEventListener() to bind the search() function
// (note the deliberate omission of parentheses) as the handler
// for the 'click' event:
document.querySelector('button').addEventListener('click', search);
table {
border: 2px solid currentColor;
border-spacing: 0;
inline-size: clamp(30rem, 50%, 800px);
margin-inline: auto;
table-layout: fixed;
}
th {
border-block-end: 2px solid currentColor;
}
:is(th, td):first-child {
text-align: start;
}
:is(th, td):not(:first-child) {
text-align: end;
}
tbody tr {
block-size: 1.8em;
opacity: 1;
overflow: hidden;
transition: block-size 300ms linear, opacity 300ms linear;
}
#error-message {
border: 2px solid currentColor;
border-radius: 300vmax;
box-shadow: inset 0 0 2px 2px #fff;
color: #f00;
margin-block: 1rem;
padding-block: 0.25rem;
padding-inline: 0.75rem;
}
<div class="row m-0 p-0">
<div class="col-md-5 p-0 ml-3">
<input type="search" id="search" class="form-control w-100" placeholder="Name" maxlength="10">
</div>
<div class="col-md-2">
<button class="btn btn-info mx-1">Search</button>
</div>
<table id="myTable" class="table border table-striped table-bordered mt-2 mx-auto table-custom--2">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>DoB</th>
</tr>
</thead>
<tbody>
<tr>
<td>Hussain, Mia</td>
<td>11/12/1983</td>
<td>39</td>
</tr>
<tr>
<td>Cai, Jameson</td>
<td>9/27/1976</td>
<td>46</td>
</tr>
<tr>
<td>He, Ivy</td>
<td>4/19/1980</td>
<td>42</td>
</tr>
<tr>
<td>Singh, Ezra</td>
<td>3/18/1987</td>
<td>36</td>
</tr>
<tr>
<td>Kumar, Hailey</td>
<td>2/3/1986</td>
<td>37</td>
</tr>
<tr>
<td>Ceng, Sofia</td>
<td>10/15/1974</td>
<td>48</td>
</tr>
<tr>
<td>I, Kayden</td>
<td>6/4/1996</td>
<td>26</td>
</tr>
<tr>
<td>Perez, Kayden</td>
<td>7/30/1972</td>
<td>50</td>
</tr>
<tr>
<td>Hernandez, Jack</td>
<td>7/7/1985</td>
<td>37</td>
</tr>
<tr>
<td>Ding, Autumn</td>
<td>9/26/1991</td>
<td>31</td>
</tr>
<tr>
<td>Ding, Waylon</td>
<td>10/25/2000</td>
<td>22</td>
</tr>
<tr>
<td>Ahmed, Grace</td>
<td>5/12/1985</td>
<td>37</td>
</tr>
<tr>
<td>Ram, Isaac</td>
<td>5/20/1973</td>
<td>49</td>
</tr>
<tr>
<td>Tan, Audrey</td>
<td>9/15/1981</td>
<td>41</td>
</tr>
<tr>
<td>Tang, Emery</td>
<td>6/28/1976</td>
<td>46</td>
</tr>
<tr>
<td>Chen, Sadie</td>
<td>10/27/1998</td>
<td>24</td>
</tr>
<tr>
<td>Ceng, Joseph</td>
<td>6/19/1971</td>
<td>51</td>
</tr>
<tr>
<td>Nguyen, Noah</td>
<td>10/25/1971</td>
<td>51</td>
</tr>
<tr>
<td>Rodriguez, Elena</td>
<td>6/22/1999</td>
<td>23</td>
</tr>
<tr>
<td>Ahmed, Kayden</td>
<td>7/15/1995</td>
<td>27</td>
</tr>
<tr>
<td>Sun, Cooper</td>
<td>9/21/1974</td>
<td>48</td>
</tr>
<tr>
<td>Ye, Camila</td>
<td>4/24/1985</td>
<td>37</td>
</tr>
<tr>
<td>Du, Nevaeh</td>
<td>5/21/1994</td>
<td>28</td>
</tr>
<tr>
<td>Dong, Nathan</td>
<td>2/18/1981</td>
<td>42</td>
</tr>
<tr>
<td>Bai, Ethan</td>
<td>10/30/1996</td>
<td>26</td>
</tr>
<tr>
<td>Zhou, Jaxon</td>
<td>10/14/1971</td>
<td>51</td>
</tr>
<tr>
<td>Kim, Josiah</td>
<td>4/9/1992</td>
<td>31</td>
</tr>
<tr>
<td>Luo, Caleb</td>
<td>5/8/1975</td>
<td>47</td>
</tr>
<tr>
<td>Garcia, Willow</td>
<td>9/23/1973</td>
<td>49</td>
</tr>
<tr>
<td>Yuan, Claire</td>
<td>8/9/1973</td>
<td>49</td>
</tr>
<tr>
<td>Bibi, Lucas</td>
<td>9/19/1979</td>
<td>43</td>
</tr>
<tr>
<td>Yan, Zoey</td>
<td>2/27/2000</td>
<td>23</td>
</tr>
<tr>
<td>Martinez, Colton</td>
<td>7/1/1986</td>
<td>36</td>
</tr>
<tr>
<td>Lopez, Ezra</td>
<td>8/25/1978</td>
<td>44</td>
</tr>
<tr>
<td>Yadav, Julian</td>
<td>2/19/1971</td>
<td>52</td>
</tr>
<tr>
<td>Cao, Legend</td>
<td>6/23/1973</td>
<td>49</td>
</tr>
<tr>
<td>Tang, Ezra</td>
<td>5/26/1997</td>
<td>25</td>
</tr>
<tr>
<td>Yu, Michael</td>
<td>2/27/1995</td>
<td>28</td>
</tr>
<tr>
<td>Khan, Ethan</td>
<td>6/12/1980</td>
<td>42</td>
</tr>
<tr>
<td>Hassan, Autumn</td>
<td>3/29/1968</td>
<td>55</td>
</tr>
<tr>
<td>Ram, Henry</td>
<td>3/9/1987</td>
<td>36</td>
</tr>
<tr>
<td>Ram, Mateo</td>
<td>9/21/1973</td>
<td>49</td>
</tr>
<tr>
<td>Hassan, Riley</td>
<td>11/29/1990</td>
<td>32</td>
</tr>
<tr>
<td>Lal, Luna</td>
<td>9/1/1976</td>
<td>46</td>
</tr>
<tr>
<td>Huang, Nolan</td>
<td>8/22/1976</td>
<td>46</td>
</tr>
<tr>
<td>Garcia, Violet</td>
<td>6/30/1984</td>
<td>38</td>
</tr>
<tr>
<td>Mohammed, Ethan</td>
<td>2/27/1977</td>
<td>46</td>
</tr>
<tr>
<td>Tan, Lily</td>
<td>5/5/1972</td>
<td>50</td>
</tr>
<tr>
<td>Zhao, Nevaeh</td>
<td>3/27/1971</td>
<td>52</td>
</tr>
<tr>
<td>Ceng, Jack</td>
<td>5/1/1981</td>
<td>41</td>
</tr>
</tbody>
</table>
<!-- I removed the 'hidden' class-name from the element, and instead chose to use
the hidden attribute (this doesn't need a value, if the attribute is present
the element will be hidden) -->
<div class="mx-auto my-5 w-25" id="error-message" hidden>
<div class="alert alert-warning text-center border border-warning">Not found</div>
</div>
</div>
参考资料: