I am trying to filter a Javascript dictionary based on multiple conditions.
I tried doing these steps:
I created an empty dictionary variable
Selected the input element and get the raw HTML node
Saved the value of the element that was changed as a variable
Saved the id of the element that was changed as another variable
conditionally add values to the filters object
// 1. Create a variable to keep track of all the filters as an object. var filters = {}; // 3. Use this function to update the filters. function updateFilters() { // 4a. Save the element that was changed as a variable. let changedElement = d3.select(this); // 4b. Save the value that was changed as a variable. let elementValue = changedElement.property("value") console.log(elementValue); // 4c. Save the id of the filter that was changed as a variable. let filterId = changedElement.attr("id"); console.log(filterId); // 5. If a filter value was entered then add that filterId and value // to the filters list. Otherwise, clear that filter from the filters object. if (elementValue != "") { filters[filterId] = elementValue; } else { delete filters[filterId]; } // 6. Call function to apply all filters and rebuild the table filterTable();
In the next function I need to loop through the filters list and keep data that matches the filter values.
// 7. Use this function to filter the table when data is entered.
function filterTable() {
// 8. Set the filtered data to the tableData.
let filteredData = tableData;
// 9. Loop through all of the filters and keep any data that
// matches the filter values
Object.entries(filters).forEach(([filterId, elementValue]) => {
if (filters[filterId] != "") {
filteredData = filteredData.filter(entry => entry.datetime === elementValue);
}
if (filters[filterId] != "") {
filteredData = filteredData.filter(entry => entry.city === elementValue);
}
if (filters[filterId] != "") {
filteredData = filteredData.filter(entry => entry.state === elementValue);
}
if (filters[filterId] != "") {
filteredData = filteredData.filter(entry => entry.country === elementValue);
}
if (filters[filterId] != "") {
filteredData = filteredData.filter(entry => entry.shape === elementValue);
}
};
// 10. Finally, rebuild the table using the filtered data
buildTable(filteredData);
}
// 2. Attach an event to listen for changes to each filter
d3.selectAll("input").on("change", updateFilters);
// Build the table when the page loads
buildTable(tableData);
The interface looks like this:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/superhero/bootstrap.min.css"> -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<title>UFO Finder</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
<link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">
<link rel="stylesheet" href="static/css/style.css">
</head>
<body class="bg-dark">
<div class="wrapper">
<nav class="navbar navbar-dark bg-dark navbar-expand-lg">
<a class="navbar-brand" href="index.html">UFO Sightings</a>
</nav>
<div class="jumbotron">
<h1 class="display-4">The Truth Is Out There</h1>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-4">
<h3>UFO Sightings: Fact or Fancy? <small>Ufologists Weigh In</small></h3>
</div>
<div class="col-md-8">
<p>Some Text</p>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<form class="bg-dark">
<p>Filter Search</p>
<ul class="list-group bg-dark">
<li class="list-group-item bg-dark">
<label for="date">Enter Date</label>
<input type="text" placeholder="1/10/2010" id="datetime"/>
</li>
<li class="list-group-item bg-dark">
<label for="city">Enter a City</label>
<input type="text" placeholder="roswell" id="city">
</li>
<li class="list-group-item bg-dark">
<label for="state">Enter a State</label>
<input type="text" placeholder="ca" id="state">
</li>
<li class="list-group-item bg-dark">
<label for="Country">Enter a Country</label>
<input type="text" placeholder="us" id="country">
</li>
<li class="list-group-item bg-dark">
<label for="Shape">Enter a Shape</label>
<input type="text" placeholder="crcle" id="shape">
</li>
<!-- <li class="list-group-item bg-dark">
<button id="filter-btn" type="button" class="btn btn-dark" >Clear Table</button>
</li> -->
</ul>
</form>
</div>
<div class="col-md-9">
<table class="table table-striped">
<thead>
<tbody>
<tr>
<th>Date</th>
<th>City</th>
<th>State</th>
<th>Country</th>
<th>Shape</th>
<th>Duration</th>
<th>Comments</th>
</tr>
</tbody>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.js"></script>
<script type="text/javascript" src="./static/js/data.js"></script>
<script type="text/javascript" src="./static/js/ufo_starterCode.js"></script>
</body>
</html>
data.js
var data = [
{
datetime: "1/1/2010",
city: "benton",
state: "ar",
country: "us",
shape: "circle",
durationMinutes: "5 mins.",
comments: "4 bright green circles high in the sky going in circles then one bright green light at my front door."
},
{
datetime: "1/1/2010",
city: "bonita",
state: "ca",
country: "us",
shape: "light",
durationMinutes: "13 minutes",
comments: "Three bright red lights witnessed floating stationary over San Diego New Years Day 2010"
}
];
The goal is to be able to filter records in a table based on the filter search criteria entered by the user. Please note that I'm very new to Javascript. Any help is appreciated.
