首页 > 解决方案 > html\js 多选表过滤器

问题描述

我有 250,000 (250K) 条查询行。某种具有约 10 列的表。数据为 CSV 格式并转换为 HTML 表格。

我需要一个想法\框架\示例如何能够对其进行排序和过滤,

它必须是响应式的,而且我更喜欢本地的,比如 js \ jQuery 之类的。

我发现的大多数脚本只有搜索和列排序,添加自定义过滤器非常复杂。

标签: javascriptjqueryhtml-tableimport-from-csv

解决方案


这是一个使用虚拟数据进行自定义过滤的示例,只是为了深入了解它是如何完成的。您也可以通过隐藏/显示行来进行过滤,但为了速度,我只是在每次过滤后重新渲染表格。

关键是函数内部的这个语句filterData

return data.filter(row => {
  for(let key in options){
    if(row[key] != options[key]) return false
  }
  return true
})

例如,选项看起来像的地方{ eyeColor: "green", age: 35 }。您只需遍历过滤器下拉列表,获取每个活动过滤器的键/值对,然后根据该过滤器过滤数据。

const data = [
  {
    "_id": "5b5f589b2340829388c09823",
    "index": 0,
    "guid": "e2dc9a1d-7e37-4d2c-b97d-fb3607f9b388",
    "isActive": true,
    "balance": "$1,995.31",
    "picture": "http://placehold.it/32x32",
    "age": 35,
    "eyeColor": "green",
    "name": "Tami Price",
    "gender": "female",
    "company": "PHOTOBIN",
    "email": "tamiprice@photobin.com",
    "phone": "+1 (856) 427-2164",
    "address": "360 Wythe Place, Hannasville, Tennessee, 896",
    "about": "Qui non reprehenderit esse ut Lorem dolor dolore incididunt laborum cupidatat adipisicing. Mollit adipisicing esse ad voluptate in esse deserunt ut ut excepteur enim laborum. Duis mollit amet irure minim elit enim ad sunt. Eiusmod anim officia nisi consequat eiusmod exercitation non non velit non. Amet sunt qui qui cupidatat minim proident id ea fugiat excepteur id. Irure dolor qui aliqua cupidatat.\r\n",
    "registered": "2017-02-20T04:52:56 +05:00",
    "latitude": -3.23247,
    "longitude": 139.287912,
    "tags": [
      "deserunt",
      "amet",
      "elit",
      "dolor",
      "ipsum",
      "nostrud",
      "aute"
    ],
    "friends": [
      {
        "id": 0,
        "name": "Carolina Pennington"
      },
      {
        "id": 1,
        "name": "Bartlett Forbes"
      },
      {
        "id": 2,
        "name": "Helene Rivera"
      }
    ],
    "greeting": "Hello, Tami Price! You have 9 unread messages.",
    "favoriteFruit": "apple"
  },
  {
    "_id": "5b5f589b8905b957f15fedd3",
    "index": 1,
    "guid": "da22124e-faa3-4c7b-a574-d897768c7c47",
    "isActive": false,
    "balance": "$3,550.38",
    "picture": "http://placehold.it/32x32",
    "age": 32,
    "eyeColor": "blue",
    "name": "Misty Bowers",
    "gender": "female",
    "company": "NEBULEAN",
    "email": "mistybowers@nebulean.com",
    "phone": "+1 (934) 544-2138",
    "address": "296 Albemarle Road, Lindisfarne, Wyoming, 403",
    "about": "Adipisicing mollit excepteur est commodo mollit ut excepteur aliqua consectetur tempor laboris excepteur. Sunt veniam non velit elit cillum ullamco culpa incididunt nisi ipsum consectetur. Do culpa ea dolore elit eu id dolor exercitation.\r\n",
    "registered": "2016-02-11T11:17:11 +05:00",
    "latitude": -33.028953,
    "longitude": -165.893086,
    "tags": [
      "cupidatat",
      "mollit",
      "dolor",
      "velit",
      "exercitation",
      "aliquip",
      "consectetur"
    ],
    "friends": [
      {
        "id": 0,
        "name": "Higgins Frye"
      },
      {
        "id": 1,
        "name": "Stacie Patel"
      },
      {
        "id": 2,
        "name": "Carmen Nunez"
      }
    ],
    "greeting": "Hello, Misty Bowers! You have 7 unread messages.",
    "favoriteFruit": "strawberry"
  },
  {
    "_id": "5b5f589b6e23f459ca3b81cd",
    "index": 2,
    "guid": "3b029252-1c8d-4c4a-a4d4-87dc779e6fcb",
    "isActive": false,
    "balance": "$2,847.74",
    "picture": "http://placehold.it/32x32",
    "age": 31,
    "eyeColor": "blue",
    "name": "Craft Mullins",
    "gender": "male",
    "company": "EPLOSION",
    "email": "craftmullins@eplosion.com",
    "phone": "+1 (826) 436-3905",
    "address": "218 Grand Avenue, Joes, Guam, 9205",
    "about": "Dolore commodo aute ipsum cillum occaecat irure mollit culpa fugiat et adipisicing qui. In ex eu labore incididunt id exercitation occaecat aliquip enim elit. Mollit aliqua ut culpa cillum. Aliqua sunt ipsum culpa pariatur ex elit id consectetur Lorem ad mollit aliquip voluptate laboris. Reprehenderit dolore sunt sit nulla.\r\n",
    "registered": "2017-03-28T06:51:13 +04:00",
    "latitude": 46.812708,
    "longitude": -54.047492,
    "tags": [
      "aute",
      "minim",
      "Lorem",
      "sit",
      "minim",
      "ex",
      "mollit"
    ],
    "friends": [
      {
        "id": 0,
        "name": "Love Crawford"
      },
      {
        "id": 1,
        "name": "Ladonna Middleton"
      },
      {
        "id": 2,
        "name": "Benton Horne"
      }
    ],
    "greeting": "Hello, Craft Mullins! You have 6 unread messages.",
    "favoriteFruit": "strawberry"
  },
  {
    "_id": "5b5f589b04a78795b168510d",
    "index": 3,
    "guid": "41188be6-c65b-47ed-8061-2fe7f228f58e",
    "isActive": true,
    "balance": "$1,147.18",
    "picture": "http://placehold.it/32x32",
    "age": 32,
    "eyeColor": "green",
    "name": "Kristine Simpson",
    "gender": "female",
    "company": "SULFAX",
    "email": "kristinesimpson@sulfax.com",
    "phone": "+1 (989) 414-3537",
    "address": "468 Cheever Place, Bergoo, Oklahoma, 8841",
    "about": "Adipisicing sunt occaecat consectetur ex exercitation consequat esse qui non laborum aliquip et laboris. Officia cillum et incididunt quis cillum enim ea in qui aliqua cupidatat ut dolore anim. Mollit culpa occaecat aliquip deserunt ex.\r\n",
    "registered": "2017-04-26T06:02:45 +04:00",
    "latitude": -22.939072,
    "longitude": 135.212528,
    "tags": [
      "est",
      "dolor",
      "aute",
      "elit",
      "mollit",
      "fugiat",
      "consectetur"
    ],
    "friends": [
      {
        "id": 0,
        "name": "Wooten Rich"
      },
      {
        "id": 1,
        "name": "Ball Fernandez"
      },
      {
        "id": 2,
        "name": "Cathryn Fulton"
      }
    ],
    "greeting": "Hello, Kristine Simpson! You have 1 unread messages.",
    "favoriteFruit": "apple"
  },
  {
    "_id": "5b5f589b87ad8ae689aa2639",
    "index": 4,
    "guid": "6a1da7a5-66c0-4fc6-a424-92add50eaeef",
    "isActive": false,
    "balance": "$2,652.13",
    "picture": "http://placehold.it/32x32",
    "age": 30,
    "eyeColor": "blue",
    "name": "Noelle Winters",
    "gender": "female",
    "company": "MICROLUXE",
    "email": "noellewinters@microluxe.com",
    "phone": "+1 (937) 554-3121",
    "address": "592 Stillwell Avenue, Clara, New Mexico, 297",
    "about": "Duis sint excepteur aute ex mollit aliquip commodo dolore exercitation ad qui est in. Exercitation esse in reprehenderit nulla deserunt. Laborum voluptate commodo enim veniam qui nostrud. Labore fugiat est labore ex est elit veniam sint tempor veniam cupidatat elit velit officia. Consectetur in est pariatur incididunt fugiat fugiat officia in excepteur. Culpa eu proident quis aliquip veniam aute excepteur ex amet eu.\r\n",
    "registered": "2018-02-27T07:48:49 +05:00",
    "latitude": -29.457437,
    "longitude": 33.52719,
    "tags": [
      "dolor",
      "cillum",
      "consequat",
      "officia",
      "eu",
      "nostrud",
      "fugiat"
    ],
    "friends": [
      {
        "id": 0,
        "name": "Roxie Burt"
      },
      {
        "id": 1,
        "name": "Priscilla Olsen"
      },
      {
        "id": 2,
        "name": "Bridgette Bray"
      }
    ],
    "greeting": "Hello, Noelle Winters! You have 6 unread messages.",
    "favoriteFruit": "strawberry"
  },
  {
    "_id": "5b5f589be181e8b38501ab88",
    "index": 5,
    "guid": "6ad40fbb-8872-4f8c-bc5e-17226e255a9c",
    "isActive": true,
    "balance": "$1,431.56",
    "picture": "http://placehold.it/32x32",
    "age": 22,
    "eyeColor": "green",
    "name": "John Mcfarland",
    "gender": "female",
    "company": "CAPSCREEN",
    "email": "johnmcfarland@capscreen.com",
    "phone": "+1 (923) 459-3323",
    "address": "390 Menahan Street, Farmers, District Of Columbia, 3239",
    "about": "Quis eu dolore irure anim voluptate sint aliqua reprehenderit est culpa. Cupidatat velit qui quis id consequat id voluptate. Velit est laboris velit mollit amet ullamco. Minim occaecat eiusmod eu officia consectetur ea fugiat sit consequat in aliqua mollit. Eiusmod ut anim excepteur ullamco cupidatat aliqua. Ea sunt qui incididunt commodo dolore labore eiusmod exercitation. Ut aute Lorem consequat sunt proident do excepteur.\r\n",
    "registered": "2016-10-03T10:41:12 +04:00",
    "latitude": 7.189025,
    "longitude": 154.651965,
    "tags": [
      "deserunt",
      "cupidatat",
      "duis",
      "excepteur",
      "sunt",
      "tempor",
      "est"
    ],
    "friends": [
      {
        "id": 0,
        "name": "Hamilton Morrison"
      },
      {
        "id": 1,
        "name": "Margarita Dominguez"
      },
      {
        "id": 2,
        "name": "Carey Atkinson"
      }
    ],
    "greeting": "Hello, John Mcfarland! You have 7 unread messages.",
    "favoriteFruit": "banana"
  }
]


const keys = [
  'name', 'email', 'age', 'eyeColor', 'gender'
]

const table = document.querySelector('table')
const tableHeader = document.createElement('tr')
const tableBody = document.createElement('tbody')
tableHeader.innerHTML = keys.map(key => `<th>${key}</th>`).join("")

table.appendChild(tableHeader)
table.appendChild(tableBody)

function fillTableData(dataset){
  tableBody.innerHTML = dataset.map(row => {
    return `<tr>${keys.map(key => `<td>${row[key]}</td>`).join("")}</tr>`
  }).join("")
}

fillTableData(data)

//generate filters
document.getElementById('filters').innerHTML = keys.map(key => {
  const options = data.reduce((arr, row) => {
    let val = row[key]
    if(arr.indexOf(val) < 0) arr.push(val)
    return arr
  }, []).sort()
  return `<label>${key}<select data-filter="${key}"><option value=""> </option>${options.map(option => `<option value="${option}">${option}</option>`).join("")}</select></label>`
}).join("")

//filter function
function filterData(){
  const options = Array.prototype.reduce.call(document.querySelectorAll('select[data-active="active"]'), (obj, elem) => {
    obj[elem.getAttribute('data-filter')] = elem.value
    return obj
  }, {})
  console.log(options)
  return data.filter(row => {
    for(let key in options){
      if(row[key] != options[key]) return false
    }
    return true
  })
}
//set up filtering
Array.prototype.forEach.call(document.querySelectorAll('select'), elem => {
  elem.addEventListener('change', function(){
    if(this.value) this.setAttribute('data-active', 'active')
    else this.removeAttribute('data-active')
    
    fillTableData(filterData())
  })
})
<table></table>
<br><br>
<div id="filters"></div>


推荐阅读