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

Tips for executing Cross-Origin-Requests from Firebase Hosting to an AWS Lambda function

Excuse me, I'm still new to web development. I have a basic single-page website hosted on Firebase hosting that retrieves some information from an AWS Lambda function (I didn't use Google Cloud because it didn't support outbound requests fo ...

The issue arises when using an Angular directive with an input type set as "number"

When the input type is text, the code below works perfectly fine. However, it fails to function when the input type is changed to number. <div ng-app="myApp" ng-controller="myCtrl as model"> <input type="text" ng-model="cero" ng-decimal > ...

Navigating with hashtags in Angular2 and anchors does not change the page position

I recently came across a helpful post that showed me how to append a fragment to the URL. Angular2 Routing with Hashtag to page anchor Although the fragment is successfully added, I'm encountering an issue where the page does not scroll to the speci ...

Creating dynamic HTML table rows with data from a JSON object

Query: In search of a Jquery or JavaScript solution for generating dynamic table rows with colspan using the JSON structure provided below. I am encountering difficulties in creating the necessary rows and have attempted several approaches without success ...

Using the codesnippet feature in CKEditor in combination with highlight.js

I am currently experimenting with implementing the highlight.js library in conjunction with the CKEditor addon called CodeSnippet. Although I have successfully integrated the CodeSnippet addon into my CKEditor, the code is not being properly detected, col ...

Having trouble with Jquery's Scroll to Div feature?

When I click on the image (class = 'scrollTo'), I want the page to scroll down to the next div (second-container). I've tried searching for a solution but nothing seems to work. Whenever I click, the page just refreshes. Any help would be gr ...

Having trouble incorporating custom CSS into my Rails/Bootstrap project

I’m having trouble figuring out what I’m doing wrong. I’ve added custom files and tried to override the existing ones. application.css.scss @import 'bootstrap-sprockets'; @import 'bootstrap'; /* * This manifest file will be co ...

Angular fails to update input changes once ajax auto-complete populates several fields

I am currently working on a project that involves using jquery auto-complete with ajax to automatically populate 3 input fields: Product Code, Description, and Price. Additionally, there are two other fields, Quantity and Total, which utilize angular. How ...

Configuring Chart.js in Laravel to Initialize with Value of Zero

I'm struggling to set my Chart.js chart to zero in my Laravel project. Could someone please help me with this? $chartjs = app()->chartjs ->name('lineChartTest') ->type('bar') ->size(['width' => ...

What is the best way to combine two rows in a data table?

As I progress with my endeavor to construct a user-friendly transition matrix in R, following up on the previous post regarding adding a vertical line to the first column header in a data table, I am faced with a new challenge. Upon executing the provided ...

Having difficulty changing the visibility of a div element

I am currently working on a project that involves jQuery and ASP.Net. My main goal is to create a button that can hide/show a div using jQuery. Below is the code that I have implemented: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLI ...

What is the method for breaking down a React useState hook into separate variables within a namespace?

Personally, I like to group React props into namespaces for better organization. When using the useState hook, I follow this approach. function MyComponent() { const [todoCount, setTodoCount] = useState(100); const [doneCount, setDoneCount] = useSta ...

Aligning text appears fine in a full screen browser, but it can cause inconsistencies in appearance when resizing the window or viewing on a phone, as demonstrated in the

Hi there, I'm new to web design and I'm struggling to make my site look good on all screen sizes. I've created a page that should work well on any screen size: https://jsfiddle.net/garixakor/j0xck25v/1/ I attempted to center one of the par ...

concise stylus CSS selector

Is there a way to condense these stylus selectors for a cleaner look? #map > div.mapboxgl-control-container > div.mapboxgl-ctrl-top-left > div:nth-child(1) > button #map > div.mapboxgl-control-container > div.mapboxgl-ctrl-top-left > ...

Is concealing content using Javascript or jQuery worth exploring?

While I have been hiding content using display:none; in css, there are concerns that Google may not like this approach. However, due to the needs of jQuery animations, it has been necessary for me. Recently, I have come across a new method for hiding conte ...

Using -webkit-hyphens: auto in Safari does not function properly when the width is set to auto

I have a situation with an h3 element where I am unsure of its width. As a result, the width is set to auto by default. However, I need the text inside this element to have hyphenation applied to it. This h3 element is within a flex container along with an ...

Steps for assigning innerHTML values to elements within a cloned div

Currently, I am setting up a search form and I require dynamically created divs to display the search results. The approach I am taking involves: Creating the necessary HTML elements. Cloning the structure for each result and updating the content of ...

Comprehending the significance of *this* within class structures

I've got this code snippet below. class Node { constructor(value, parent, possibleChildren = []) { this.value = value; this.parent = parent; this.children = [] this.setChildren(possibleChildren); } setChildren(possibleChil ...

Instructions on incorporating domains into next.config.js for the "next/image" function with the help of a plugin

Here is the configuration I am currently using. // next.config.js const withImages = require("next-images"); module.exports = withImages({ webpack(config, options) { return config; }, }); I need to include this code in order to allow images from ...

Guide to removing a duplicate footer generated by a Rails application due to the use of .load in jQuery/AJAX

Currently, I am utilizing jQuery/AJAX to dynamically load a page within my rails application using the code snippet shown below: $("#div1").load(url); The challenge I am facing is that the loaded page contains its own footer. As a result, when this div i ...