如何在网页上实现日期范围过滤器?

How do I implement a date range filter on my webpage?

提问人:X888ARJ 提问时间:11/3/2023 最后编辑:X888ARJ 更新时间:11/3/2023 访问量:76

问:

我有以下日期选择器:

<div style="margin-bottom: 20px;">
    <label for="startDate">Start Date: </label>
    <input type="date" id="startDate" class="date-picker" />
    <label for="endDate">End Date: </label>
    <input type="date" id="endDate" class="date-picker" />
    <button onclick="filterByDate()">Filter</button>
</div>

我有一张这样的表格:

<thead class="thead-dark sticky-top" style="top: 50px;">
    <tr>
        <th>Job No</th>
        <th>Company</th>
        <th>Permit No</th>
        <th>R No</th>
        <th>TM Company</th>
        <th>TM Type</th>
        <th>Address</th>
        <th>Checked By</th>
        <th>Checked Date</th>
        <th style="width:250px;">Comments</th>
    </tr>
</thead>        

我想在表格中的“检查日期”列进行筛选,该列被分配了一个“TbDate”值并以 DD/MM/YYYY HH:mm 格式显示:

<td>@firstJob.TbDate?.ToString("dd/MM/yyyy HH:mm")</td>

日期选取器和表行的呈现 HTML 如下所示:

       <div style="margin-bottom: 20px;">
            <label for="startDate">Start Date: </label>
            <input type="date" id="startDate" class="date-picker" pattern="\d{2}/\d{2}/\d{4}">
            <label for="endDate">End Date: </label>
            <input type="date" id="endDate" class="date-picker" pattern="\d{2}/\d{2}/\d{4}">
            <button onclick="filterByDate()">Filter</button>
        </div>        
       
        <tr class="data-row">
           <td><a href="/Job?JobNo=505248">505248</a></td>
           <td>SCS</td>
           <td>SMA TEST</td>
           <td>SMATEST1</td>
           <td>></td>
           <td></td>
           <td>DO NOT PLAN, THIS IS A TEST, TEST TOWN</td>
           <td>Test Name</td>
           <td>27/10/2023 12:17</td>
           <td>                                       
           <form id="CommentsBox_505248" style="display: flex; align-items: center; justify-content: flex-end; width: 100%;">
               <input type="hidden" name="JobNo" value="505248">
               <textarea name="Comments" placeholder="Add comments" style="flex: 1 1 auto; width: 100%; height: 80px; box-sizing: border-box; margin-right: 10px;"></textarea>
               <button type="button" onclick="submitComment('505248')">Submit</button>
           </form>               
           </td>            
         </tr>

如何实现 JavaScript 以筛选表中日期选择器中设置的范围之间的行?

我只想使用 DD/MM/YYYY 值进行过滤,而忽略 HH:mm 值。

我正在使用 Bootstrap、剃须刀页面、JQuery 和 Vanilla JS。

javascript html jquery asp.net razor-pages

评论

0赞 Professor Abronsius 11/3/2023
什么?如果您希望使用它来进行过滤,请添加该函数。一些渲染的 HTML 也很有用,以便可以观察到效果filterByDate
0赞 X888ARJ 11/3/2023
filterByDate 函数尚未实现。我在问题中添加了一些渲染的 html。
0赞 Professor Abronsius 11/3/2023
您是否能够修改 HTML 的格式,或者这是否超出了您的范围?如果可以查询 date 属性本身,而不必钻取到单个表单元格文本内容,则过滤表格行会更容易......这当然是可能的,但会更容易tr

答:

0赞 J.Porter 11/3/2023 #1

我认为你的日期格式是错误的。

“checkedAt”日期的格式类似于 dd/MM/yyyy HH:mm,因此您无法使用“checkedAt”日期创建新日期。

通常,日期字符串的格式如下:MM/dd/yyyy HH:mm。

如果您像这样更改“checkedAt”的格式,您可以更轻松地解决问题。

const originalData = []; //your dataList in table
const startAt = new Date(document.getElementById("startDate").value);
const endAt = new Date(document.getElementById("endDate").value);

const filteredData = originalData.filter((data) => {
  const checkedAt = new Date(data.checkDate);
  return checkedAt > startAt && checkedAt < endAt;
});

//you get filtered data list : filteredData

希望这个答案能帮到你。

0赞 Professor Abronsius 11/3/2023 #2

我不使用 Bootstrap 或 jQuery,因此无法提供任何关于他们可能拥有的任何本机方法的指导,但是使用 vanilla JS,您也许可以像这样实现您的目标。

下面的代码片段显示了基于您编辑的 HTML 的 3 个可能的虚拟数据表行。我希望这是您可能看到的合理摹本。

所有内联事件处理程序都已移出到委托侦听器,该侦听器将检查以确定要运行的函数。表中的表单可能不需要 ID,内联样式也已移至外部 css。event.target

该函数最初检查是否为开始日期和结束日期指定了值。使用经过过滤的输入元素引用数组,我们构建了两个新的 Date 对象并获取每个对象的时间。这些时间用于与 HTML 表中的行进行比较。filterByDate

查询 DOM 以查找 class 的所有表行,并查找包含日期字符串值的 table-cell。根据上面的评论,例如,如果表行本身具有包含此日期字符串的数据集属性,这将更简单。 修改日期字符串以创建有效的字符串格式,并创建一个新的 Date 对象并将其用于比较。如果表格行的日期在输入元素给定的范围内,则将显示该行,否则该行将被隐藏。.row-data

const convertdate=(str)=>{
  let [date,time]=str.split(' ');
  let [d,m,y]=date.split('/');
  return [y,m,d].join('/');
}

const filterByDate=(e)=>{
  let inputs=e.target.closest('div').querySelectorAll('input[type="date"]');
      inputs=[...inputs].filter(input=>{
        return input.value!='';
      });
      
  if( inputs.length==2 ){
    let ds=( new Date( inputs[0].value ) ).getTime();
    let df=( new Date( inputs[1].value ) ).getTime();
  
    let col=document.querySelectorAll('.data-row');
        col.forEach(tr=>{
          tr.style.display='none';
        })
        col=[...col].filter(tr=>{
          let jobdate=( new Date( convertdate( tr.querySelector('td:nth-of-type(9)').textContent ) ) ).getTime();
          
          return jobdate >= ds && jobdate <= df;
        });
        
        col.forEach( tr=>{
          tr.style.display='table-row';
        });
  }else{
    console.log('too few dates to create the upper and lower ranges')
  }
  return true;
};

const submitComment=(e)=>{
  let form=e.target.closest('form');
  return form.submit();
};


document.addEventListener('click',e=>{
  if( e.target instanceof HTMLButtonElement && e.target.classList.contains('subcom') ){
    return submitComment(e);
  }
  if( e.target instanceof HTMLButtonElement && e.target.classList.contains('filter') ){
    return filterByDate(e);
  }
});
table{
  border-collapse:none;
  font-family:monospace;
}
thead{
  background:grey;
  color:white;
}

.data-row td{
  padding:1rem;
  border:1px dotted grey;
}

textarea{
  flex: 1 1 auto; 
  width: 100%; 
  height: 80px; 
  box-sizing: 
  border-box; 
  margin-right: 10px;
}
form{
  display: flex; 
  align-items: center; 
  justify-content: flex-end; 
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div style="margin-bottom: 20px;">
  <label>Start Date: <input type="date" class="date-picker" pattern="\d{2}/\d{2}/\d{4}"></label>
  <label>End Date: <input type="date" class="date-picker" pattern="\d{2}/\d{2}/\d{4}"></label>
  <button class='filter'>Filter</button>
</div>


<table>
  <thead class="thead-dark sticky-top" style="top: 50px;">
    <tr>
      <th>Job No</th>
      <th>Company</th>
      <th>Permit No</th>
      <th>R No</th>
      <th>TM Company</th>
      <th>TM Type</th>
      <th>Address</th>
      <th>Checked By</th>
      <th>Checked Date</th>
      <th style="width:250px;">Comments</th>
    </tr>
  </thead>
  <tbody>
    <tr class="data-row">
      <td><a href="/Job?JobNo=505248">505248</a></td>
      <td>MAY</td>
      <td>SMA TEST</td>
      <td>SMATEST1</td>
      <td>&gt;</td>
      <td></td>
      <td>TEST TOWN</td>
      <td>Test Name</td>
      <td>01/05/2023 12:17</td>
      <td>
        <form>
          <input type="hidden" name="JobNo" value="505248">
          <textarea name="Comments" placeholder="Add comments"></textarea>
          <button class="subcom" type="button">Submit</button>
        </form>
      </td>
    </tr>


    <tr class="data-row">
      <td><a href="/Job?JobNo=63457456">63457456</a></td>
      <td>NOV</td>
      <td>SMA TEST</td>
      <td>SMATEST1</td>
      <td>&gt;</td>
      <td></td>
      <td>TEST TOWN</td>
      <td>Test Name</td>
      <td>22/11/2023 16:22</td>
      <td>
        <form>
          <input type="hidden" name="JobNo" value="63457456">
          <textarea name="Comments" placeholder="Add comments"></textarea>
          <button class="subcom" type="button">Submit</button>
        </form>
      </td>
    </tr>
    
    <tr class="data-row">
      <td><a href="/Job?JobNo=5052456">5052456</a></td>
      <td>SEPT</td>
      <td>SMA TEST</td>
      <td>SMATEST1</td>
      <td>&gt;</td>
      <td></td>
      <td>TEST TOWN</td>
      <td>Test Name</td>
      <td>5/09/2023 12:30</td>
      <td>
        <form>
          <input type="hidden" name="JobNo" value="5052456">
          <textarea name="Comments" placeholder="Add comments"></textarea>
          <button class="subcom" type="button">Submit</button>
        </form>
      </td>
    </tr>
  </tbody>
</table>

评论

0赞 X888ARJ 11/3/2023
是的,这与我所做的是一样的。我将保存表中的日期值的单元格数据存储到数组中,然后将开始日期和结束日期与数组中的元素进行比较,并设法使其正常工作。