Link to home
Start Free TrialLog in
Avatar of Animaze
AnimazeFlag for United States of America

asked on

Loop through list items with JQuery to style multiple lists

I'm looking to add a CSS class to highlight a row of list items. Technically this is table row type behavior where a whole row will be highlighted, but it is being done with a series of lists. The behavior I am looking for is when you mouse over a list item in one of these lists, JQuery calculates what position that list item is in the list and adds a class of "highlight" to that list item as well as the other list items in the same position in the other unordered lists.

I tried using JQuery to find the index() of the list item being hovered over and then applying a CSS class to that, but I think the index() would need to reset upon looping through each unordered list so could then look up that particular index in each list and style. Just not sure how to go about that.

So in the HTML example below contains three unordered lists, in the CSS I have them floated next to each other to form columns. if someone hovers over "List item 3" in List 1, "List item 3" in all unordered lists will be given a  class of "highlight" - Likewise if someone hovers over the same list item in List 2 or 3, resulting in a whole row being highlighted. The class applied should be removed on mouseout.
<!-- List 1 -->
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
</ul>

<!-- List 2 -->
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
</ul>

<!-- List 3 -->
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
</ul>

Open in new window

Avatar of Carl Tawn
Carl Tawn
Flag of United Kingdom of Great Britain and Northern Ireland image

There might be neater ways to do this, but try:
<html>
<head>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
  <style>
     .highlight { background-color: yellow; }
  </style>
</head>
<body>

<script type="text/javascript">
$(function() {
	$("li").hover(function (e) {
	    var idx = ($(this).index());
	    $('li').each(function() {
	        if (idx == $(this).index())
        	    $(this).addClass('highlight');
	    });
	    },
	    function(e) {
	    var idx = ($(this).index());
	    $('li').each(function() {
	        if (idx == $(this).index())
	            $(this).removeClass('highlight');
	    });
	});
});
</script>

<!-- List 1 -->
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
</ul>

<!-- List 2 -->
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
</ul>

<!-- List 3 -->
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
</ul> 

</body>
</html>

Open in new window

Avatar of Animaze

ASKER

Thanks for the solution carl_tawn.

That does work as expected, however, and I apologize for not mentioning before, but there's actually a deeper nest of lists - well here's the complete HTML so you can see. I tried implementing the code from your solution to this, but now it is acting strange - highlighting each group in the same position in other rows. I suspect it would just need to target the list items a bit differently?
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
<title>List Test</title>

<style>
.highlight { background: #ffc; }
ul { float: left; list-style-type: none; }
.specs ul { margin: 15px 0 }
</style>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
	$('#products .specs li').hover(function (e) {
	    var idx = ($(this).index());
	    $('#products .specs li').each(function() {
	        if (idx == $(this).index())
        	    $(this).addClass('highlight');
	    });
	    },
	    function(e) {
	    var idx = ($(this).index());
	    $('#products .specs li').each(function() {
	        if (idx == $(this).index())
	            $(this).removeClass('highlight');
	    });
	});
});
</script>
</head>
<body>

<ul id="products">
	<li>
		<div class="specs">
		<!-- List 1 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		
		<!-- List 2 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		
		<!-- List 3 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		</div>
	</li>
	<li>
		<div class="specs">
		<!-- List 1 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		
		<!-- List 2 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		
		<!-- List 3 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		</div>
	</li>
	<li>
		<div class="specs">
		<!-- List 1 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		
		<!-- List 2 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		
		<!-- List 3 -->
		<ul>
		<li>List item 1</li>
		<li>List item 2</li>
		<li>List item 3</li>
		<li>List item 4</li>
		</ul>
		</div>
	</li>
</ul>

</body>
</html>

Open in new window

You mean you just want to target the LI elements that are within the same DIV ?
Avatar of Animaze

ASKER

I'm including an image to better clarify. I guess really each "row" of list items - only highlight the row being hovered over. Not other "rows" in same position in other lists (not being hovered). So I think the JavaScript would still need to look outside the current div.specs if I understand your question correctly.

 User generated image
I think I see what you mean. Try this:
<script type="text/javascript">
$(document).ready(function() {
	$('#products .specs li').hover(function (e) {
	    var idx = ($(this).index());
            var listIdx = ($(this)).parent().index();
	    $('#products .specs li').each(function() {
	        if (idx == $(this).index() && $(this).parent().index() == listIdx)
        	    $(this).addClass('highlight');
	    });
	    },
	    function(e) {
	    var idx = ($(this).index());
            var listIdx = ($(this)).parent().index();
	    $('#products .specs li').each(function() {
	        if (idx == $(this).index() && $(this).parent().index() == listIdx)
	            $(this).removeClass('highlight');
	    });
	});
});
</script>

Open in new window

Actually, ignore that. IE wasn't showing the lists properly, and that version is highlighting columns instead of rows :)
ASKER CERTIFIED SOLUTION
Avatar of Carl Tawn
Carl Tawn
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Animaze

ASKER

Thanks so much for your help. Works perfectly.
And I think we both learned something new :)
Avatar of Animaze

ASKER

Absolutely! Thanks again. I can see using this for all kinds of things actually.