How can I remove a specific JSON object from localStorage based on the data associated with the element that is currently being clicked on?

Unique Scenario

  • A user interacts with an element, triggering a change in the background image and storing data related to that element in localStorage: this process functions correctly.
  • Next, the toggle variable is set to 0, the background image changes again, and the data is removed from local storage: this step also works as expected.

  • ...

  • However, when a user clicks on another element (causing the previous data to be deleted), new data should be inserted. Why does this not happen?

JSON Data:

 Object {
    sess_id   : 182104, 
    name      : "AUTOMECH FORMULA", 
    city      : "Cairo", 
    country   : "Egypt", 
    event_url : "automech-formula"
}

events:189 Object {
    sess_id   : 182104, 
    name      : "AUTOMECH FORMULA", 
    city      : "Cairo", 
    country   : "Egypt", 
    event_url : "automech-formula"
}

Snapshot for all data removed upon clicking a specific div:

HTML:

<div class="evt_date"  style="overflow:hidden" style="overflow:hidden" itemscope itemtype="http://schema.org/Event">                             
    <a href="javascript:void(0);"  class="favourate_dextop" id="fav'.$data[$k]['id'].'"  onClick=" favaorite('.$data[$k]['id'].',\''.$name_event.'\',\''.$event_city.'\',\''.$event_country.'\',\''.$event_urls.'\',this)"></a>
</div>

Javascript:

var image2 = 'http://im.gifbt.com/images/star1_phonehover.png';
var image1 = 'http://im.gifbt.com/images/star1_phone.png';
var toggle = 1;

function favaorite(sess_id,name,city,country,event_url,pointer){
    var eventData;
    // Checking if there is any data in local storage
    if (localStorage.getItem('eventData') === null) {
        eventData = [];
    }else{
        // Parsing the serialized data back into an array of objects
        eventData = JSON.parse(localStorage.getItem('eventData'));
        console.log(eventData);   
    }
    var details={};
    details.sess_id   = sess_id;
    details.name      = name;
    details.city      = city;
    details.country   = country;
    details.event_url = event_url;

    // Adding the new data to the array
    eventData.push(details);

    if (toggle == 1){
        console.log("1");
        $(pointer).closest('.evt_date').find('.favourate_dextop').css('background-image', 'url("' + image2 + '")');
        toggle = 0;
    }else{
        console.log("2");
        $(pointer).closest('.evt_date').find('.favourate_dextop').css('background-image', 'url("' + image1 + '")');
        $.each(eventData, function(key, value){
            console.log(value);
            delete value.sess_id;
            delete value.name;
            delete value.city;
            delete value.country;
            delete value.event_url;            
        });
        toggle = 1;
    }
    
    var jsondata=localStorage.setItem('eventData', JSON.stringify(eventData));
    console.log(jsondata);
}

Check out the Fiddle here

Answer №1

One of the main issues lies in attempting to use JSON.stringify on a standard JavaScript array:

eventData = [];

This approach will only work if your data is structured as an object: eventData = {};

Another concern pertains to the following actions:

delete value.sess_id;
delete value.name;
delete value.city;
delete value.country;
delete value.event_url;

The consequence of these actions is that instead of deleting the object, you are actually clearing it out. As a result, your new data resembles this: {}{}{}{}{}... (indicating numerous empty, unidentified objects). To successfully delete the object, you must first determine which specific one you intend to remove ( (*) refer to the subsequent section)


Here is my suggestion/solution :

  • Eliminate the onclick attribute and utilize jQuery's .click() event handler instead.

  • Store all data in data attributes - this facilitates easy retrieval of associated data with the element directly as an object (without additional processing).

  • Checking the toggle state is redundant since it toggles automatically upon each click. The focus should be on confirming the existence of the object and inserting/deleting it accordingly. Utilize .toggleClass() for the image itself and assign a CSS class with suitable image background (as opposed to programmatically replacing it).

  • (*) Assign a unique key to each object in localStorage so that it can be identified later on. This key could be anything distinctive and recognizable ("matchable") with a specified element. Consider setting it as the id attribute of the currently clicked element, like:

    fav1:{name :'blah', ...}, fav2:{...}, ...

HTML:

<a href="#" class="favourate_dextop" id="fav'.$data[$k]['id'].'"
    data-sess_id="'.$data[$k]['id'].'"
    data-name="'.$name_event.'"
    data-city="'.$event_city.'"
    data-country="'.$event_country.'" 
    data-event_url="'.$event_urls.'" >
</a>

jQuery:

$(document).ready(function(){

    // initialize an empty object (not an array):
    var eventData = {};
    // check localStorage once the page is fully loaded (not upon click):
    if (localStorage.getItem('eventData') !== null) {
        // highlight any favorited links present in localstorage:
        $.each(eventData = JSON.parse(localStorage.getItem('eventData')), function(id){
            $('#'+id).addClass('faved');
        });
    }

    // replace 'onclick' attribute with jQuery .click() event handler:
    $('.favourate_dextop').click(function(e){
        // prevent default link click behavior (instead of using "javascript:void(0);" in the href attribute):
        e.preventDefault();
        // verify if the link's "id" attribute (this.id) exists in the object:
        if (eventData[this.id] !== undefined) {
            // if yes, remove it:
            delete eventData[this.id];
        } else {
            // if not, add it:
            // retrieve all 'data' attributes of the element as an object using the .data() method
            eventData[this.id] = $(this).data();
        }
        // toggle '.faved' class:
        $(this).toggleClass('faved');
        // update localstorage:
        localStorage.setItem('eventData', JSON.stringify(eventData));
    });     
});

In your CSS, introduce a .faved class instead of changing the image background with jQuery:

.favourate_dextop.faved, .favourate_dextop:hover{
    background:url('http://im.gifbt.com/images/star1_phonehover.png') no-repeat;
}

JSFiddle

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

PHP isn't getting the AJAX POST data from the JavaScript file

I've been stuck on this issue for hours now, unable to find a solution. Here is the javascript code snippet: function sendMovement(cel) { var name = "test"; $.ajax({ type: 'POST', url: '../game.php', ...

Creating a connection between a secondary jQuery anything slider and a distinct CSS style on a webpage

Currently, I am attempting to incorporate two anything sliders within the same webpage. My goal is to apply unique styling to each slider. Despite my efforts, I am encountering difficulties in calling upon a second style sheet without it completely overr ...

How to Vertically Center a Span in a Mat-Header-Cell with Angular 5 Material

In my angular5 application, I am utilizing a material table to showcase some data. Within a mat-header-cell, I have a combination of a span and an img, and I'm attempting to align them correctly. This is how it currently appears: Below is the snipp ...

Target the CSS element with a specific class only if it is not the first child within its parent

In my coding project, I have created a div.container which contains multiple p elements. Some of these p elements have the class p.special. My goal is to select the p.special elements that are not positioned at the very top of the parent container (i.e., n ...

Creating a dynamic slideshow with automated arrow navigation is simpler than you may think

I have successfully tested the slideshow and it is functioning perfectly without any issues. I would like to have a dual slideshow setup (slideshow 1 and slideshow 2) with next and previous buttons, but I am interested in adding an automatic sliding featur ...

Implementing a FadeOut effect for the clicked link

When clicking on each link, I want the same link to fadeOut() after clicking on the ok button in the myalert() function. If clicked on cancel, it should not fadeOut(). How can I achieve this using the myalert() function? For example: http://jsfiddle.net/M ...

Adding a new column to a table that includes a span element within the td element

I am attempting to add a table column to a table row using the code below: var row2 = $("<tr class='header' />").attr("id", "SiteRow"); row2.append($("<td id='FirstRowSite'><span><img id='Plus' s ...

React- Input value disappears after submission

Implementing validation for email-based input has been a bit of a challenge for me. I have managed to set up the debounce function for onChange event handling, but encountered a strange issue. The problem arises when the user submits an invalid string bef ...

Navigating the missing "length" property when dealing with partial functions generated using lodash's partialRight

I've been utilizing MomentTimezone for time manipulation within the browser. My development stack includes TypeScript and Lodash. In my application, there is an accountTimezone variable set on the window object which stores the user's preferred ...

Gin and Golang: Implementing HTML files with CSS styling

I am still learning English, so please bear with me :) My issue is that when using Gin to load HTML, my HTML file contains an import (/stylesheet/index.css), but when I run my app with Gin, it gives an alert that the stylesheet file could not be loaded. ...

Get a CSV file through EmberJs

I have been experimenting with various function calls, but I am unable to figure out how to initiate a CSV download in EmberJs. Below is the most recent code I have tried: let endpoint = '/api/foo/'; let options = { url: endpoint, type: ...

Concealing elements using react navigation

Just diving into React.js and I've got a question regarding react router. I'm a bit confused about nested routes in react router. Let's say we have the following code snippet (taken from react-router's github page) <Router> < ...

Experience the power of Kendo UI Date Picker combined with AngularJS. When the datepicker is initialized, it starts

Check out my code snippet below: When the datepicker loads initially, it appears empty. However, if you remove ng-model from the directive template, the datepicker displays its initial value correctly. Yet, changing the selected date does not mark the fo ...

Struggling to properly line up the baselines of navigation list items that are styled as circular elements using CSS

I have transformed my navigation menu into a series of CSS circles with text inside. The issue I am facing is that the text spills out unevenly based on the amount of content in each circle. To address this, I used a JavaScript solution to center-align the ...

retrieving the outcome from a PHP script invoked through Ajax

Having trouble transferring the results of a PHP script to HTML input fields This is my PHP script: $stmt->execute(); if ($stmt->rowCount() > 0){ $row = $stmt->fetch(PDO::FETCH_ASSOC); echo 'Located: ' . $row[&ap ...

Changing the mouse cursor dynamically with Angular programming

What is the recommended approach for changing the mouse cursor programmatically in Angular? For instance: HTML: <div [style.cursor]="cursorStyle">Content goes here</div> or <div [ngStyle]="{ 'cursor': cursorStyle ...

The timing of jQuery's .load function appears to be off, catching us by surprise

My current challenge involves loading returned html from an .aspx page through AJAX, but facing a timing issue with a click event that needs to occur before executing some essential tasks. Specifically, the process begins when a user types in a text field ...

What is the best way to upload my React project to GitHub without adding the node modules directory?

I'm looking to share my React Project on GitHub, but I don't want to include the node modules folder. What's the best way to go about this? ...

Material UI does not have built-in functionality for displaying colored text within a multiline textfield component in React

Attempting to utilize the material ui library in a react app has brought an issue to light. It appears that styling colored text does not work as expected for multiline textfields. Consider the following scenario: import React, { Component } from 'r ...

What is the best approach for adding variable rows to a Postgres junction table: should you concatenate a query string, utilize multiple queries, or explore alternative methods

Below is the code snippet for handling a variable-length list of tags and inserting data into the database: // JSON object from req.body { "title": "title", "reference": "1213", "noteType": &q ...