You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现HTML表格的唯一值筛选(仿Excel/谷歌表格筛选功能)

实现HTML表格的唯一值筛选(仿Excel/谷歌表格筛选功能)

Hey there! I totally get your frustration—having duplicate values cluttering up the filter dropdown defeats the purpose of an Excel-like filter. Let's fix this by tweaking the script to only show unique values in each column's filter, while still filtering all matching rows when you select a value.

The Core Fix: Track Unique Values & Their Associated Rows

Instead of generating a filter option for every single row, we'll first collect all distinct values from the target column, then map each value to all rows that contain it. Here's the modified script.js that does exactly this:

$(document).ready(function(){
  $(".grid thead td").click(function(){
    showFilterOption(this);
  });
});

// Map to store unique values and their corresponding rows for each column
var valueRowMap = {};

function showFilterOption(tdObject){
  var filterGrid = $(tdObject).find(".filter");
  if (filterGrid.is(":visible")){
    filterGrid.hide();
    return;
  }

  $(".filter").hide();
  filterGrid.empty();
  var columnIndex = parseInt($(tdObject).attr("index"));
  var $table = $(tdObject).parents("table");
  var $rows = $table.find("tbody tr");
  
  // Step 1: Collect unique values and link them to their rows
  valueRowMap = {};
  $rows.each(function(ind, rowElement){
    var cellText = $(rowElement).children().eq(columnIndex).text().trim();
    // Label empty cells clearly (you can remove this line to show blank options)
    var displayValue = cellText === "" ? "[Empty]" : cellText;
    
    // Initialize array for new values
    if (!valueRowMap[displayValue]) {
      valueRowMap[displayValue] = [];
    }
    valueRowMap[displayValue].push(rowElement);
  });

  // Step 2: Add "Select All" checkbox
  var allValuesVisible = true;
  filterGrid.append('<div><input id="all" type="checkbox" checked>Select All</div>');

  // Step 3: Generate filter options for each unique value
  Object.keys(valueRowMap).forEach(function(value){
    // Check if any row with this value is currently visible
    var isChecked = valueRowMap[value].some(row => $(row).is(":visible"));
    if (!isChecked) allValuesVisible = false;

    var optionDiv = document.createElement("div");
    optionDiv.classList.add("grid-item");
    optionDiv.innerHTML = `<input type="checkbox" ${isChecked ? 'checked' : ''} >${value}`;
    filterGrid.append(optionDiv);
  });

  // Update "Select All" state based on current visibility
  if (!allValuesVisible){
    filterGrid.find("#all").removeAttr("checked");
  }

  // Step 4: Add action buttons
  filterGrid.append('<div><input id="close" type="button" value="Close"/><input id="ok" type="button" value="Ok"/></div>');
  filterGrid.show();

  // Step 5: Handle user interactions
  var $closeBtn = filterGrid.find("#close");
  var $okBtn = filterGrid.find("#ok");
  var $allCheckbox = filterGrid.find("#all");
  var $filterOptions = filterGrid.find(".grid-item");

  $closeBtn.click(function(){
    filterGrid.hide();
    return false;
  });

  $okBtn.click(function(){
    // Hide all rows first
    $rows.hide();
    // Show rows for each checked value
    $filterOptions.each(function(){
      if ($(this).find("input").is(":checked")){
        var selectedValue = $(this).text().trim();
        // Map back to empty string if we used "[Empty]" label
        var actualValue = selectedValue === "[Empty]" ? "" : selectedValue;
        valueRowMap[actualValue].forEach(row => $(row).show());
      }
    });
    // Show all rows if "Select All" is checked
    if ($allCheckbox.is(":checked")) {
      $rows.show();
    }
    filterGrid.hide();
    return false;
  });

  // Prevent checkbox clicks from closing the filter
  filterGrid.find("input[type='checkbox']").click(function(event){
    event.stopPropagation();
  });

  // Toggle checkbox when clicking the option text
  $filterOptions.click(function(event){
    var checkbox = $(this).find("input[type='checkbox']");
    checkbox.prop("checked", !checkbox.is(":checked"));
  });

  // Toggle all options when "Select All" is changed
  $allCheckbox.change(function(){
    var isChecked = $(this).is(":checked");
    filterGrid.find(".grid-item [type='checkbox']").prop("checked", isChecked);
  });

  // Keep filter open when clicking inside it
  filterGrid.click(function(event){
    event.stopPropagation();
  });

  return filterGrid;
}

Key Improvements:

  • Unique Values Only: Duplicate entries like multiple "Apple" or empty cells now appear just once in the filter dropdown.
  • Row Grouping: Each unique value is linked to all rows containing it, so selecting "Apple" will show every row with "Apple" in that column.
  • Empty Cell Clarity: Empty cells are labeled "[Empty]" (you can remove this if you prefer blank options).
  • Persistent State: The filter remembers which values were previously selected based on visible rows when you reopen it.

HTML & CSS Notes:

Your existing index.html and style.css can stay exactly as they are. The only optional tweak is adjusting the filter's width in style.css if the "[Empty]" label is too long, but this isn't necessary for functionality.

How It Works:

  1. When you click a column header, the script scans all rows to collect distinct values from that column.
  2. It creates a filter option for each unique value, checking if any row with that value is currently visible.
  3. When you click "Ok", it hides all rows first, then shows only the rows associated with your selected values.
  4. The "Select All" checkbox toggles all filter options and shows/hides all rows accordingly.

This should give you the clean, intuitive filtering experience you're looking for!

备注:内容来源于stack exchange,提问作者Ishrat Hossain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 07:13:10