Solved

Loop through list items with JQuery to style multiple lists

Posted on 2011-02-23
10
869 Views
Last Modified: 2012-05-11
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

0
Comment
Question by:Animaze
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
10 Comments
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 34968181
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

0
 

Author Comment

by:Animaze
ID: 34972618
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

0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 34972711
You mean you just want to target the LI elements that are within the same DIV ?
0
Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

 

Author Comment

by:Animaze
ID: 34972871
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.

 Example image
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 34973377
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

0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 34973398
Actually, ignore that. IE wasn't showing the lists properly, and that version is highlighting columns instead of rows :)
0
 
LVL 52

Accepted Solution

by:
Carl Tawn earned 500 total points
ID: 34973718
Try this one:
<script type="text/javascript">
$(document).ready(function() {
	$('#products .specs li').hover(function (e) {
	    var idx = $(this).index();
	    var listIdx = $(this).parent().parent().parent().index();

	    $('#products > li:eq('+listIdx+') 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>

Open in new window

0
 

Author Closing Comment

by:Animaze
ID: 34973835
Thanks so much for your help. Works perfectly.
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 34973851
And I think we both learned something new :)
0
 

Author Comment

by:Animaze
ID: 34973922
Absolutely! Thanks again. I can see using this for all kinds of things actually.
0

Featured Post

Why Off-Site Backups Are The Only Way To Go

You are probably backing up your data—but how and where? Ransomware is on the rise and there are variants that specifically target backups. Read on to discover why off-site is the way to go.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction A frequently asked question goes something like this:  "I am running a long process in the background and I want to alert my client when the process finishes.  How can I send a message to the browser?"  Unfortunately, the short answer…
PROBLEM: The other day I was working on adding an ajax request to a webpage that already had a dialog box on the page.  The dialog box was using relative positioning to be positioned next to a form field I had on the page.  Everything was working…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question