Lolmewn
Lolmewn

Reputation: 1521

Hiding list items with a "show more" button

I have an issue. I am getting data from a MySQL database, and make a list of it. That's all good, and works fine, but the list is now over 100 items long if I don't limit it. I've tried Googling how to shorten list, and found some things with jQuery and JavaScript, but that didn't work too well.

What I'm looking for is a way to make the list limit itself on 10 items, with a [More] button under it. When pressed, the next 10 items show, and when pressed again, 10 more etc.

I have my list in normal <li> and <ul> bits. If there's any more information needed, please ask me. This is the webpage it's about: http://lolmewn.nl/stats/

A bit of my PHP code:

echo "<li><a href=\"?player=" . $row['player'] . "\">" . $row['player'] . 
     "</a></li>\n";

Upvotes: 5

Views: 43774

Answers (6)

omni
omni

Reputation: 4495

If you want this is pure javascript I made a example on jsfiddle

Javascript

function showMore() {

    var listData = Array.prototype.slice.call(document.querySelectorAll('#dataList li:not(.shown)')).slice(0, 3);

  for (var i=0; i < listData.length; i++)
  {
    listData[i].className  = 'shown';
  }
  switchButtons();
}

function showLess() {
    var listData = Array.prototype.slice.call(document.querySelectorAll('#dataList li:not(.hidden)')).slice(-3);
  for (var i=0; i < listData.length; i++)
  {
    listData[i].className  = 'hidden';
  }
  switchButtons();
}

function switchButtons() {
    var hiddenElements = Array.prototype.slice.call(document.querySelectorAll('#dataList li:not(.shown)'));
  if(hiddenElements.length == 0)
  {
    document.getElementById('moreButton').style.display = 'none';
  }
  else
  {
    document.getElementById('moreButton').style.display = 'block';
  }

  var shownElements = Array.prototype.slice.call(document.querySelectorAll('#dataList li:not(.hidden)'));
  if(shownElements.length == 0)
  {
    document.getElementById('lessButton').style.display = 'none';
  }
  else
  {
    document.getElementById('lessButton').style.display = 'block';
  }
}

onload= function(){
    showMore();
}

HTML

<ul id="dataList">
    <li class="hidden">One</li>
    <li class="hidden">Two</li>
    <li class="hidden">Three</li>
    <li class="hidden">Four</li>
    <li class="hidden">Five</li>
    <li class="hidden">Six</li>
    <li class="hidden">Seven</li>
    <li class="hidden">Eight</li>
    <li class="hidden">Nine</li>
    <li class="hidden">Ten</li>
    <li class="hidden">Eleven</li>
</ul>
<input id="moreButton" type="button" value="More" onclick="showMore()"/>
<input id="lessButton" type="button" value="Less" onclick="showLess()"/>

CSS

.shown{
  display:block;
}
.hidden{
  display:none;
}

Upvotes: 3

KiiroSora09
KiiroSora09

Reputation: 2287

Maybe you can try this. In this example I used 2 items instead of 10. I used css to hide all li elements starting from the 3rd li element inside the ul. I used jQuery to reveal additional 2 lis every time show more is clicked.

Hope this helps

Updated Link Again...

EDIT

$(function () {
    $('span').click(function () {
        $('#datalist li:hidden').slice(0, 2).show();
        if ($('#datalist li').length == $('#datalist li:visible').length) {
            $('span ').hide();
        }
    });
});
ul li:nth-child(n+3) {
    display:none;
}
ul li {
    border: 1px solid #aaa;
}
span {
    cursor: pointer;
    color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<ul id="datalist">
  <li>dataset1</li>
  <li>dataset1</li>
  <li>dataset2</li>
  <li>dataset2</li>
  <li>dataset3</li>
  <li>dataset3</li>
  <li>dataset4</li>
  <li>dataset4</li>
  <li>dataset5</li>
  <li>dataset5</li>
</ul>
<span>readmore</span>

Upvotes: 32

Scott Stevens
Scott Stevens

Reputation: 2651

If you want to limit the number of results from the database, add LIMIT 10 (or any number) to the MySQL query.

If you want to actually hide the lists, but leave them available, you will need CSS to initially hide them, and Javascript/Jquery to unhide them. (CSS3 might let you unhide them without Javascript/Jquery, but it isn't fully supported everywhere yet).

Assuming all the list items have the same CSS class then a javascript loop like the following may work:

function unhide(number) {
    var items = document.getElementsByClassName('tagnamehere');
    var shown=0;
    for (var i=0; shown<number && i<items.length; i++) {
        if (items[i].style.display=="" || items[i].style.display=="none") {
            items[i].style.display="list-item";
    shown+=1;
        }
    }
}

In the CSS, all you need to add is .tagnamehere {display:none;}

Feel free to substitute with your own tags.

Upvotes: 0

gopi1410
gopi1410

Reputation: 6625

One method is to use ajax to load the list items & restrict them to 10 items using mysql limit.

Otherwise, if you load all at once, you can do the following: (write the code yourself)

  • Load all of them in a ul and make the display of all none.

  • Then using jquery eq selector display the first 10 li elements.

  • on clicking more, just toggle those li which you want to display.

Upvotes: 2

mck89
mck89

Reputation: 19241

Simple solution in pure javascript:

var ul = document.getElementsByTagName("ul")[0], //Your <ul>
    readmore = document.createElement("li"),
    lisColl = ul.getElementsByTagName("li"),
    len = lisColl.length,
    lis = [],
    pos = 0;
readmore.textContent = "Read more";
for (var i = 0; i < len; i++) {
    lisColl[i].style.display = "none";
    lis.push(lisColl[i]);
}
readmore.onclick = function () {
    if (this.parentNode) {
        this.parentNode.removeChild(this);
    }
    for (var c = 0; pos < len; pos++) {
        if ((c++) === 10) {
            ul.insertBefore(this, lis[pos + 1]);
            break;
        }
        lis[pos].style.display = "";
    }
}
readmore.onclick.call(readmore);

Upvotes: 1

Tepken Vannkorn
Tepken Vannkorn

Reputation: 9713

Have you ever try jquery datatable yet?

Upvotes: 1

Related Questions