Is it possible to search for a specific value within a field in a JSON array that may contain multiple values?

My challenge involves an ajax query that fetches results to be displayed in an html table as shown below:

<input type="button" value="Customer" onclick="SelectCustomer()">
<input type="button" value="Advisor" onclick="SelectAdvisor()">
<input type="button" value="Get Results" onclick="GetResults()">
<table id="results">
</table>

I aim to filter these results based on the affected area, displaying items with a status of Open and specific areas like Advisors or Customers. While my current filtering code successfully filters by Status, I face difficulties when trying to filter by the Affected Area field. Experimenting with JavaScript variables to store selection information for filtering has not yielded expected results, especially if the field contains multiple values.

var dResponse = [
    {"Reference": "123456","Status": "Open","AffectedArea": ["IT","Advisor"]}
    {"Reference": "654321","Status": "Closed","AffectedArea": ["Customer","IT"]}
    {"Reference": "567889","Status": "Open","AffectedArea": ["Advisor","Customer"]}
    {"Reference": "987654","Status": "Open","AffectedArea": ["Customer"]}
]
var custSelect = "Unselected";
var adviSelect = "Unselected";
var custfil = "";
var advifil = "";

function SelectCustomer(){
    if (custSelect == "Unselected") {
        custSelect = "Selected";
        adviSelect = "Unselected";
    } else {
        custSelect = "Unselected";
    }
}
function SelectAdvisor(){
    if (adviSelect == "Unselected") {
        adviSelect = "Selected";
        custSelect = "Unselected";
    } else {
        adviSelect = "Unselected";
    }
}

function GetResults() {
    var results = document.getElementById("results");
    var filResponse = dResponse.filter(function(item){
        return item.Status == "Open";
    })
    if (custSelect == "Selected"){
        FilterCust();
    }
    if (adviSelect ==" Selected"){
        FilterAdvi();
    }
    results.innerHTML += "<tr><td>Reference</td><td>Status</td><td>Affected Area</td></tr>";
    for(var obj in filResponse){
        results.innerHTML += "<tr><td>" + dResponse[obj].Reference + "</td><td>" + dResponse[obj].Status + "</td><td>" + dResponse[obj].AffectedArea + "</td></tr>";
    }
}

function FilterCust() {
 filResponse = dResponse.filter(function(item){
  return item.ImpactedArea == "Customer";
})
}
function FilterAdvi() {
 filResponse = dResponse.filter(function(item){
  return item.ImpactedArea == "Advisor";
})
}

The JSON results display multiple values in the same field, stemming from a REST query to a SharePoint list. Despite facing challenges with filtering, the script manages to extract data as intended.

Answer №1

Instead of keeping track of individual variables like custSelect and adviSelect, I recommend storing them in an array for a cleaner and more efficient approach. You can then use the array with the some function to perform filtering.

<input type="button" value="Customer" onclick="handleOnChange(this.value)" />
<input type="button" value="Advisor" onclick="handleOnChange(this.value)" />
<input type="button" value="Get Results" onclick="GetResults()" />
<table id="results">
  <!-- Table content will be generated dynamically using JavaScript -->
</table>
<script>
  const dResponse = [
    {
      Reference: '123456',
      Status: 'Open',
      AffectedArea: ['IT', 'Advisor']
    },
    {
      Reference: '654321',
      Status: 'Closed',
      AffectedArea: ['Customer', 'IT']
    },
    {
      Reference: '567889',
      Status: 'Open',
      AffectedArea: ['Advisor', 'Customer']
    },
    {
      Reference: '987654',
      Status: 'Open',
      AffectedArea: ['Customer']
    }
  ];

  let selectedArea = [];
  const handleOnChange = value => {
    const index = selectedArea.findIndex(a => a === value);
    if (index > -1) {
      selectedArea.splice(index, 1);
    } else {
      selectedArea.push(value);
    }
  };

  const GetResults = () => {
    const results = document.getElementById('results');
    const filResponse = dResponse.filter(item => item.Status == 'Open' && selectedArea.some(a => item.AffectedArea.indexOf(a) > -1));
    results.innerHTML +=
      '<tr><td>Reference</td><td>Status</td><td>Affected Area</td></tr>';
    filResponse.forEach(item => {
      results.innerHTML +=
        '<tr><td>' +
        item.Reference +
        '</td><td>' +
        item.Status +
        '</td><td>' +
        item.AffectedArea +
        '</td></tr>';
    });
  };
</script>

Update (11/22/2019) :

<!DOCTYPE html>
<html>
  <head>
    <style>
      .selected {
        background: yellow;
      }
    </style>
  </head>
  <meta charset="utf-8" />
  <body>
    <form onsubmit="GetResults(event)">
      <input type="button" name="AffectedArea" value="IT" onclick="handleToggleOnChange(this)" />
      <input type="button" name="AffectedArea" value="Customer" onclick="handleToggleOnChange(this)" />
      <input type="button" name="AffectedArea" value="Advisor" onclick="handleToggleOnChange(this)" />
      <select name="Status" onchange="handleSelectOnChange(this)">
        <option value="Open" selected="selected">Open</option>
        <option value="Closed">Closed</option>
      </select>
      <input type="submit" />
    </form>
    <table id="results">
      <!-- Table content will be created with Javascript -->
    </table>
    <script>
      const dResponse = [
        {
          Reference: "123456",
          Status: "Open",
          AffectedArea: ["IT", "Advisor"]
        },
        {
          Reference: "654321",
          Status: "Closed",
          AffectedArea: ["Customer", "IT"]
        },
        {
          Reference: "567889",
          Status: "Open",
          AffectedArea: ["Advisor", "Customer"]
        },
        {
          Reference: "987654",
          Status: "Open",
          AffectedArea: ["Customer"]
        }
      ];

      // Store form's filter data
      const formData = {
        AffectedArea: [],
        Status: 'Open',
      }

      const handleToggleOnChange = input => {
        const { name, value } = input;
        const index = formData[name].findIndex(a => a === value);
        if (index > -1) {
          input.classList.remove('selected');
          formData[name].splice(index, 1);
        } else {
          input.classList.add('selected');
          formData[name].push(value);
        }
        // Display formData
        console.log(formData);
      };

      const handleSelectOnChange = (select) => {
        const { name, value } = select;
        formData[name] = value;
        // Display formData
        console.log(formData);
      }

      const createRow = () => document.createElement("tr");

      const createColumn = (text, colspan) => {
        const column = document.createElement("td");
        const textNode = document.createTextNode(text);
        column.appendChild(textNode);
        column.setAttribute('colspan', colspan);
        return column;
      };

      const GetResults = (e) => {
        e.preventDefault();
        const results = document.getElementById("results");
        const filResponse = dResponse.filter(
          item =>
            // Status must be Open
            item.Status == formData.Status &&
            // Item's AffectedArea's array includes one of the selected area
            formData.AffectedArea.some(a => item.AffectedArea.indexOf(a) > -1)
        );
        // Clear previous result
        while (results.firstChild) {
          results.firstChild.remove();
        }
        // Create header row
        const headerRow = createRow();
        let headerKeys = [];
        if (dResponse.length > 0) {
          headerKeys = Object.keys(dResponse[0]);
          headerKeys.forEach(key => {
            headerRow.appendChild(createColumn(key));
          });
        }
        results.appendChild(headerRow);
        // Create content result rows
        if (filResponse.length > 0) {
          const rows = [];
          filResponse.forEach(item => {
            const row = createRow();
            Object.values(item).forEach(value => {
              row.appendChild(createColumn(value));
            });
            rows.push(row);
          });
          if (rows.length > 0) {
            rows.forEach(r => {
              results.appendChild(r);
            });
          }
        } else {
          // Create no results found row
          const row = createRow();
          row.appendChild(createColumn("No results found", headerKeys.length));
          results.appendChild(row);
        }
      };
    </script>
  </body>
</html>

This is a unique implementation where I suggest utilizing arrays for efficient filtering in your project. I have provided additional options for user selection and improved organization of the code. Check out the live demo for a better understanding:

Live Demo Link: https://codesandbox.io/s/html-filter-table-demo-qm19r?fontsize=14&hidenavigation=1&theme=dark

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

Encountered an error with Aurelia webpack 4 when trying to load a necessary CSS file during runtime

I encountered a unique issue with webpack and aurelia that I can't seem to figure out. After creating a new webpack configuration based on online resources and official documentation, the compilation goes smoothly without any errors. However, during r ...

The PHP function is not successfully receiving a value from the AJAX call to be entered into the Database

I've been struggling with a piece of code lately, trying to pass the value 1 to my database when a user clicks the "collect coins" button. The goal is to reset the column "dailyfree" every day at 12 pm so that users can click the button again on the n ...

When the jQuery button is clicked, the execute function will run multiple times

I am attempting to create a button using jQuery that calls a JavaScript function, but I am facing an issue : Upon loading the page, the first click on mybutton does not elicit any response The second click results in the function being executed twice On ...

User events in the fullCalendar

I'm feeling stuck. I currently have a basic fullCalendar setup for the User model in Rails. I want to add 2 buttons, allowing the User to separate the calendar into two views. One view would display only their own events, while the other would show al ...

The tooltip function is not functioning properly on Internet Explorer when the button is disabled

I have been utilizing a similar solution found at http://jsfiddle.net/cSSUA/209/ to add tooltips to disabled buttons. However, I am encountering an issue specifically in Internet Explorer (IE11). The workaround involves wrapping the button within a span: ...

Creating Text Transitions with JavaScript in Qualtrics: An In-Depth Guide

Currently, I am creating a survey using Qualtrics and I require various texts that will fade in and out within the same area. The goal is to have text that changes every second, displaying the following: Choose a language Escolha um idioma Elija un idiom ...

If the option of "none" is chosen, I would like to deactivate all checkbox selections

Struggling with disabling all checkboxes in a PHP form when the NONE option is selected. <h5>HEALTH OF STUDENT</h5> <p>Any physical, emotional, or other difficulties to be aware of?</p> <table> <td>Hearing ...

Can the table be automatically updated on page reload?

My goal is to populate a table using $.ajax(), but the content is not showing up when the page first loads. Is there something missing in my implementation of the $.ajax() function? Here's the HTML structure: <div class="row"> <div clas ...

What are some effective ways to optimize a scrolling script?

Within my div element, I have a list of ordered elements (ol) that I am manipulating with drag and drop functionality using jQuery Nestable. If you could help me troubleshoot this issue, it would be greatly appreciated: How to scroll the window automatical ...

linking a div within a navigation bar

I have implemented a template from bootstrap. Here is the navigation bar where you can find the about section. Inside it, there is a bootstrap button: <button type="button" class="btn btn-light">Light</button> When I click on this button, the ...

combine all of the values listed below into one cohesive value

Is there a way to merge multiple objects into a single object recursively? Each iteration of my code produces a string object that I store in a list. The list contains the following: bean [String1, String2, String3]. These three strings need to be combine ...

Expo constants failing to load on web due to unresolved manifest object issue

When setting up Firebase Auth in my expo app (using Google Auth), I needed to store my firebase variables in a .env file containing API_KEYS, AuthDomain, and more. To access these environment variables, I utilized expo constants in my firebase.ts file. Ini ...

The module script failed to load due to an unexpected response from the server, which was MIME type of text/jsx instead of a javascript module script

I have recently set up an express server and created an API, as well as installed React using Vite for my frontend. However, when I attempt to connect or load my main HTML file to the server, an error is displayed in the console. This is all new to me as I ...

Make sure the inputs in separate table data cells are lined up in

I need help aligning two input fields in separate td elements to be on the same line. The issue I am encountering is that when an input is added to a td, it covers up any text within the td. https://i.stack.imgur.com/c7GiQ.png There are two scenarios: I ...

What is the best way to incorporate Cross-Origin Resource Sharing (CORS

How do I go about implementing CORS in jQuery? I've been attempting to create a basic page scraper, but keep encountering an Access-Control-Allow-Origin error. Below is the code I've been using: $(document).ready(function(){ $('#start' ...

Is the scrolling functionality acting strange while using React Three Fiber?

In my React Three Fiber application, I have the following structure: Website Canvas NativeHTMLContent Canvas Website The issue I'm facing is that after scrolling down the entire canvas, the scrollbar resets to the top and starts scrolling from the t ...

When utilizing jQuery lightbox to pull data from a database using PHP/Ajax, it may require a double click the

Encountering a strange issue where I must click on specific buttons with unique IDs. These IDs are then sent through Ajax to a PHP script, which searches for corresponding entries in the database. The retrieved data is then displayed in a jQuery lightbox. ...

What is the best way to access the dimensions of a parent element in React with Hooks?

I am currently working on a new component and I am facing the challenge of obtaining the width and height of its parent <div>. Since all my components are functional ones using Hooks, the examples I found involving classes do not fit my case. Here i ...

Encountered an error with symbol '@' while utilizing ES6 decorators

I have recently set up a React project and now I'm attempting to integrate MobX into it. This requires using decorators such as: @observable However, when I try to implement this, I encounter the following error: https://github.com/mobxjs/mobx Mod ...

Debugging JavaScript in ASP .NET (solving quick breakpoint problems)

There seems to be a mystery about setting breakpoints in my JavaScript code - sometimes it works, other times it doesn't. Despite all efforts, I can't seem to figure out what factors contribute to this inconsistency. While debugging the dynamic p ...