Browsing a collection of objects in JavaScript to sift through them

I have a situation where I created an array of objects and implemented a function to loop through this array, generating HTML elements and populating them with values from the objects. These elements are appended to existing HTML tags on the page. Currently, the result is a list displayed on the webpage. However, I am seeking assistance in utilizing user input to filter through the array of objects. I want to display only the values that match the user's input. Can anyone provide guidance or help?

let internationalCountries = [
    {
        name: "Spain",
        method: "Delivery",
        price: "£10.99",
    },
    {
        name: "Germany",
        method: "Delivery",
        price: "£8.99",
    },
    {
        name: "Japan",
        method: "Delivery",
        price: "£39.99",
    },
]

let renderCountryList = () => {
    let list;
    let itemName = "";
    let para1;
    let para2;
    let method = "";
    let price = "";
    let ul = document.querySelector('.country-list')
    let deliveryInfo = document.querySelector('.delivery-info')
    for (let i = 0; i < internationalCountries.length; i++){
        list = document.createElement('li')
        itemName = document.createTextNode(internationalCountries[i].name)
        list.appendChild(itemName)
        ul.appendChild(list)
        para1 = document.createElement('p')
        para2 = document.createElement('p')
        method = document.createTextNode(internationalCountries[i].method)
        price = document.createTextNode(internationalCountries[i].price)
        para1.appendChild(method)
        para2.appendChild(price)
        deliveryInfo.appendChild(para1)
        deliveryInfo.appendChild(para2)
    }
}
renderCountryList()
<input type="text" placeholder="Search..." id="searchInput">
<div>
  <ul class="country-list">
  
  </ul>
</div>
<div class="delivery-info">

</div>

Answer №1

Here is the solution:

Check out the live demo here: CODEPEN solution

<input type="text" placeholder="Search..." id="searchInput">
<div id="info-wrapper">
  <div>
    <ul class="country-list">

    </ul>
  </div>
  <div class="delivery-info">

  </div>
</div>
const internationalCountries = [
    {
        name: "Spain",
        method: "Delivery",
        price: "£10.99",
    },
    {
        name: "Germany",
        method: "Delivery",
        price: "£8.99",
    },
    {
        name: "Japan",
        method: "Delivery",
        price: "£39.99",
    }
]

const backToStartStage = () => {
    let divSection = document.querySelector('#info-wrapper')
    divSection.innerHTML = '<div><ul class="country-list"></ul></div><div class="delivery-info"></div>'
}

const renderCountryList = (country) => {
    let list;
    let itemName = "";
    let para1;
    let para2;
    let method = "";
    let price = "";
    let ul = document.querySelector('.country-list')
    let deliveryInfo = document.querySelector('.delivery-info')
    
    list = document.createElement('li')
    itemName = document.createTextNode(country.name)
    list.appendChild(itemName)
    ul.appendChild(list)
    para1 = document.createElement('p')
    para2 = document.createElement('p')
    method = document.createTextNode(country.method)
    price = document.createTextNode(country.price)
    para1.appendChild(method)
    para2.appendChild(price)
    deliveryInfo.appendChild(para1)
    deliveryInfo.appendChild(para2)
}

$(document).ready(function(){
  $("input#searchInput").keyup(function(){
    const input = $("input#searchInput").val();
    const found = internationalCountries.filter(country => {
      return country.name.toUpperCase() === input.toUpperCase()
    })
    if(found.length > 0) {
       backToStartStage()
       renderCountryList(found[0])
    } else {
      backToStartStage()
    }
  });
});

Answer №2

To trigger a function when the user types in an input field, you can utilize the onkeyup() method and pass the value of the input to a specified function such as printResults(). This function will then clear any existing content within the ul and div, and proceed to filter the results based on the input value. If the filtered results return an empty array, nothing will happen; otherwise, it will iterate through each result using a forEach loop.

Tip: breaking down your code into smaller functions can greatly improve its readability and maintainability.

Give it a try:

let internationalCountries = [
    {
        name: "France",
        method: "Standard Shipping",
        price: "$12.99",
    },
    {
        name: "Italy",
        method: "Express Shipping",
        price: "$15.99",
    },
    {
        name: "Australia",
        method: "DHL Express",
        price: "$29.99",
    },
];

const filterData = (val) => {
  val = val.toLowerCase().trim();
  return internationalCountries.filter(item => item.name.toLowerCase() == val);
}

const printResults  = (val) => {
  let ul = document.querySelector('.country-list');
  let shippingDetails = document.querySelector('.shipping-details');
  ul.innerHTML = "";
  shippingDetails.innerHTML = "";
  
  let results = filterData(val);
  
  results.forEach((item, index) => {
    createListElement(ul, item.name);
    createP(shippingDetails, item.method);
    createP(shippingDetails, item.price);
  });
}

const createListElement = (ul, val) => {
  let list = document.createElement('li');
  let itemName = document.createTextNode(val);
  list.appendChild(itemName);
  ul.appendChild(list);
}

const createP = (div, val) => {
  let p = document.createElement('p');
  let text = document.createTextNode(val);
  p.appendChild(text);
  div.appendChild(p);
}
<input type="text" placeholder="Search..." id="searchInput" value="" onkeyup="printResults(this.value)" />
<div>
  <ul class="country-list">
  
  </ul>
</div>
<div class="shipping-details">

</div>

Answer №3

Provide some example input for the input field and show sample results in the list. Do you plan to search only by country name or do you require additional configuration? Please include those specifics as well.

If your search criteria is limited to country names, you can utilize the following code snippet:

let internationalCountries = [
    {
        name: "Spain",
        method: "Delivery",
        price: "£10.99",
    },
    {
        name: "Germany",
        method: "Delivery",
        price: "£8.99",
    },
    {
        name: "Japan",
        method: "Delivery",
        price: "£39.99",
    },
]

let onChangeText = (e) => {
    renderCountryList(e.target.value);
}

document.querySelector('#searchInput').addEventListener('keyup', onChangeText);

let renderCountryList = (searchedName) => {
    let list;
    let itemName = "";
    let para1;
    let para2;
    let method = "";
    let price = "";
    let ul = document.querySelector('.country-list')
    let deliveryInfo = document.querySelector('.delivery-info')
    ul.innerHTML = null;
    deliveryInfo.innerHTML = null;
    
    res = searchedName ? internationalCountries.filter(item => item.name.toLowerCase().indexOf(searchedName.toLowerCase()) > -1) : [...internationalCountries];
    for (let i = 0; i < res.length; i++){
        list = document.createElement('li')
        itemName = document.createTextNode(res[i].name)
        list.appendChild(itemName)
        ul.appendChild(list)
        para1 = document.createElement('p')
        para2 = document.createElement('p')
        method = document.createTextNode(res[i].method)
        price = document.createTextNode(res[i].price)
        para1.appendChild(method)
        para2.appendChild(price)
        deliveryInfo.appendChild(para1)
        deliveryInfo.appendChild(para2)
    }
}
renderCountryList()
<input type="text" placeholder="Search..." id="searchInput" >
<div>
  <ul class="country-list">
  
  </ul>
</div>
<div class="delivery-info">

</div>

Answer №4

Create a simple layout with

HTML

<input type="text" placeholder="Enter query here" onkeyup="searchFunction(this.value)" />
<ul class="results-list"&rt;</ul>

Javascript

<script>
let searchResults = [{name: "Apple",category: "Fruit",price: "$1.99"},{name: "Banana",category: "Fruit",price: "$0.99"},{name: "Orange",category: "Fruit",price: "$2.49"}];
const searchFunction  = (val) => {
  let ul = document.querySelector('.results-list');
  ul.innerHTML = '';
  let results = searchResults.filter(({name, category, price}) => (name+category+price).toLowerCase().includes(val));
  results.forEach((item, index) => {
    ul.innerHTML += `<li>${item.name}<p>${item.category}</p><p>${item.price}</p></li>`;
  });
}
</script>

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

Converting & Modifying a PHP array variable into JavaScript

I've been experimenting with a fresh method for users to input data into an HTML form using the Slim Select JavaScript library. So far, I've got the basic functionality down, including a preset list of <option> items. Previously, the PHP ...

Hey there, what exactly does 'TypeError: Cannot access the 'scopedFn' property of an undefined object' mean?

Having trouble implementing RadListView with Nativescript-Vue. I am attempting to utilize a v-template for the header followed by another v-template for the list itself. 1) The header does not seem to be recognized, as only the standard v-template is disp ...

Using memoization with lodash isEqual to compare property objects

Working with a component that updates the state for animation, I decided to enhance performance by adding shouldComponentUpdate(prevProps) { return !isEqual(prevProps.properties, this.props.properties) } to its child components. The properties ob ...

Issue with directive not activating when attribute is changed

I am facing an issue with my website where users can make selections from two dropdowns, and based on those values, attributes are sent to directives for a corresponding function to be called. The problem I'm encountering is that the directives are n ...

Transferring specific form data through a POST request

I am attempting to transfer specific values from a form to PayPal once the form is submitted. Below is the code for my form: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <form class="form-horizo ...

Guide on deploying a Next.js React project with IIS on a Windows Server

Our goal is to deploy the application on an IIS server while ensuring it supports dynamic routing. After attempting to install IIS node, we are unsure of our next steps. Do we need to load a specific file like server.js in order to run the application ...

button for resetting the zoom in Highcharts

Attempting to manipulate the visibility of the Zoom Button on a highstock chart through x axis zooming with the navigator feature enabled. The default behavior seems to disable the button in this scenario. While there are functions allowing for display, I ...

What is causing the premature termination of the for loop?

I am currently utilizing Node.js (with nodemon as the server) to upload an excel file, parse its contents, and then send each row to a MongoDB database. The total number of rows in the array is 476, however, the loop seems to stop at either 31 or 95 withou ...

Modify the style of ckeditor's <span> attribute

When using CKEditor in text areas of my form, I encountered an issue with the default style not matching the black background of the site. Here is the basic toolbar setup: CKEDITOR.replace( 'editor1', { toolbar : [ [ 'Bold', &ap ...

When a model.find is passed as an argument to be invoked, it results in an error

After working with ExpressJS for a while, I decided to explore using Mongoose alongside it. In the callback of my queries where I handle errors like this: function( error, data ) {...} , I found myself repeating code. To streamline this process, I created ...

Is it possible to pass a variable as an input parameter in the Date constructor when creating a timestamp in Firebase

I'm looking to work with timestamp queries. Note: setSD and setED are part of the Vue object's data, and the firebase function call is within the method. callFirebase: function (){ let startdate = new Date(this.setSD+'T00:00:00&apo ...

Evaluating operational Angular component - Error: $(...).somename function is not defined

I've encountered an issue while attempting to test my component in Angular. The component itself functions correctly during regular use, but when I try to run the tests using "yarn run test", I receive the following error message: HeadlessChrome 0.0. ...

Identifying an Android device using Javascript or jQuery

Is there a way to identify an Android device for styling a mobile website? I want to add specific CSS styles for users on the Android platform. Appreciate any help! ...

Is there a shorter method to continuously run a function based on keypress in a specific scenario?

What is the goal of my task? My objective is to keep the movement of the TrumpHead going until another key is pressed to change its direction, similar to the game snake. I am considering creating multiple cases with functions containing cases within each ...

Filtering nested JSON objects of children using a specific value in Angular 8

Within the function filterchildrenByRegion(), I am receiving an API response. My goal is to eliminate objects that do not match the selected Region and return all data as it is. Example 1 - If I input '1UL Africa' into the changeRegion() functi ...

Renewing Firebase User Token in Angular Using HTTP Interceptor

I've encountered a puzzling issue while implementing error handling in my Angular HTTP Interceptor code. It appears that the code within my chain of ".then()" statements is being triggered out of order somehow. Here's a snippet of my code... im ...

Can a menu with data-toggle='dropdown' remain visible even after clicking on it?

I have a dropdown menu that I created with the use of data-toggle='dropdown'. Everything seems to be working fine as the buttons close the menu upon clicking, except I would like the gray button (as shown below) to keep the menu open. https://i. ...

What is the best way to transmit extra data when tunneling a TLS connection?

I have developed a basic HTTP proxy that utilizes the HTTP CONNECT method for HTTP tunneling. const http = require('http'); const https = require('https'); const pem = require('pem'); const net = require('net'); con ...

Vue 2 draggable does not maintain reactivity when the v-model value consists of a parent tag's iterable

Utilizing Vue 2 alongside Vuex, the incoming object gets organized into distinct sub-objects according to the classCategory value. Could it be failing because the v-model value in draggable is a key sourced from the parent tag object? <div class="c ...

Exploring VueJs 3's Composition API with Jest: Testing the emission of input component events

I need help testing the event emitting functionality of a VueJs 3 input component. Below is my current code: TextInput <template> <input v-model="input" /> </template> <script> import { watch } from '@vue/composition-api&ap ...