uxkidd
uxkidd

Reputation: 69

How iterate a jQuery function for each slide in a slider?

Summary: The purpose of this is to display a 3-part slider that users can click through, and they can use the index on each slide to filter the cards on that slide to a specific topic. The filters are working fine, but there's a problem in the JavaScript when it populates the indices: it's populating an index for all 3 cards, and showing that large index on each slide. Instead, the index for each slide needs to be unique, and only contain the hashtags from the cards in that same slide. I really want to avoid duplicating code for the different slides.

HTML

The following HTML has 3 (li) slides. Each slide contains a visible index (.hashtag-list), and one or more article cards (.item). Each (.item) besides the first one contains a hidden input with one or more hashtag values.

<li class="trend-cards">
    <div class="card-items">
        <div class="item trendingtopiccardblock">
            <div class="hashtag-list"></div>
        </div>
        <div class="item">
            <input class="tags" type="hidden" value="TopicA,TopicB"/>
        </div>
        <div class="item">
            <input class="tags" type="hidden" value="TopicC"/>
        </div>
    </div>
</li>
<li class="trend-cards">
    <div class="card-items">
        <div class="item trendingtopiccardblock">
            <div class="hashtag-list"></div>
        </div>
        <div class="item">
            <input class="tags" type="hidden" value="TopicC, TopicD"/>
        </div>
        <div class="item">
            <input class="tags" type="hidden" value="TopicA,TopicC,TopicD"/>
        </div>
    </div>
</li>
<li class="trend-cards">
    <div class="card-items">
        <div class="item trendingtopiccardblock">
            <div class="hashtag-list"></div>
        </div>
        <div class="item">
            <input class="tags" type="hidden" value="TopicA, TopicD"/>
        </div>
        <div class="item">
            <input class="tags" type="hidden" value="TopicB,TopicC,TopicD"/>
        </div>
    </div>
</li>

JavaScript

The following jQuery pulls the values from the .tags classes, stores them in an array, removes duplicates, sorts them, and then populates the HTML in a callback. (Ignore the countryButtons and countries array, as that's not relevant.)

    populateHashtagList: function() {

        var $cards = $(".card-items .tags");
        var list = [];
        var $countryButtons = $('.card-filtering li .country-filtering');
        var countries = [];

        $countryButtons.each(function() {
           countries.push(this.firstChild.data.replace("#", "").toLowerCase());
        });

        //Get tag values, set to lowercase and store in List array
        $cards.each(function() {
            var tags = getTags($(this).val());
            $(tags).each(function (index, value) {
                var tagValue = value.toLowerCase();
                if($.inArray(tagValue, countries) === -1) list.push(value);
            });

        });

        //Remove duplicates from the array
        var uniqueTags = [];
        $.each(list, function(i, el){
            if($.inArray(el, uniqueTags) === -1) uniqueTags.push(el);

        });
        uniqueTags.sort(); 

        function getTags(parameter) {
            var arr = parameter.split(',');
            return arr;
        }

        //Populate hash-tag List
        var hashtagList = $('.hashtag-list');

        populateHashtagList();

        function populateHashtagList(callback) {

            $.each(uniqueTags, function(i, el){
                var htmlToInsert = '<span class="active"><a href="#">' + el + '</a></span>';
                hashtagList.append(htmlToInsert);
            });

            if(typeof callback == "function")
            callback();  
        }
    }

What I've tried

I appreciate any feedback and input on this. I want to learn how to do this better in the future. Thank you very much!

Upvotes: 0

Views: 1687

Answers (1)

MakG
MakG

Reputation: 1274

Wrapping this code in .each() function is the best solution here. You said you tried that and you probably forgot to specify parent element for cards and hashtag-list selectors.

Here is a working example: https://jsfiddle.net/k3oajavs/

$(".trend-cards").each(function(){
    var $cards = $(".card-items .tags", this);
    // ...
    var hashtagList = $('.hashtag-list', this);
});

Upvotes: 1

Related Questions