How can I encode a check to see if the element is the first or last of the parent?

I have the following menu, which can contain up to 50 elements and two links that the user can use to go to the previous or next city. Here for this example, I just show four address links.

<ul id="menu"> <li><a href="/City/0101004H">1</a></li> <li><a href="/City/0101004I">2</a></li> <li><a href="/City/0101004J">3</a></li> <li><a href="/City/0101004K">4</a></li> </ul> <a id="prev" href="#"><img width="16" height="16" src="/images/prev.png">Prev</a> <a id="next" href="#"><img width="16" height="16" src="/images/next.png">Next</a> 

I had some help with stack overflow and the following code appeared:

fiddle

 $("#menu").on('click', 'a[href^="/City"]', function(event) { event.preventDefault(); var prev = $(this).parent().prev().find('a'); var next = $(this).parent().next().find('a'); $('#prev').prop('href', jQuery(prev).prop('href')).prop('title', 'City ' + jQuery(prev).text()); $('#next').prop('href', jQuery(next).prop('href')).prop('title', 'City ' + jQuery(next).text()) }); 

This sets the href value of the previous and next value when I click one of the menu items. It works, but not for the first and last items in the list. I need the following:

a) When the first element is clicked, I would like #prev to change to:

 <a id="prev" href="#"><img src="/images/noentry.png"></a> 

b) When clicking the last item, I would like #next to change to:

 <a id="next" href="#"><img src="/images/noentry.png"></a> 

Is there an easy way to do this without adding extra code?

+7
source share
4 answers

You can check the length of the jQuery object for zero and act accordingly:

 $("#menu").on('click', 'a[href^="/City"]', function(event) { event.preventDefault(); var pHref, nHref, pTitle, nTitle; var prev = $(this).parent().prev().find('a'); var next = $(this).parent().next().find('a'); if (prev.length == 0) { pHref = "#"; pTitle = ""; } else { pHref = prev.prop('href'); pTitle = prev.prop('City' prev.text()); } if (next.length == 0) { nHref = "#"; nTitle = ""; } else { nHref = next.prop('href'); nTitle = next.prop('City' prev.text()); } $('#prev').prop('href', pHref).prop('title', pTitle); $('#next').prop('href', nHref).prop('title', nTitle) }); 

or a little cleaner with a local function to do the job:

 ("#menu").on('click', 'a[href^="/City"]', function(event) { function setProps(targetSelector, srcObject) { var href, title; if (srcObject.length) { href = srcObject.prop('href'); title = srcObject.prop('title'); } else { href = "#"; title = ""; } $(targetSelector).prop('href', href).prop('title', title); } event.preventDefault(); var p = $(this).parent(); setProps('#prev', p.prev().find('a')); setProps('#next', p.next().find('a')); }); 
+1
source

You can check if the element is the first child or the last child using the following:

 $(this).parent().is(":first-child"); $(this).parent().is(":last-child"); 

If this refers to pressing a , we will check if it was the first link or the last link in the list, checking whether its parent was the first child or last child, or neither.

In addition, you can use the attribute-object-construct for the following values:

 $("#menu").on('click', 'a', function(event) { // Prevent link from taking us anywhere event.preventDefault(); // We'll be referencing the parent numerous times var parent = $(this).parent(); // Determine the new properties of the PREV link var prev = parent.is(":first-child") ? { html: '<img src="/images/noentry.png" />', title: null } : { html: '<img src="/images/prev.png" /> Prev', title: 'City ' + parent.prev().text() } ; // Determine the new properties of the NEXT link var next = parent.is(":last-child") ? { html: '<img src="/images/noentry.png" />', title: null } : { html: '<img src="/images/next.png" /> Next', title: 'City ' + parent.next().text() } ; // Set new attribtes of both PREV and NEXT $("#prev").attr( prev ); $("#next").attr( next ); });​ 

You could optionally build attributes for the #prev and #next for your needs.

Demo: http://jsfiddle.net/MX94J/1/

+10
source

If the elt element is the first of its siblings, $(elt).prev().length will be 0 .
If the elt element is the last of its siblings, $(elt).next().length will be 0 .

+1
source

An alternative way to do this is to use an index or properties instead:

http://jsfiddle.net/QrE6u/1/

 var index = 0; var nElements = $('#menu a').length; $('#menu a').click(function(e) { e.preventDefault(); index = $(this).parents('ul').find('a').index(this); if (index==0) { $('#prev img').attr('src', '/images/noentry.png'); } if (index==nElements-1) { $('#next img').attr('src', '/images/noentry.png'); } alert(index); }); $('#prev').click(function() { index = (index - 1) % nElements; $('#menu a').eq(index).click(); }); $('#next').click(function() { index = (index + 1)% nElements; $('#menu a').eq(index).click(); });​ 
+1
source

All Articles