【问题标题】:Use select option to only display table rows with the desired value="" of the first <td>使用 select 选项仅显示具有第一个 <td> 的所需 value="" 的表行
【发布时间】:2019-01-16 15:07:07
【问题描述】:

我有一个表格和一个下拉列表,其选项由带有两个选项的 javascript 代码创建 - 2018 和 2019。

我需要一个代码来仅显示选定年份的表格行,并按日期,然后按小时进行设置。

第一个表格单元格:日期 (dd/mm/yyyy) 第二个表格单元格:小时(24 小时格式)

var select = document.getElementById("year");
var options = ["2018", "2019"];

for (var i = 0; i < options.length; i++) {
  var opt = options[i];
  var el = document.createElement("option");
  el.textContent = opt;
  el.value = opt;
  select.appendChild(el);
}
<select id="year">

</select>

<table>
  <tbody>
    <tr>
      <td>06/05/2018</td>
      <td>16:00h</td>
      <td>Chris</td>
    </tr>

    <tr>
      <td>24/10/2019</td>
      <td>20:00h</td>
      <td>Alex</td>
    </tr>

    <tr>
      <td>11/03/2018</td>
      <td>15:00h</td>
      <td>Dani</td>
    </tr>

    <tr>
      <td>08/04/2019</td>
      <td>12:30h</td>
      <td>Joe</td>
    </tr>

    <tr>
      <td>22/04/2018</td>
      <td>10:30h</td>
      <td>Mike</td>
    </tr>
  </tbody>
</table>

【问题讨论】:

    标签: javascript jquery filter html-select html.dropdownlistfor


    【解决方案1】:

    我对这个有一点乐趣,我使用 vanilla JavaScript 创建了一个解决方案,但是您可以使用 jQuery 对其进行一些简化,但您并不完全需要 jQuery 来执行此操作。这是我的解决方案。

    (function(){
      // store a reference to the filter
      let filter = document.getElementById('year');
      // store a reference to the table
      let table = document.getElementById('data-table');
      // array to hold the javascript representation of the rows
      let jRows = [];
      // wire the event handler for the change function
      filter.addEventListener('change', filterRows);
    
      // initialization function
      function init(){
        // get all the existing rows in the table
        let rows = table.querySelectorAll('tbody>tr');
        // used to store all the availble years
        let years = [];
        // loop over each row
        [...rows].forEach(function(row) { 
          // get the columns in this row
          let cols = row.querySelectorAll('td');
          // create an object to represent the row, break out year and time into their
          // own fields to make it easier to sort later
          var r = {
            date: cols[0].innerHTML,
            year: parseInt(cols[0].innerHTML.substr(cols[0].innerHTML.lastIndexOf('/') + 1)),
            time: cols[1].innerHTML,
            sortTime: parseInt(cols[1].innerHTML.replace('h', '').replace(':', '')),
            name: cols[2].innerHTML
          };
          // store this row in the global array of rows
          jRows.push(r);
          // check if this year is already added to the unique list of years
          if (years.indexOf(r.year) < 0)
            years.push(r.year)
        });
    
        // sort the years
        years.sort();
        // create the all option for the filter
        let all = document.createElement('option');
        all.value = 'all';
        all.innerHTML = 'All';
        filter.appendChild(all);
        // loop over each year adding the option to the filter
        years.forEach(function(year){
          let opt = document.createElement('option');
          opt.value = year;
          opt.innerHTML = year;
          filter.appendChild(opt);
        });
        // initially call the filterRows function to sort the table
        filterRows();
      }
    
      function filterRows(){
        // get the current filter
        let selectedFilter = filter.options[filter.selectedIndex].value;
        // clone the rows to manipulate the
        var displayRows = Array.from(jRows);
        // if we aren't showing all the rows, filter them
        if (selectedFilter !== 'all'){
          displayRows = displayRows.filter(r => r.year == selectedFilter)
        }
        // sort the rows by year and time
        displayRows.sort(function (x, y) { return x.year - y.year || x.sortTime - y.sortTime; })
        // create a new tbody element
        var tbody = document.createElement('tbody');
        // loop over each row and construct the tr element
        displayRows.forEach(function(row){
          let r = document.createElement('tr');
    
          let cDate = document.createElement('td');
          cDate.innerHTML = row.date;
    
          let cTime = document.createElement('td');
          cTime.innerHTML = row.time
    
          let cName = document.createElement('td');
          cName.innerHTML = row.name;
    
          r.appendChild(cDate);
          r.appendChild(cTime);
          r.appendChild(cName);
    
          tbody.appendChild(r);
        });
        // replace the current tbody with the new one
        table.replaceChild(tbody, table.getElementsByTagName('tbody')[0]);
      }
    
      // initialize the table
      init();
    })();
    <select id="year">
    
    </select>
    
    <table id="data-table">
      <tbody>
        <tr>
          <td>06/05/2018</td>
          <td>16:00h</td>
          <td>Chris</td>
        </tr>
    
        <tr>
          <td>24/10/2019</td>
          <td>20:00h</td>
          <td>Alex</td>
        </tr>
    
        <tr>
          <td>11/03/2018</td>
          <td>15:00h</td>
          <td>Dani</td>
        </tr>
    
        <tr>
          <td>08/04/2019</td>
          <td>12:30h</td>
          <td>Joe</td>
        </tr>
    
        <tr>
          <td>22/04/2018</td>
          <td>10:30h</td>
          <td>Mike</td>
        </tr>
      </tbody>
    </table>

    【讨论】:

      【解决方案2】:

      var select = document.getElementById("year");
      var options = ["2018", "2019"];
      
      for (var i = 0; i < options.length; i++) {
        var opt = options[i];
        var el = document.createElement("option");
        el.textContent = opt;
        el.value = opt;
        select.appendChild(el);
      }
      
      // get the table.
      var table = document.getElementById("table");
      
      // Read data for sorting and filtering
      // ---------------------------------------
      
      // iterate through the rows of the table.
      var rows = table.getElementsByTagName("tr");
      for (var i = 0; i < rows.length; i++) {
      
        var tr = rows[i];
      
        // temp vars for filtering/sorting table.
        var year = NaN;
        var month = NaN;
        var day = NaN;
        var hour = NaN;
      
        // iterate through columns for data/time data.
        var cols = tr.getElementsByTagName("td");
        for (var j = 0; j < cols.length; j++) {
      
          // get the contents of the cell.
          var td = cols[j];
          var contents = td.innerText;
      
          // check if contents contains date.
          var dateResult = contents.match(/([0-9]{2})[\/]{1}([0-9]{2})[\/]{1}([0-9]{4})/m);
          // if match, collect year, month, day values.
          if (dateResult != null && 0 < dateResult.length) {
      
            year = parseInt(dateResult[3]);
            month = parseInt(dateResult[2]);
            day = parseInt(dateResult[1]);
      
          } else { // only check the time if content is not a "date".
      
            // check if contents contains time.
            var timeResult = contents.match(/([0-9]{2}):[0-9]{2}h/m);
            // if match, collect hour value.
            if( timeResult != null && 0 < timeResult.length) {
              hour = parseInt(timeResult[1]);
            }
      
          }
      
          // break the loop if necessary data has been collected.
          if (!isNaN(year) && !isNaN(month) && !isNaN(day) && !isNaN(hour)) {
            break;
          }
      
        }
      
        // create a value for sorting.
        var sort = year * 1000000 + month * 10000 + day * 100 + hour;
      
        // set sorting and filtering (year) data on row.
        tr.setAttribute('data-sort', sort);
        tr.setAttribute('data-year', year);
      
      }
      
      // Sort the rows by Year/Month/Date/Hour
      // ---------------------------------------
      
      // convert rows (NodeList) to Array.
      var rowsArray = Array.prototype.slice.call(rows);
      
      // sort the rows array by "sort" value on elments.
      rowsArray.sort(function(a, b) {
        return a.dataset.sort - b.dataset.sort;
      });
      
      // get the table body.
      var tbody = table.getElementsByTagName("tbody")[0];
      
      // reorder rows in table.
      for (var i = 0; i < rowsArray.length; i++) {
        
        var row = rowsArray[i];
        
        tbody.removeChild(row);
        tbody.appendChild(row);
        
      }
      
      // Add filter event listener to select
      // ---------------------------------------
      
      var filterRows = function() {
      
        // get the selected year.
        var year = parseInt(this.options[this.selectedIndex].value);
      
        // iterate table rows. show/hide as needed.
        for (var i = 0; i < rows.length; i++) {
      
          var tr = rows[i];
      
          if( 0 < year && tr.dataset.year != year ) {
            tr.style.display = "none";
          } else {
            tr.style.display = "table-row";
          }
      
        }
      
      };
      
      // apply year filter on select change event.
      select.addEventListener("change", filterRows);
      
      // optionally call filterRows(); to initialize table sorting.
      // filterRows();
      <select id="year">
        <!-- added blank option to allow for first year to be selected on load -->
        <option>----</option>
      </select>
      
      <table id="table">
        <tbody>
          <tr>
            <td>06/05/2018</td>
            <td>16:00h</td>
            <td>Chris</td>
          </tr>
      
          <tr>
            <td>24/10/2019</td>
            <td>20:00h</td>
            <td>Alex</td>
          </tr>
      
          <tr>
            <td>11/03/2018</td>
            <td>15:00h</td>
            <td>Dani</td>
          </tr>
      
          <tr>
            <td>08/04/2019</td>
            <td>12:30h</td>
            <td>Joe</td>
          </tr>
      
          <tr>
            <td>22/04/2018</td>
            <td>10:30h</td>
            <td>Mike</td>
          </tr>
        </tbody>
      </table>

      【讨论】:

      • 不错的解决方案,一件小事是您没有考虑时间的分钟数。例如,如果有一行是 15:07h,另一行是 15:36,另一行是 15:56,则排序失败。这是我正在谈论的一个例子:jsfiddle.net/2s18ek07
      • @AdamH 原帖只要求按小时排序。
      • 很公平,在这种情况下,此解决方案按预期工作。
      • @AdamH 我明白你的意思。 OP 似乎确实将全时(小时/分钟)视为“小时”。也许是军事时间的事情。
      • 嗯,无论哪种方式,修改您的解决方案以将分钟考虑在内并不难。根据规格,我仍然认为您的解决方案是可以接受的。
      【解决方案3】:

      您将其标记为 jQuery,因此我建议使用以下代码。

      它包括一个排序,年份选择是从表格内容生成的

      var options = [];
      
      // create a valid date from the first two cells
      function makeDate(row) {
        var date = $("td",row).eq(0).text(), 
            time = $("td",row).eq(1).text().substring(0,5);
        date = date.split(/\//).reverse().join('/');   
        var year = date.split("/")[0];
        if (options.indexOf(year) ==-1) options.push(year);
        var dateString = date + " " + time;
        return Date.parse(dateString);
      }
      
      $(function() {
        var $select = $("#year");
      
        // sort the table before showing it
        // sorting it generates the year array
      
        $('tbody tr').sort(function(a,b){
          var aVal = makeDate(a), bVal = makeDate(b);
          if (aVal < bVal) return -1;
          if (aVal > bVal) return 1;
          return 0;
        }).appendTo('tbody')
      
        // Create the select from the array of years found in the table
      
        options.sort().reverse().forEach(function(opt) {
          $select.append($("<option/>",{ text:opt, value:opt}));
        })
      
        // show / hide the relevant rows based on select value
      
        $select.on("change",function() {
          $("table tbody tr").hide();
          $("table tbody td:contains("+this.value+")").closest("tr").show();
        }).change();
      
        
      });
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <select id="year"></select>
      
      <table>
        <tbody>
          <tr>
            <td>06/05/2018</td>
            <td>16:00h</td>
            <td>Chris</td>
          </tr>
      
          <tr>
            <td>24/10/2019</td>
            <td>20:00h</td>
            <td>Alex</td>
          </tr>
      
          <tr>
            <td>11/03/2018</td>
            <td>15:00h</td>
            <td>Dani</td>
          </tr>
      
          <tr>
            <td>07/03/2017</td>
            <td>12:30h</td>
            <td>Fred</td>
          </tr>
      
          <tr>
            <td>08/04/2019</td>
            <td>12:30h</td>
            <td>Joe</td>
          </tr>
      
      
          <tr>
            <td>22/04/2018</td>
            <td>10:30h</td>
            <td>Mike</td>
          </tr>
        </tbody>
      </table>

      【讨论】:

        【解决方案4】:

        如果您不想使用jQuery 或其他库,这里有一个使用纯 JS 的替代方案:

        https://jsfiddle.net/MtzPwner/2hydzwLk/13/

        它利用表上的rows 属性来遍历行,并利用cells 属性来获取第一个单元格的值。年份是从那里开始的splitpop,如果需要,可以用其他方法替换(可能是indexOf?)。祝你好运!

        【讨论】:

          【解决方案5】:

          您可以从这里开始 .. 您可以使用多种方法从 td 文本中获取年份,但是虽然 year 是唯一一个长度为 4 个字符的年份,但您可以直接使用 :contains 选择器

          $('#year').on('change' , function(){
             var SelectedYear = $(this).val();
             $('tr').removeClass('inYear');
             $('td:contains("'+ SelectedYear +'")').closest('tr').addClass('inYear');
          }).change();  // add .change here will run the change event on load
          .inYear{
            background : red;
          }
          <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          <html>
          <head>
          </head>
          
          <body>
          <select id="year">
              <option value="nothing">All Years</option>
              <option value="2018">2018</option>
              <option value="2019">2019</option>
          </select>
          
          <table>
            <tbody>   
              <tr>
                <td>06/05/2018</td> 
                <td>16:00h</td> 
                <td>Chris</td>
              </tr>
          
              <tr>
                <td>24/10/2019</td> 
                <td>20:00h</td> 
                <td>Alex</td>
              </tr>
          
              <tr>
                <td>11/03/2018</td>
                <td>15:00h</td>
                <td>Dani</td>                     
              </tr>
          
              <tr>
                <td>08/04/2019</td>
                <td>12:30h</td>
                <td>Joe</td>  
              </tr>
          
              <tr>
                <td>22/04/2018</td>
                <td>10:30h</td>
                <td>Mike</td>
              </tr>
            </tbody>
          </table>            
          
          </body>
          </html>

          注意:如果选择是动态生成的,您需要Event binding on dynamically created elements? $(document).on('change' , '#year' , function(){ //code here })

          【讨论】:

          • 很好!谢谢你!另外,我怎样才能让这段代码从没有背景颜色“重启”?
          猜你喜欢
          • 2011-08-19
          • 2023-03-18
          • 1970-01-01
          • 2018-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-14
          相关资源
          最近更新 更多