Tips for implementing the JSON object table filter functionality

My website features a collection of json objects organized as shown below:

 [
    {
        "a": true or false,
        "b": "information",
        "c": "information",
        "d": "information",
        "e": "information"
    },
    ...
 ]

The goal here is to display all the objects in a table and include a checkbox for filtering out objects with a value of false. Initially, the site was intended to show the full list of unfiltered objects. However, upon adding the checkbox event listener, the entire list disappeared. When toggling the checkbox, it repeatedly adds more filtered content to the bottom of the table.

I'm struggling to identify what I'm doing wrong. The code snippet I've been working with is provided below:

var stuff = document.getElementById("stuff-info");
var ourRequest = new XMLHttpRequest();
ourRequest.open('GET', 'url');
ourRequest.onload = function() {
    var ourData = JSON.parse(ourRequest.responseText);
    renderHTML(ourData);
};
ourRequest.send();

function renderHTML(data) {
    var htmlString = "";
    var filteredData = data.filter(function(element) {
        return element.a
    });
    var checkbox = document.querySelector("input[name=hide]");

    checkbox.addEventListener('change', function() {
        if (this.checked) {
            for (i = 0; i < filteredData.length; i++) {
                htmlString += "<table><tr><td>" + filteredData[i].b + "</td><td>" + filteredData[i].c + "</td><td>" + filteredData[i].d + "</td><td>" + filteredData[i].e + "</td></tr>"
            }
        } else {
            for (i = 0; i < data.length; i++) {
                htmlString += "<table><tr><td>" + data[i].b + "</td><td>" + data[i].c + "</td><td>" + data[i].d + "</td><td>" + data[i].e + "</td></tr>"
            }
        }
        stuff.insertAdjacentHTML('beforeend', htmlString);
    });
}

Answer №1

It might be more simple to use a CSS selector for filtering:

#filter:checked ~ table .filter { display: none }
<input type=checkbox id=filter> Filter 

<table border=1>
  <tr class=filter><td>1</td><td>a</td></tr>
  <tr><td>2</td><td>b</td></tr>
  <tr class=filter><td>3</td><td>c</td></tr>
  <tr><td>4</td><td>d</td></tr>
</table>

Answer №2

As soon as I implemented the checkbox event listener, the entire table list vanished.

The logic for determining what to display is confined within the onchange event, causing no rendering until a checkbox is modified.

Upon checking the checkbox, I noticed that the filtered objects were being continuously added in duplicates.

All html strings are appended using += to the original htmlString variable within the closure, resulting in an ever-growing list of rows. Additionally, new strings are inserted into the DOM without replacing the old tables, leading to an exponential increase.


I believe incorporating higher order functions instead of traditional for loops would be beneficial. By utilizing the map array method to convert each item in the array into a string, the code becomes cleaner and more manageable.

This separation of rendering logic from event handling makes it much simpler to reuse the render function with varying data or events. It also enables easy addition of additional transformations or filters.

const ourRequest = new XMLHttpRequest();
ourRequest.onload = function() {
    const ourData = JSON.parse(ourRequest.responseText);
    initialRender(ourData);
};
ourRequest.open('GET', 'url');
ourRequest.send();

function filterAll() { return true; }
function filterA() { return element.a; }

function toRowString(item) {
  return `
    <tr>
      <td>${item.a}</td>
      <td>${item.b}</td>
      <td>${item.c}</td>
      <td>${item.d}</td>
      <td>${item.e}</td>
    </tr>`;
}

function renderTable(predicate, parentElement, data){
    const rows = data
        .filter(predicate)
        .map(toRowString);

    parentElement.innerHTML = `<table>${rows}</table>`;
}

function initialRender(data) {
    const stuff = document.getElementById("stuff-info");
    const checkbox = document.querySelector("input[name=hide]");

    renderTable(filterAll, stuff, data);

    checkbox.addEventListener('change', function(event) {
        renderTable( 
          event.target.checked ? filterA : filterAll,
          stuff,
          data
        );
    });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Access specific keys and values within a JSON array using Ruby

I am just starting out with Ruby, and I have a Json array that looks like this: "elements": [ { "type": "Contact", "id": "1", "createdAt": "131231235", "name": "test", "updatedAt": "1 ...

Turn off the background when the automatic popup box appears

I have implemented a popup box that automatically appears after 5 seconds when the site is loaded. However, if I click outside of the popup box, it closes. I want to disable the background when the popup box is displayed. If I remove the two lines of code ...

Tips for accessing JSON values in JavaScript

How can I extract values from a JSON object in JavaScript? Below is the code snippet I've tried: var obj={"0.5":0.009333, "0.21":0.048667,"0.31":0.070667}; var value =0.21; var p=0; for(i=0; i<= obj.length ;i++){ if(value== obj[i]) ...

Calculating the total sum in Vuejs when an event is triggered

I am faced with a situation where the price of a product is added to an existing total when a user increases the quantity. However, the problem lies in the fact that even if the user decreases the quantity, the price continues to increase. Solution html ...

The issue of AngularJS directive failing to update controller variable

After conducting an extensive search on both Google and Stack Overflow, I was unable to find a solution to the issue at hand. So, moving forward, here is the problem I am facing: I have created a directive that is intended to retrieve data selected in a ...

Getting a product by its slug can be achieved with Next.js 14 and Sanity by utilizing the capabilities

My dilemma involves retrieving specific product details based on the current slug displayed in the browser. While I successfully retrieve all products using the following code: export async function getAllProducts() { const productData = await client.fe ...

What is the best way to clear and fill a div without causing it to resize?

I am faced with a challenge involving four thumbnail divs labeled .jobs within a #job-wrap container. When a .job is clicked, I want the #job-wrap to fade out, clear its contents, load information from the selected .job, and then fade back in. However, whe ...

Angular 2 ngFor generates a collection of rows and columns forming a single large column

It seems that ngfor is generating divs one by one, resulting in a poor design where they are stacked on top of each other. I would like to achieve a layout like this: [1] [2] [3] [4] [5] [6] However, the current outcome looks like this: [ 1 ] [ 2 ] [ 3 ...

TypeScript compilation error - No overload is compatible with this call

Currently, I am working on a project using TypeScript alongside NodeJS and Express. this.app.listen(port, (err: any) => { if (err) { console.log("err", err) } else { console.log(`Server is listing on port ${port}`); } }); The co ...

Seeking assistance with basic Javascript/Jquery for Ajax on Rails 3 - can anyone help?

I've been diving into JavaScript and hit a roadblock. At the moment, I have a very basic gallery/image application. My goal is to create a functionality where clicking on an image will lead the user to a URL stored in my model data using AJAX. Additi ...

Label dynamically generated from user input for radio button option

In my attempt to develop a radio group component, I encountered an issue where the value of one radio option needs to be dynamically set by an input serving as a label. While I have successfully created similar components before without React, integrating ...

Tips for adding a picture to a server and applying CSS filters to enhance it

I recently came across a set of CSS filters that can be applied to images by simply specifying the filter ID. Now, I'm looking to create a button that will allow me to save the edited image (with the filter applied) to a designated file location. I&a ...

A guide on Implementing PastBack Functionality with AJAX Responses

When I make a GET request for an HTML page, I come across the following element: <a id="ctl00_cphRoblox_ClaimOwnershipButton" href="javascript:__doPostBack('ctl00$cphRoblox$ClaimOwnershipButton','')">Claim Ownership</a> My ...

Change the value of input on onClick event in React

Although this may seem simple, it is a little confusing to me. I'm having trouble understanding why the input value in the following case is not being reset. handleReset() { this.setState({ data: "" }); } <button onClick={this.handleReset}>R ...

Unraveling Nested JSON with Redshift and PostgreSQL

Attempting to extract 'avg' from a JSON text through the use of JSON_EXTRACT_PATH_TEXT() function. Here is a snippet of the JSON: { "data":[ { "name":"ping", "idx":0, "cnt":27, "min":16, ...

Setting up the customized filename for precompiled Handlebars templates

When compiling Handlebars templates with the NPM package, is there a way to manually adjust the name/index that is generated? In my experience using Handlebars in various environments like Rails, NodeJS, and PHP, I've observed that the generated temp ...

Unusually Elevated Frame Rates within Three.js

I just launched a new website yesterday, which is dedicated to live editing three.js examples. I noticed that whenever I make updates to the code or switch between different example files, the frame rate of the site jumps up to around 1000 f/s. You can fi ...

Begin the Wordpress AJAX Login

Is there a way to trigger the code below when a user is logged out from another location due to user inactivity, similar to how wp-admin displays an AJAX login overlay if a user is logged out? I have not come across any documentation or tutorials on achiev ...

Use a conditional statement for each element within the array

Below is the code I am currently using: if (res[0].toString() == "hello") { res[0] = "string"; }; While it works, I would like this logic to apply to all elements rather than just the first one. Is there a way to achieve this for every element in the ar ...

What is the best way to create a sortable column that is based on a nested object within data.record?

I am utilizing jquery jtable to showcase some data in a table. I have been using the following code snippet for each field in the table to display the data and enable sorting: sorting: true, display: (data) => { return data.record.<whatever_value ...