views:

83

answers:

4

I'm looking for a way to fill a <ul> list up to 10 item. If the list doesn't have 10 in the HTML, I want the items to repeat themselves.

For example:

<ul id="carousel">
  <li><a href="#">1</a></li>
  <li><a href="#">2</a></li>
  <li><a href="#">3</a></li>
  <li><a href="#">4</a></li>
</ul>

I tried to do it myself, but it's not exactly working they way I want it to:

  max_slides = 10;

  slides_holder = $('#carousel');
  all_slides = $('#carousel li');
  number_of_slides = all_slides.length;
  number_of_slides_to_add = max_slides - number_of_slides;

  if( number_of_slides < max_slides)
  {
    slides_to_add = $('#carousel li:lt('+number_of_slides_to_add+')').clone();
    slides_holder.append(slides_to_add);
  }

  // $('#carousel').initiateCarousel();

It should become this:

<ul id="carousel">
  <li><a href="#">1</a></li>
  <li><a href="#">2</a></li>
  <li><a href="#">3</a></li>
  <li><a href="#">4</a></li>
  <li><a href="#">1</a></li>
  <li><a href="#">2</a></li>
  <li><a href="#">3</a></li>
  <li><a href="#">4</a></li>
  <li><a href="#">1</a></li>
  <li><a href="#">2</a></li>
</ul>

The items should repeat themselves. It only works when there are 5 items or more... The reason is this: I'm using a special carousel plugin that should always have 10 items at all times. If it doesn't, it starts to act funky.

Thanks for any help.

+3  A: 

Try this:

var li = $('ul#carousel li');
var len = li.size();

// Repeat the list until length is 10
while(len < 10) {
    $('ul#carousel li:last').after(li.clone());
    len += li.size();
}

// Remove extra items after the 10th item
$('#carousel > li').gt(9).remove();

The first segment will ensure that there's at least 10 elements in the UL. The second segment makes sure there are at most 10 elements in the UL so you end up with exactly ten items.

Tatu Ulmanen
I like how you duplicate the entire group rather than trying to clone them one-by-one. Much more efficient, I'd think.
Sandro
Personally not crazy about adding superfluous elements to the dom only to remove them. What if the max is 10, and the initial population is 9? Seems like a little overkill.
patrick dw
@patrick, the alternatives would require quite a lot more code, and the overhead of creating and destroying elements is negligible. What if the max is 10, and the initial population is 15? You'd still need to remove the extra elements.
Tatu Ulmanen
Tatu - Nah, not a lot more code. (see below) Actually it might be a little less. Didn't take the time to count characters. :o) For an image carousel it would seem unlikely that the initial population would exceed the max, because you would have unique content being truncated. But I do understand your point.
patrick dw
That last section of your code can be replaced with this: `$('#carousel > li').gt(9).remove();` That should run much faster.
nickf
@nickf, you're absolutely right, I just couldn't memorize a shorter version. I've updated my post.
Tatu Ulmanen
+2  A: 

Here is my take:

var $container = $('#carousel');
var $original = $container.children('li');
var totalChildren = $original.length;

while (totalChildren < 10) {
  $container.append($original.clone());
  totalChildren = $container.children('li').length;
}

$container.children('li:gt(9)').remove();

Note that :gt is 0 based.

CalebD
A: 

Here's one way.

max = 10;
$car = $('#carousel');
curr = orig = $car.children().length;

while(curr < max) {
    $car.children().eq(curr - orig).clone().appendTo($car);
    curr = $car.children().length;
}

Nothing to clean up at the end. It does a 'look back' during each pass and clones and appends the proper element.

patrick dw
A: 

Your code look good with a single exception the way you add new slides. Instead of adding only once you'll need to loop and keep adding until you have 10 items. Something like:

while( number_of_slides < max_slides)
{
    slides_to_add = $('#carousel li:lt('+number_of_slides_to_add+')').clone();
    slides_holder.append(slides_to_add);
    number_of_slides += number_of_slides_to_add;
    number_of_slides_to_add = max_slides - number_of_slides;
}
Ariel