Reputation: 69
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
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