使用选择选项仅显示表中第一行的期望值=“”的行

时间:2019-01-16 15:07:07

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

我有一个表和一个下拉列表,其选项是由带有两个选项的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>

5 个答案:

答案 0 :(得分:1)

您将其标记为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>

答案 1 :(得分:1)

我对此很有趣,我使用香草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 :(得分:1)

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>

答案 3 :(得分:0)

这里是开始的方式。您可以使用多种方法从td文本中获取年份,但是Year是唯一一个长度为4个字符的年份,您可以直接使用:contains选择器< / p>

$('#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 })

答案 4 :(得分:0)

如果您不想使用jQuery或其他库,则可以使用纯JS:

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

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