1

I am have created a .each loop in JQUERY which loops through Data in a JSON file and then populates the content in little thumbnails. When you click on that thumbnail, it will then populate the post page with the matching content on the thumbnail.

The problem I am having is that when you click on each thumbnail, it only displays the last object in the array and not the corresponding content.

No matter which thumbnail I click on, it will show the last objects content. I would really appreciate some help.

I have attached a snippet of code along with the JSON data file. I have marked the problem area with a Problem comment.

I am not sure how to fix the closure issue.

CODE -

var newsData;
var eventsData;
var nightData;
var dineData;
var outData;
var videoData;
var data;
var str = 'news';

function getposts(str) {
    var baseUrl = 'http://www.capetownetc.com/api/get_category_posts/?slug=';
    $.ajax({
        type: 'GET'
        , url: baseUrl + str
        , data: {
            get_param: 'value'
        }
        , dataType: 'json'
        , success: function postData(data) {
            if (str == 'news') {
                newsData = data;
                displayPosts(newsData);
            }
            if (str == 'events') {
                eventsData = data;
            }
            if (str == 'nightlife%20culture') {
                nightData = data;
            }
            if (str == 'dine') {
                dineData = data;
            }
            if (str == 'family%20fun') {
                outData = data;
            }
            if (str == 'videos') {
                videoData = data;
            }
        }
    });
}
getposts('news');
getposts('events');
getposts('nightlife%20culture');
getposts('dine');
getposts('family%20fun');
getposts('videos');

function displayPosts(str) {
    data = str;
    if (str == 'news') {
        data = newsData;
    }
    if (str == 'events') {
        data = eventsData;
    }
    if (str == 'nightlife%20culture') {
        data = nightData;
    }
    if (str == 'dine') {
        data = dineData;
    }
    if (str == 'family%20fun') {
        data = outData;
    }
    if (str == 'videos') {
        data = videoData;
    }
    var maxLength2 = 6;
    var maxLength = 130;
    var imgTitle = {};
    var imgThumb = {};
    var cat = {};
    var ex = {};
    var text = {};
    $('#post-cont').empty();
    
    $.each(data.posts, function (i, item) {
        //TITLE
        imgTitle = item.title.replace('Newsflash:', '');
        console.log(imgTitle);
        
        //THUMBNAIL
        imgThumb = item.thumbnail_images.medium.url;
        
        //CATEGORY
        cat = item.categories[0].title;
        
        //EXCERPT
        ex = item.excerpt.substr(0, maxLength);
        
        //CONTENT
        text = item.content;
        
        $("#post-cont").append('<div class="p1 full-post-text" id="search-result"><a class="p1 link-click" target="_blank"></a><div class="p1 text-post-img"><span class="p1 card-img1" id="p1Img" style="background-image:url(' + imgThumb + ');"></span><a class="p1 post-cat">' + cat + '</a> </div><div class="p1 full-text-info"><h2 class="p1 text-heading" id="p1Heading">' + imgTitle + '</h2>' + ex + '</div></div>');
        
        //    POST POPULATE ***
    $(document).on('click', '#search-result', function(i, item) {
        $('#cont').css('left', '0px');
        $('#post-header').css('left', '0px');
        $('#post-cont').css('left', '-9999px');
        $('#slider').css('left', '-9999px');
        
        //Image Post1 ***PROBLEM AREA***
        
        $('#post-pop').append('<h1 class="post1 header">' + imgTitle + '</h1><p class="lay2 post-source"></p><p class="post1 text"></p><div class="post inter-tags"><ul class="post-tag-list" id="post-inter-tags"></ul></div>');
        
        console.log(imgTitle);
    
    });
        
    });
} //End of displayPosts
            <div class="post1 cont" id="cont">
                
                <div class="content-container">
                    <div class="header-img">
                        <span id="para-img"></span>
                    </div>

                    <div class="pageContent" id="post-pop">

                        
                    </div>
                </div>
                
            </div>

JSON Data File

  • The code inside the click will only run when you click - so `imgTitle` will be the value at the end of the loop. See http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – freedomn-m Mar 20 '17 at 09:44
  • Possible duplicate of [How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – freedomn-m Mar 20 '17 at 09:45
  • So then I should create a separate function maybe and then just call it in the onclick function? –  Mar 20 '17 at 09:47

2 Answers2

0

You are using img_title as global variable, hence it is updated till last element of the loop and stores last element details. If you have index, you can try something like

    $('#post-pop').append('<h1 class="post1 header">' + data.posts[i].img_title + '</h1><p class="lay2 post-source"></p><p class="post1 text"></p><div class="post inter-tags"><ul class="post-tag-list" id="post-inter-tags"></ul></div>');
Dave Ranjan
  • 2,966
  • 24
  • 55
  • Won't this have the same issue - instead of `img_title` being global? `i` will be global therefore give the last element. You might need more detail on how to use `i`. – freedomn-m Mar 20 '17 at 09:47
  • Thanks for the reply.. I see what you are saying.. The problem is, my data.posts[i] always gives me undefined and i'm not sure why :( –  Mar 20 '17 at 09:48
0

I have found some of the issues in your code

First,

Please put the click event handler outside the function (or) change why because for every item it will bind this click event and leads to multi times calling when click on any item.

$(document).on('click', '#search-result', function(i, item) {

to

$("#search-result").click(function(evt) {

Second,

For the title you need to manage through your code something like

add one attribute to the below div

<div class="p1 full-post-text" id="search-result">

attr-index to manage the current post/item details

<div class="p1 full-post-text" id="search-result" attr-index="'+i+'">

and inside the click event handler use that attribute and then you can fetch that data

var ind = $(this).attr("attr-index");
imgTitle = data.posts[ind].title;
Vara Prasad
  • 497
  • 3
  • 11
  • Thank you so much man! I really appreciate the help. I have been struggling with this throughout my code and I couldn't figure it out. Thanks for helping out and explaining the fault in what I was doing. You are a champ! –  Mar 20 '17 at 10:19
  • Thank you Darian :) – Vara Prasad Mar 20 '17 at 10:22