Reputation: 1109
This should be a nice easy one for someone - I have a table row that slideToggle
s when an image is clicked. As the table is dynamic, there could be any number of rows so I have had to identify the areas to show/hide by classname.
Not a problem. However, I only ONE instance of the extrainfo
div to be shown at once. As one is shown, any already visible should be hidden:
EDIT: Here is a fiddle: http://jsfiddle.net/shpsD/
Added HTML below.
var toggleSpeed = 300;
var expandImg = "../Images/expand.png";
var collapseImg = "../Images/collapse.png";
$(".moreless").click(function () {
var detailsRow = $(this).parent().parent().next();
detailsRow.find('.extrainfo').slideToggle(toggleSpeed);
if ($(this).attr('src') == collapseImg) {
$(this).attr('src',expandImg);
$(this).closest('tr').removeClass('highlight_row');
}
else {
$(this).attr('src',collapseImg);
$(this).closest('tr').addClass('highlight_row');
}
});
});
-
<table>
<tr>
<th>Header</th>
<th></th>
</tr>
<tr>
<td>row 1</td>
<td><img src="expand.png" class="moreless" /></td>
</tr>
<tr>
<td colspan="2">
<div class="extrainfo">
EXTRA INFO!!
</div>
</td>
</tr>
<tr>
<td>row 2</td>
<td><img src="expand.png" class="moreless" /></td>
</tr>
<tr>
<td colspan="2">
<div class="extrainfo">
EXTRA INFO!!
</div>
</td>
</tr>
</table>
Upvotes: 0
Views: 1009
Reputation: 253308
First hide the elements:
$('table .extrainfo').slideUp();
You could also use the :visible
selector, if you want, though it doesn't necessarily make things any faster, but perhaps a little more understandable:
$('table .extrainfo:visible').slideUp();
And then show:
detailsRow.find('.extrainfo').slideDown();
Edited with regards to the comment left by the OP (below):
It works fine when switching between rows, but it is not possible to hide all rows, as if only a single row is expanded it slides up and then immediately down. Any ideas?
I'm not sure, this was a pretty quick look once I'd finished work, but I might be over-doing things, but the following seems to work as you'd require:
$(".moreless").click(function() {
// caching variables:
var that = $(this),
table = that.closest('table'),
row = that.closest('tr'),
visInfo = table.find('.extrainfo:visible').length,
extrainfo = row.next().find('.extrainfo');
// I suspect this conditional is flawed, and redundant,
// but essentially if there's already a visible element *and*
// the next '.extrainfo' element in the next row is visible,
// then we're having to toggle/close
if (visInfo == 1 && extrainfo.is(':visible')) {
// we're working on the row that's already visible:
extrainfo.slideToggle(toggleSpeed);
row.toggleClass('highlight_row');
}
else {
// not toggling the same table-row, so tidying up previously
// visible elements (if any)/removing 'highlight_row' class
// and also setting the src of the image to the expandImg
var highlighted = table.find('.highlight_row');
highlighted.find('.moreless').attr('src',expandImg);
highlighted.removeClass('highlight_row');
table.find('.extrainfo').slideUp(toggleSpeed);
// now we're showing stuff/adding the class
extrainfo.slideDown(toggleSpeed);
row.addClass('highlight_row');
}
// this effectively toggles the src of the clicked image:
that.attr('src', function(i,v) {
return v == expandImg ? collapseImg : expandImg;
});
});
(I'll add references and answer further questions once I've eaten...sorry!)
References:
Upvotes: 4
Reputation: 1862
first you can do:
$('.extrainfo').hide();
then once every extrainfo classed ones hide, you can go ahead and do :$(this).closest('.extrainfo').show();
if you know that extrainfo div is right after the link or div you click, you can do:
$(this).next('.extrainfo').show()
Upvotes: 0