Add/Remove Table Columns in JavaScript Based On Checkbox Status

Tags: ,



In the following DEMO if you paste the list in the search box:

00001, 00002, 00003, 00004, 00005, 00006, 00007, 00008, 00009, 00010, 00011, 00012, 00013

It will pull the respective property features from a JSON file that is located here: https://api.myjson.com/bins/f2nos

var data = {};

$(document).ready(function () {
    $("#Search").click(function (any) {
		$("tbody").empty();
        var searchIds = new Set($('#searchBox').val().split(/[ ,rn]+/).map(s => s.trim()));
        searchIds.forEach(CODE =>
			
            $("tbody").append('<tr>' + `<td class="theader1" id="theader1">${CODE}</td>` + `<td class="theader2" id="theader2">${datab[CODE]}</td>` + `<td class="theader3" id="theader3">${datac[CODE]}</td>` + `<td class="theader4" id="theader4">${datad[CODE]}</td>` + '</tr>'));
    });
});

function getdata() {
    fetch("https://api.myjson.com/bins/f2nos").then(resp => resp.json()).then(resp => {
        datab = Object.assign({}, ...resp.features.map(
            ({ properties: { CODE, DIVISION}}) => ({ [CODE]: DIVISION}))
        );
        datac = Object.assign({}, ...resp.features.map(
            ({ properties: { CODE, PROVINCE}}) => ({ [CODE]: PROVINCE}))
        );
        datad = Object.assign({}, ...resp.features.map(
            ({ properties: { CODE, NAME}}) => ({ [CODE]: NAME}))
        );		
    });
}

getdata();						
	
/*Checkbox To Table Head*/
$("input:checkbox:not(:checked)").each(function() {
    var column = "table ." + $(this).attr("name");
    $(column).hide();
});

$("input:checkbox").click(function(){
    var column = "table ." + $(this).attr("name");
    $(column).toggle();
});
  <head>
   <title>Code Table</title>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  </head>
  <body>
	<span class="clearable">
		<input id="searchBox" type="text" rows="25" cols="15" WRAP="HARD" placeholder="Paste the list HERE" type="search">
	</span>
	<button class="button button1" id="Search">Search</button>	
	</br>
	<p><input type="checkbox" class="theader1" name="theader1" checked="checked"> CODE
  <input type="checkbox" class="theader2" name="theader2" checked="checked"> DIVISION
  <input type="checkbox" class="theader3" name="theader3" checked="checked"> PROVINCE
  <input type="checkbox" class="theader4" name="theader4" checked="checked"> NAME</p>
	</br>
		<table border="1px" id="data">
			<thead>
			<tr>
			<th class="theader1" id="theader1">CODE</th>
			<th class="theader2" id="theader2">DIVISION</th>
			<th class="theader3" id="theader3">PROVINCE</th>	
			<th class="theader4" id="theader4">NAME</th>
			</tr>
			</thead>
			<tbody></tbody>
		</table>

The checkboxes control whether or not the table columns are visible.

So if you uncheck checkbox CODE, CODE column will disappear

One small problem.

When I uncheck any checkboxes BEFORE the search, for example CODE, and then search I get this weird table: enter image description here

The reason that is happening is because even though the checkbox is unchecked the APPEND() Statement still appends the CODE column.

So how to connect the checkbox status to the append statement so that columns don’t show up even after the search?

I’m assuming the solution is to turn every Table TD into a variable and somehow connect it to the status of the checkbox?

How to achieve this? Or better solutions?

Answer

“So how to connect the checkbox status to the append statement so that columns don’t show up even after the search?”

“I’m assuming the solution is to turn every Table TD into a variable and somehow connect it to the status of the checkbox?”

“How to achieve this? Or better solutions?”

You are correct, it is the way the rows are appended to the table without checking if any of the checkboxes were unchecked. The following are the changes made:

  • All checkboxes have only one class: .theader

  • All <td> have the #ids removed, it’s invalid HTML to have duplicated #ids plus it served no purpose anyhow.

  • Below is the solution to the issue concerning column generation:

   searchIds.forEach(CODE => {
     // Row template stored as an array of strings 
     var theader = [
       `<td class="theader1">${CODE}</td>`, 
       `<td class="theader2">${datab[CODE]}</td>`,
       `<td class="theader3">${datac[CODE]}</td>`, 
       `<td class="theader4">${datad[CODE]}</td>`
     ];
     // <tr> is appended before <td> is generated 
     $("tbody").append('<tr></tr>');
     // Each checkbox...
     $('.theader').each(function(idx) {
        // ...that is checked... 
        if ($(this).is(':checked')) {
          // ...will append the string from the array according to current index
          $("tbody tr:last").append(`${theader[idx]}`);
        }
     });
  });

var datab, datac, datad;
$("#Search").click(function() {
  $("tbody").empty();

  var searchIds = new Set($('#searchBox').val().split(/[ ,rn]+/).map(s => s.trim()));

  searchIds.forEach(CODE => {

    var theader = [`<td class="theader1">${CODE}</td>`, `<td class="theader2">${datab[CODE]}</td>`, `<td class="theader3" >${datac[CODE]}</td>`, `<td class="theader4">${datad[CODE]}</td>`];
    $("tbody").append('<tr></tr>');
    $('.theader').each(function(idx) {

      if ($(this).is(':checked')) {
        $("tbody tr:last").append(`${theader[idx]}`);
      }
    });
  });
});


function getdata() {
  fetch("https://api.myjson.com/bins/f2nos").then(resp => resp.json()).then(resp => {
    datab = Object.assign({}, ...resp.features.map(
      ({
        properties: {
          CODE,
          DIVISION
        }
      }) => ({
        [CODE]: DIVISION
      })));
    datac = Object.assign({}, ...resp.features.map(
      ({
        properties: {
          CODE,
          PROVINCE
        }
      }) => ({
        [CODE]: PROVINCE
      })));
    datad = Object.assign({}, ...resp.features.map(
      ({
        properties: {
          CODE,
          NAME
        }
      }) => ({
        [CODE]: NAME
      })));
  });
}

getdata();

/*Checkbox To Table Head*/
$(".theader:not(:checked)").each(function() {
  var column = "table ." + $(this).attr("name");
  $(column).hide();
});

$(".theader").click(function() {
  var column = "table ." + $(this).attr("name");
  $(column).toggle();
});
<head>
  <title>Code Table</title>

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>

<body>
  <fieldset>
    <input id="searchBox" placeholder="Paste the list HERE" type="search">

    <button type="button" id="Search">Search</button>
    <br><br>
    <input type="checkbox" class="theader" name="theader1" checked="checked"> CODE
    <input type="checkbox" class="theader" name="theader2" checked="checked"> DIVISION
    <input type="checkbox" class="theader" name="theader3" checked="checked"> PROVINCE
    <input type="checkbox" class="theader" name="theader4" checked="checked"> NAME

  </fieldset>
  <br>
  <table border="1px" id="data">
    <thead>
      <tr>
        <th id="theader1" class="theader1">CODE</th>
        <th id="theader2" class="theader2">DIVISION</th>
        <th id="theader3" class="theader3">PROVINCE</th>
        <th id="theader4" class="theader4">NAME</th>
      </tr>
    </thead>
    <tbody>

    </tbody>
  </table>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


Source: stackoverflow