复选框多个过滤器-纯JS

时间:2019-05-13 10:43:35

标签: 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('');
};

2 个答案:

答案 0 :(得分:1)

您可以尝试这样:

const array = [{
    "name": "John",
    "surname": "XYZ",
    "department": "IT"
  },
  {
    "name": "John",
    "surname": "XYZ",
    "department": "accountancy"
  },
  {
    "name": "Paul",
    "surname": "XYZ",
    "department": "Chemistry"
  }
];

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

function generateTableHead(table, data) {
  const thead = table.createTHead();
  const row = thead.insertRow();
  for (const key of data) {
    const th = document.createElement("th");
    const [first, ...rest] = key;
    const heading = `${first.toUpperCase()}${rest.join('')}`;
    const text = document.createTextNode(heading);
    th.appendChild(text);
    row.appendChild(th);
  }
}

function generateTable(table, data) {

  for (let i = 1; i < table.rows.length;)
    table.deleteRow(i);

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

function onDepartmentChange(event) {
  const currentDepartment = event.currentTarget.value;
  let filteredArray = [];

  if (this.checked) {
    filters.push(currentDepartment); 
  } else {
    filters = filters.filter(x => x !== currentDepartment);
  }
  
  if (filters.length === 0) {
    filteredArray = array;
    generateTable(table, filteredArray);
    return;
  }
  
  filteredArray = array.filter(x => filters.some(y => y === x.department));
  generateTable(table, filteredArray);
}

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

document.querySelectorAll('[name=deptFilter]')
  .forEach(x => x.addEventListener('change', onDepartmentChange));
<table id="tblClass">
</table>

<br>
<label>Filter by department: 
  <br>
  <span> 
    <input name="deptFilter" type="checkbox" value ="IT"/> IT
    <input name="deptFilter" type="checkbox" value ="accountancy" /> Accountancy
    <input name="deptFilter" type="checkbox" value ="None" /> None
  </span>
</label>

答案 1 :(得分:1)

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

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>