Navigating an array like a pro / Unraveling the mystery behind click event targets

Currently, I am working on implementing an Add to Favorite feature. When I click on an icon, the breed next to that icon gets added to the likes array. I have created a renderLikes function to display the contents of the array on the screen. However, only one breed appears because of the elements.favorite.innerHTML='' part. If I remove that section, the entire array keeps getting added to the DOM tree whenever I click on an icon. Is there a way to render each item in the array individually like

item

,

item2

, and so forth?

Another issue I encountered is that sometimes when I click on an icon, it adds an empty element to the array. How can I prevent this problem from occurring?

<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        ul {
            list-style: none;
            line-height: 1.6;
        }
    .icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  stroke-width: 0;
  stroke: currentColor;
  fill: currentColor;
  vertical-align: middle;
  cursor: pointer;
  transition: transform .3s;
  transform: scale(0.8);
}
.icon:hover {
    transform: scale(1.6) rotate(-15deg);
}
.icon-fill {
    fill: red;
}
    </style>
    <title>Like Button Practice</title>
</head>

<body>
<ul class="list"></ul>

<h2>My Favorite Dogs</h2>
<div class="favorite">

</div>
    <script>

const data = [
    { 
        "breed": "Beagle",
        "characteristics": "playful" 
    },
    {
        "breed": "Golden Retriever", 
        "characteristics": "calm" 
    },
    {
        "breed": "Corgi", 
        "characteristics": "bright" 
    },
    {
        "breed": "Goldendoodle", 
        "characteristics": "gentle" 
    },
    {
        "breed": "Labrador Retriever", 
        "characteristics": "loyal" 
    },
]

const elements = {
    "icon": document.querySelectorAll('svg'),
    "dom": document.querySelector('.list'),
    "favorite": document.querySelector('.favorite')
}

const likes = [];

// Render method
function test() {
    data.map(item => {
        renderList(item.breed);        
        return item.breed;
    })
};
test();


function renderList(dog) {
    const markup = `
    <li id="${dog}">
        <svg class="icon icon-heart-outlined"><use xlink:href="icon/sprite.svg#icon-heart-outlined"></use></svg>  
        ${dog}
    </li>
    `;
    elements.dom.insertAdjacentHTML('beforeend', markup);    
}


function renderLikes(item) {
    const markup = `
    <p>${item}</p>
    `;
    elements.favorite.innerHTML = '';
    elements.favorite.insertAdjacentHTML('beforeend', markup);    
}


elements.dom.addEventListener('click', e => {


        const id = e.target.parentNode.id;

   if (e.target.matches('.icon, .icon *')) {

    // If (Beagle, Golden Retriever... does not exist in likes array, it returns -1)
    const index = likes.indexOf(e.target.parentNode.id);    

       if (index === -1) {

            likes.push(id);
            console.log(likes);

            likes.forEach(function( value ) {
            console.log( value );
            renderLikes(value);
});
        } else {
            likes.splice(index, 1);
        }
    }
});
    </script>
</body>
</html>

Answer №1

Absolutely, using innerHTML = '' essentially deletes all content within the element.

It's important to separate your data from the view in order to maintain a clean structure.

Here's how you can approach it:

  • Click on an element
  • Add it to a list
  • Display all elements in the list

This way, you only need to manage the data logic and let the render logic handle how it is presented.

For optimal consistency, start by ensuring that your render reflects the model accurately before focusing on performance optimizations like virtual DOM or differential rendering.

You could implement something like this:

const $likelist = document.querySelector('.likelist');
const likeTemplate = item => `<p>Something ... ${item} more text </p>`;
const renderLikes = () => $likelist.innerHTML = likes.map(item => likeTemplate(item)).join();
const addToLikelist = (element) => {
  // Check if the item is valid and not already in the list
  likes.push(element);
  renderLikes();
}

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

Empowering Components with React Hooks

I am currently in the process of transitioning from using class components to React hooks with the Context API. However, I am encountering an error and struggling to pinpoint the exact reason for it. Here are my Codes: // contexts/sample.jsx import React ...

Using JS/AJAX to update a section of a webpage when a button is clicked

Currently, I am working on developing a generator that will display a random line from a .txt file. Everything is going smoothly so far, but I have encountered an issue - I need a specific part of the page to refresh and display a new random line when a ...

What is the best way to access and utilize the data stored in my database using mySQL, PHP, and JavaScript?

My Objective : When a user selects a location from the dropdown list, I want the function "newMark()" to place a marker on Google Maps; Current Achievements : The map is displayed along with the select field containing all locations saved in my database. ...

Add a nested array to a designated key within an array

As I dive into PHP programming, I'm encountering some challenges in building a calendar. I am storing events in an array, with each day as a key. However, I've hit a roadblock where I can only display one event per day due to my current data stru ...

Obtaining an integer from a specific location within the argument vector using C programming

I have developed a C program that reads data from a table in a .txt file, makes modifications to it, and then outputs the modified table to another .txt file. One of the functions in the program is responsible for printing an empty line before the line spe ...

I am looking for a sample code for Tizen that allows scrolling of a <div> element using the bezel

Seeking a functional web application in Tizen that can scroll a div using the rotating bezel mechanism. I have dedicated several hours to getting it to work without success. I keep revisiting the same resources for the past three days: View Link 1 View Li ...

Order the variables in the dropdown menu based on the PHP variables

I currently have a select list that allows me to choose between two options: Popularity and Recently Ordered. My goal is to filter the objects on the page based on these attributes, connecting each option to its respective function in my dataloader.php fi ...

extracting generated hyperlinks through a JavaScript function via webdriver

Looking for help with accessing a tricky href that cannot be hardcoded due to dynamic generation: Base classes https://gist.github.com/codyc4321/724f05aca8f6775e2fc1 (access_link of interest) class HCCDriver(FirefoxDriver): def __init__(self, userna ...

Update the link by simply clicking on a div tag

I am currently working on a PHP page and my goal is to add the extension ?id=variable_value to its URL when I click on a specific div. However, whenever I try to do this, it shows me an error message stating that the URL with the extension is undefined. B ...

AWK: Converting an Uninitialized Variable to an "array" Type Instead of a "numeric-string" Type

Cracking the AWK recursion enigma. I'm faced with a recursive challenge that involves populating an array. However, I need to initially pass the array as a parameter, with the recursion responsible for filling it up. The issue arises when the recursi ...

Generate a Monaco Editor within a Vue.js component

Currently, I am integrating Monaco Editor with Vue.js and facing some confusion regarding how Monaco is being instantiated within the Vue component: 1) In my data() method, I have defined an editorEx object to be used for this purpose, like so: data() { ...

Transform the JSON format received from the API endpoint to make it suitable for use in the component

I'm working on a react-native app that fetches event data from a wordpress endpoint. Below is the JSON I receive from the wordpress API. How can I restructure it to fit into my calendar component? Where should I handle this restructuring in my app? ...

The sidebar navigation is not appearing on Safari and IOS devices

I am facing an issue with my fixed position navbar and sidebar menu buttons on mobile, specifically on IOS and Safari. When clicking on the cart or account buttons, the sidebar menu does not show up. It seems to be a compatibility issue, and I am looking f ...

The mySql INSERT query in my Node application is not returning any results, even after using res.json()

I have recently delved into using Node.js and I am facing a bit of a challenge. Currently, I am attempting to insert a new product into my table. However, the ID for the product is not set to auto-increment. Therefore, in order to save the ID, I am implem ...

Adjustable height and maximum height with overflow functionality

Currently, I am in the process of developing a task manager for my application and facing an obstacle when trying to calculate the height of a widget. My goal is to determine the maximum height (assuming a minimum height is already set) by subtracting a ce ...

Are there any substitute proxy servers that are capable of bypassing CORS restrictions using local IP addresses?

Successfully bypassing CORS for AJAX requests to public IP addresses using proxy servers has been a game-changer. Is there a similar approach that can be utilized for local IP addresses when the server is hosted off-site? Unfortunately, I lack the abilit ...

Encountering a console error while attempting to navigate to the 404 page on Angular

I am working on implementing a route to a page in Angular for handling incorrect URL addresses. Error Received in Console While there is no error message in my IDE, the console displays the following error: ERROR TypeError: Cannot read property 'name ...

Organizing an Ordered List of Items into Alternating Columns Using HTML

I am in the process of developing a responsive HTML design to showcase an array of organized data. For smaller screens, the layout will consist of a single column displaying items sequentially. However, on larger screens, the design should adapt to featur ...

Application crash imminent, alert: Uncaught TypeError detected - Unable to access property 'some' of undefined within React

My application has 3 sections. The first section consists of a form where users fill in details about watches, and the data is submitted using the submitHandler function. In the second part, users can enter watches from the first section. When a user click ...

Investigating the variety of HTTP 206 responses pertaining to video content

Currently, I am utilizing Amazon CloudFront to serve HTML5 videos. These videos are being requested through HTTP range requests and the expected responses are often in the form of HTTP 206 Partial Content. I have a requirement where I want to log the requ ...