Reputation: 1695
Bottom Line:
I'm having trouble retrieving the value of multiple data-attributes and inserting them as the text of a child element.
Details:
I've got a table
with each tr
"bucket" containing a particular number of three kinds of shapes (spheres, cubes, pyramids), which are stored in data-attribute
s. I've got a ul
with corresponding li
s for each shape. When a shape is checked, tr
s with more than 0 of that shape are highlighted. HOWEVER, I'm also trying to retrieve the number for each selected shape and display it in the td.contents
element for each tr
(i.e. "pyramids: 300, cubes: 50"), which is what I have been unsuccessful with.
Here's the HTML -
<ul>
<li data-shape="spheres">spheres</li>
<li data-shape="cubes">cubes</li>
<li data-shape="pyramids">pyramids</li>
</ul>
<table>
<tr data-spheres="380" data-cubes="0" data-pyramids="200"><td>bucket 1</td><td class="contents">no shapes selected</td></tr>
<tr data-spheres="0" data-cubes="90" data-pyramids="0"><td>bucket 2</td><td class="contents">no shapes selected</td></tr>
<tr data-spheres="100" data-cubes="20" data-pyramids="400"><td>bucket 3</td><td class="contents">no shapes selected</td></tr>
<tr data-spheres="500" data-cubes="110" data-pyramids="0"><td>bucket 4</td><td class="contents">no shapes selected</td></tr>
</table>
And JS (line 22 is where I'm having trouble) -
(function() {
//store tr elements
var buckets = $('tr');
$('li').click(function () {
//toggle checked class OK
$(this).toggleClass('checked');
//reset classes and .contents text OK
$(buckets).removeClass('active');
$('td.contents').text('no shapes selected');
//map the shape data attribute for all li elements
//with class '.checked' OK
var checkedShapes = $('.checked').map(function() {
return $(this).data('shape');
});
//for each checked shape, filter tr elements with
//more than 0 of that shape OK
$.each(checkedShapes, function( index, value ) {
var filteredBuckets = $(buckets).filter(function() {
return $(this).data(value) > "0";
});
//add .active class to those tr elements OK
$(filteredBuckets).addClass('active');
//get number of checked shapes (i.e. "pyramids: 300, cubes: 50")
//and display in td.contents DOESN'T WORK
$('tr.active td.contents').text($(this).parent('tr').data(value));
});
});
})();
And a jsFiddle: http://jsfiddle.net/a8gtrn63/33/
From what I understand in the docs for .data()
, this should be retrieving the selected data attributes, but it isn't. I think there may be an issue with the value
reference, but I'm having trouble seeing it. Any input is greatly appreciated.
Upvotes: 3
Views: 830
Reputation: 111
The $(this) was referring to the $.each loop and not the text, so I fixed it by iterating through the elements and then used $(this):
(function() {
//store tr elements
var buckets = $('tr');
$('li').click(function () {
//toggle checked class OK
$(this).toggleClass('checked');
//reset classes and .contents text OK
$(buckets).removeClass('active');
$('td.contents').text('no shapes selected');
//map the shape data attribute for all li elements
//with class '.checked' OK
var checkedShapes = $('.checked').map(function() {
return $(this).data('shape');
});
//for each checked shape, filter tr elements with
//more than 0 of that shape OK
$.each(checkedShapes, function( index, value ) {
var filteredBuckets = $(buckets).filter(function() {
return $(this).data(value) > "0";
});
//add .active class to those tr elements OK
$(filteredBuckets).addClass('active');
//get number of checked shapes (i.e. "pyramids: 300, cubes: 50")
//and display in td.contents DOESN'T WORK
$('tr.active td.contents').each(function(){
$(this).text($(this).parent('tr').data(value));
});
});
});
})();
Upvotes: 1
Reputation: 76426
This is how your code should look alike:
(function() {
//store tr data-attributes
var buckets = $('tr');
$('li').click(function () {
//toggle checked class
$(this).toggleClass('checked');
//reset classes and .contents text
$(buckets).removeClass('active');
$('td.contents').text('no shapes selected');
//map the shape data attribute for all li elements with class '.checked'
var checkedShapes = $('.checked').map(function() {
return $(this).data('shape');
});
//for each checked shape, filter tr elements with more than 0 of that shape
$.each(checkedShapes, function( index, value ) {
var filteredBuckets = $(buckets).filter(function() {
return $(this).data(value) > "0";
});
//add .active class to those tr elements
$(filteredBuckets).addClass('active');
//get number of checked shapes and display in td.contents
//$('tr.active td.contents').text($(this).parent('tr').data(value));
$(filteredBuckets).each(function() {
var currentText = $($(this).find("td")[1]).text();
if (currentText.indexOf(":") === -1) {
$($(this).find("td")[1]).text(value + ": " + $(this).data(value));
} else {
$($(this).find("td")[1]).text($($(this).find("td")[1]).text() + ", " + value + ": " + $(this).data(value)); }
});
});
});
})();
Explanation: You need to iterate the filteredBuckets
and set the desired text for each element. If it already has some shape data, then we append the new shape data and if there is no previous shape data, then we replace the old text to the new shape data.
Upvotes: 0