YannickHelmut
YannickHelmut

Reputation: 555

Count number of list elements and create "more" dropdown

I'm trying to create a menu which counts the number of <li> and if there are more than 5 of them in the list, move the rest into a dropdown list.

Basically the code would look like this:

<ul class="menu">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
  <li id="more"> 
    <a href="#">More</a>
    <ul>
      <li>Move 6 here</li>
      <li>Move 7 here</li>
      <li>Move 8 here</li>
      <li>Move 9 here</li>
    </ul>
  </li>
</ul>

Counting the number of elements can be achieved with $("#menu").children().length - but what should I do now ?

Upvotes: 1

Views: 904

Answers (4)

user4639281
user4639281

Reputation:

Create a new list item containing a ul tag. Use the :gt(n) selector to get any elements greater than n. Append those items to the created element's ul, then append the created element to the original list.

(Demo)

$('.menu:has(li:gt(5))').each(function () {
    var more = $('<li><a href="#">More</a><ul></ul></li>');
    $('ul', more).append($(this).find('li:gt(4)'));
    $(this).append(more);
});

Upvotes: 0

AmmarCSE
AmmarCSE

Reputation: 30557

$('.menu:has(li:gt(4))').each(function() {
  $(this).append('<li id="more"></li>');
  $(this).find('#more').append('<a href="#">More</a>');
  $(this).find('#more').append('<ul></ul>');
  var lis = $(this).find('li:gt(4)').not('#more');
  $(this).find('#more').find('ul').append(lis);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="menu">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>

</ul>

Upvotes: 2

Tushar
Tushar

Reputation: 87203

To get the count of direct descendants lis inside .menu:

$('.menu > li').length

To move lis in more:

$('.menu li:gt(4):not(#more)').appendTo('#more ul'); // If `#more` already exists

Demo: https://jsfiddle.net/tusharj/77120z44/1/

EDIT

If #more don't exists:

$('.menu').append('<li id="more"><ul></ul></li>');
$('.menu li:gt(4):not(#more)').appendTo('#more ul');

Demo: https://jsfiddle.net/tusharj/77120z44/4/

Upvotes: 0

Arun P Johny
Arun P Johny

Reputation: 388316

You can use the children length to determine whether to move them, if so then create a new li and ul structure as required as given below

var $menu = $('.menu');
if ($menu.children().length > 5) {
  //create a new ul and all lis after the 5th one to that
  var $ul = $('<ul />').append($menu.children().slice(5)).hide();
  //create a new anchor element with a click handler that will toggle the more div
  var $a = $('<a />', {
    href: '#',
    text: 'More'
  }).click(function() {
    $(this).text(function(i, text) {
      return text == 'More' ? 'Less' : 'More';
    }).next().toggle();
  });
  //create a new li element and add the anchor and ul to it and append the li to the parent ul
  $('<li />', {
    id: 'more'
  }).append($a).append($ul).appendTo($menu);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="menu">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
</ul>

Upvotes: 1

Related Questions