javascript - 通过复选框进行多重过滤 - 纯 JS

标签 javascript arrays object checkbox

我想为表格创建过滤器。该表是从数组生成的。我已经创建了复选框,但现在卡住了。

我搜索了很多,但找不到解决方案。

我想根据生成的复选框过滤表格数据,但我不知道如何将它们连接在一起。我不知道如何从表中收集对象,这些对象将匹配复选框的值,以便在取消选择给定类型后过滤表的行。

我尝试使用 event.target.getAttribute('data-filter') 但我在过滤数组以匹配事件时遇到问题。

有没有可能只用纯 javascript 做这样的事情?

这里是我的代码:

let array= [
    {
        "name": "John",
        "surname": "XYZ",
        "department": "IT"
    },
    {
        "name": "John",
        "surname": "XYZ",
        "department": "accountancy"
    },

]

function generateTableHead(table, data) {
    let thead = table.createTHead();
    let row = thead.insertRow();
    for (let key of data) {
        let th = document.createElement("th");
        let text = document.createTextNode(key);
        th.appendChild(text);
        row.appendChild(th);
    }
}

function generateTable(table, data) {
    for (let element of data) {
        let row = table.insertRow();
        for (key in element) {
            let cell = row.insertCell();
            let text = document.createTextNode(element[key]);
            cell.appendChild(text);
        }
    }
}

let table = document.querySelector("table");
let data = Object.keys(array[0]);

generateTable(table, array);
generateTableHead(table, data);



// FILTER: checkboxes 

const getDepartments = array.map(function (element) {
    return [element.department].join('');
});

let departmentFilters = [...new Set(getDepartments)];


let createFilters = function () {
    box = document.querySelector('#filterType');
    box.innerHTML = departmentFilters.map(function (department) {
        let checkboxes = '<label>' +
            '<input type="checkbox" data-filter="' + department + '" checked>' + department +
            '</label>';
        return checkboxes;
    }).join('');
};

最佳答案

关于演示中评论的更改的详细信息

let array = [{
    "name": "Jane",
    "surname": "Doe",
    "department": "IT"
  },
  {
    "name": "John",
    "surname": "Doe",
    "department": "Finance"
  },
  {
    "name": "Darth",
    "surname": "Vader",
    "department": "Sith Lord"
  }
];

const table = document.querySelector("table");
const filters = document.querySelector('#filterType');

function generateTable(table, array) {
  let row, cell;
  array.forEach(function(obj) {
    row = table.insertRow();
    /*
    Object.entries returns an array of key/value pairs of
    an object
    To access kv pairs, detsructure each pair: [key, value]
    Each cell is assigned 'data-key' with value 
    */
    for (let [key, value] of Object.entries(obj)) {
      cell = row.insertCell()
      let text = document.createTextNode(value);
      cell.appendChild(text);
      cell.dataset.key = value;
    }
  });
  // generateTableHead is called on return
  let keys = Object.keys(array[0]);
  return generateTableHead(table, keys);
}

function generateTableHead(table, keys) {
  let thead = table.createTHead();
  let row = thead.insertRow();
  for (let key of keys) {
    let th = document.createElement("th");
    let text = document.createTextNode(key);
    th.appendChild(text);
    row.appendChild(th);
  }
}

/*
Pass the name of header and the array
The return is an array of values under the given key (header)
*/
function getKey(target, array) {
  let keyArray = array.map(function(obj) {
    for (let [key, value] of Object.entries(obj)) {
      if (key === target) {
        return value;
      }
    }
  });
  /*
  A fieldset is created with id of key
  The array of values is passed to createFilters on return
  */
  filters.insertAdjacentHTML('beforeend', `<fieldset id='${target}'><legend>${target}</legend></fieldset>`)
  createFilters(keyArray);
}

/*
A Set of the given array is converted back into an array
of unique values
Each checkbox is inserted into the newest fieldset
*/
function createFilters(array) {
  let set = Array.from(new Set([...array]));
  set.forEach(function(name) {
    let chk = `<label><input type="checkbox" data-filter="${name}" checked>${name}</label>`;
    filters.lastElementChild.insertAdjacentHTML('beforeend', chk);
  });
};

/*
This is the callback function called whenever a checkbox is
checked or unchecked.
The checked/unchecked checkbox (e.target) determines which cell is affected by comparing data-key and data-filter attribute values.
*/
function filterKey(e) {
  const tgt = e.target;
  let name = tgt.dataset.filter;
  let keys = document.querySelectorAll(`[data-key="${name}"]`);
  for (let cell of keys) {
    if (tgt.checked) {
      cell.closest('tr').classList.remove('off');
    } else {
      cell.closest('tr').classList.add('off');
    }
  }
}

generateTable(table, array);

/*
Pass any applicable key (header) and create a new filter
*/
// Uncomment any or all 
// getKey('name', array);
// getKey('surname', array);
getKey('department', array);

// Register the form to the change event
filters.onchange = filterKey;
.off {
  visibility: collapse;
}
<form id='filterType'></form>
<table></table>

关于javascript - 通过复选框进行多重过滤 - 纯 JS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56110725/

相关文章:

java - 泛型和数组

javascript - Javascript 中的自定义排序数组

css - 使图像替代文本在所有浏览器上看起来几乎相同

javascript - 快速 session 不会在页面之间持续存在

javascript - 响应式图像 map 卷展重新定位

javascript - jQuery ajax data.d 未定义

javascript - Grunt - fatal error 未定义不是函数

java - 颠倒句子中的单词

java - 如何在没有初始化和特定数量元素的情况下在 Kotlin 中创建对象数组?

javascript - 如何在 javascript 中对映射对象的数据进行分组?