4

Scenario

  • A user clicks on an element, image background of that element has been changed and the data assigned to that element (onclick attribute) is inserted into localStorage: this part works fine.
  • Now toggle variable is set to 0, background image is changed and the data is being deleted from local storage : this part works fine.

  • ...

  • A user clicks on another element (first click data is deleted of prev div ). though a new data should be inserted in that case, but it does not?

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 on particular div clicked):-

enter image description here

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;
    //is anything in localstorage?
    if (localStorage.getItem('eventData') === null) {
        eventData = [];
    }else{
        // Parse 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;

    // Push the new data (whether it be an object or anything else) onto 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);
            //$('#fav'+ delete value.sess_id + '');
            //$('#fav'+ delete value.name + '');
            //$('#fav'+ delete value.city + '');
            //$('#fav'+ delete value.country + '');
            //$('#fav'+ delete value.event_url + '');
            delete value.sess_id;
            delete value.name;
            delete value.city;
            delete value.country;
            delete value.event_url;            
            //localStorage.removeItem(value.sess_id);

        });
        toggle = 1;
    }
    // Alert the array value
    // alert(eventData);  // Should be something like [Object array]
    // Re-serialize the array back into a string and store it in localStorage
    var jsondata=localStorage.setItem('eventData', JSON.stringify(eventData));
    console.log(jsondata);
}

Fiddle

Artur Filipiak
  • 9,027
  • 4
  • 30
  • 56
afeef
  • 547
  • 3
  • 9
  • 25
  • Can you try with plain js?It may force the cache somehow. Or force a refresh: copy the target in a node, then readd the node to dom with the new bg – cox Mar 28 '15 at 08:39
  • im unable to dig the issue – afeef Mar 28 '15 at 08:41
  • http://stackoverflow.com/questions/17886578/refresh-part-of-page-div - show a basic refresh of an element (not the page) – cox Mar 28 '15 at 08:47

1 Answers1

2

The main problem is that you're trying to JSON.stringify a normall javascript array:

eventData = [];

While that would work only if your data is an object : eventData = {};

The next thing is this:

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

With the above, you're actually emptying the object rather than deleting it. Therefore your new data looks like: {}{}{}{}{}... (means many empty anonymous objects). To delete the object, at first place you have to know which object exactly you want to delete ( (*) see the next part)


My advice/solution :

  • I would remove onclick attribute and use jQuery's .click() event handler instead.

  • I'd hold all the data in data attributes - this way you can very easily get the data asociated with the element as an object (without further processing).

  • Checking toggle state is unnecesary, since it's naturaly toggled on each click. You should only check the existence of the object and delete/insert it accordingly. For the image itself use .toggleClass() and set CSS class with a proper image background (instead of replacing it programatically).

  • (*) I'd give each object in localStorage a key, so that it could be recognised later on. It could be anything unique and recognizable ("matchable") with a specified element. I'd set it to 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(){

    // declare an empty object (not array):
    var eventData = {};
    // check localStorage first after the page is ready (not on click):
    if (localStorage.getItem('eventData') !== null) {
        // if there's any faved link in the localstorage, highlight it:
        $.each(eventData = JSON.parse(localStorage.getItem('eventData')), function(id){
            $('#'+id).addClass('faved');
        });
    }

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

Add a .faved class to your CSS, instead of replacing image background with jQuery:

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

JSFiddle

Artur Filipiak
  • 9,027
  • 4
  • 30
  • 56
  • there is bug when i click on star image is not changing its background image, (tablet samsung, android mobile ).. and after refresh working im not able dig issue. – afeef Mar 30 '15 at 12:32
  • @user4041461 I can't really find what may cause your issue. I have just checked it on every device I have and it works flawlessly. What browser (and release version) are you using? It does not work also on my JSFiddle example? – Artur Filipiak Mar 30 '15 at 12:51
  • exactly same issue as jsfiddle shows occurs in android mobile . – afeef Mar 30 '15 at 13:16
  • no it not working mozziila , chrome, saafri as well as.. toggling of images – afeef Mar 30 '15 at 13:51
  • Seems like android devices don't like `:hover` CSS. You may need to play with `@media` query breakpoints for screen sizes http://jsfiddle.net/xxuhL555/ Does it work? (I've set CSS `:hover` only for screens above 1224px) – Artur Filipiak Mar 30 '15 at 14:02
  • Sorry, I didn't own any Android device – Artur Filipiak Mar 30 '15 at 14:06
  • Does this work for you? http://jsfiddle.net/7gaxaxfu/ (images are changed on each click?) – Artur Filipiak Mar 30 '15 at 15:01
  • 1
    But what modification you want? Like I wrote before - it is the `:hover` effect issue. Hover makes no sense on mobile devices (IOS seems to handle that somehow, but android won't), you have to deal with `@media` query breakpoints for different screen sizes to disable `:hover` on small screens (my previous JSFiddle in the comment) or mobile detection (some jquery plugin may help), See this SO question: http://stackoverflow.com/questions/8291517/disable-hover-effects-on-mobile-browsers. There's **NO** truly foolproof approach to get rid of this, so I cannot just simply *fix it* for you. – Artur Filipiak Mar 30 '15 at 15:47
  • now i have got new issue that $('.favourate_dextop').click(function(e) works when html loads browser assign class to it ,,now problem occurs when page loads dynamicall (facebook load more say)..in this click events is not firing .how could i solve this issue. – afeef Mar 31 '15 at 14:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/74201/discussion-between-user4041461-and-artur-filipiak). – afeef Mar 31 '15 at 14:55