Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Using the :nth-of-type() Selector in jQuery where value of n varies

I've a series of 60 list items in the HTML, and I only want to show 10 at a time.

Before the javascript below runs all of the list items are hidden using jQuery.

The following code then dictates which list items to display, depending on an index value which is determined by another function.

if (index=='0') {
          $( "ul.student-list" ).children('li:nth-of-type(n+0):nth-of-type(-n+10)').show();
      } else if (index=='1') {
          $( "ul.student-list" ).children('li:nth-of-type(n+11):nth-of-type(-n+20)').show();
      } else if (index=='2') {
              $( "ul.student-list" ).children('li:nth-of-type(n+21):nth-of-type(-n+30)').show();
      } else if (index=='3') {
          $( "ul.student-list" ).children('li:nth-of-type(n+31):nth-of-type(-n+40)').show();
      } else if (index=='4') {
          $( "ul.student-list" ).children('li:nth-of-type(n+41):nth-of-type(-n+50)').show();
      } else if (index=='5') {
          $( "ul.student-list" ).children('li:nth-of-type(n+51):nth-of-type(-n+60)').show();
      }

The code works fine, doing what I want it to, but it feels like the above if else conditional is ripe for shortening. I came up with some formulas to calculate the positions n should start and end at, but I can't seem to find anyway to get the :nth-of-type() Selector to take these.

The formula for the first n value would be: =((index+1)*studentsPerPage)-(studentsPerPage-1)

The formula for the second n value would be: =(index+1)*studentsPerPage

In both case above studentsPerPage is 10. 'Index' is a global variable in the script and varies depending on a previous function.

I've tried placing the formulas directly into the :nth-of-type() Selector, and I've tried calculating the values of the first and second Ns, storing these are variables and passing the variables to the :nth-of-type() Selector. Neither works.

Any thoughts on how this could be done? If at all?

1 Answer

Hi Chris,

Did you try to do string concatenation when you added the variables in? That should be what you need here.

Since you have (index+1)*studentsPerPage appearing in both formulas, I would calculate the upper limit first and then use that to calculate the lower limit to avoid that repetition.

var upper = (index+1)*studentsPerPage;
var lower = upper - studentsPerPage + 1;

Then you could use string concatenation to create a string with those 2 variables in it.

'li:nth-of-type(n+' + lower + '):nth-of-type(-n+' + upper + ')'

This can get confusing, You have to be careful here where you put the quotes and plus signs because you have + for the nth-expressions and + for the string concatenation.

Another approach that you could take is to use the slice() method. https://api.jquery.com/slice/

You would be able to avoid that long selector. I would save all 60 list items in a variable so that you are not continually retrieving them and then each time a particular page is needed, you get a slice of those 60 items.

var $students = $('.student-list li'); // put this where you are initializing other variables so that it only runs once.

var upper = (index+1)*studentsPerPage;
var lower = upper - studentsPerPage + 1;

$students.slice(lower - 1, upper).show();

Indexing is zero-based so you have to start at lower - 1 and go up to but not including the upper value.

In terms of efficiency, I'm not sure which one is better but the slice method is certainly cleaner code.

Good advice - I had not tried string concatenation, very helpful! Thank you. I've now shortened the code down with the first option and it works how I had hoped.