Hiding list items with a "show more" button
Asked Answered
L

6

5

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";
Lilliamlillian answered 8/6, 2012 at 6:55 Comment(3)
What have you tried? You should show at least your HTML in your question. Also, you can split your large list into multiple <ul>s, each with 10 <li>. This should make it much easier.Holdback
Please Look at this #4054711Mccullough
Felix Christy thanks for your comment. However, doesn't that only show the first 3, then expand to everything?Lilliamlillian
T
32

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>
Transilluminate answered 8/6, 2012 at 7:51 Comment(14)
That looks briliant! Is there any way to remove the "Add More" text if the end of the list has been reached?Lilliamlillian
@Lilliamlillian I updated the link in my answer. Please see if it pleases you.Transilluminate
I can't get it to work, I'm probably doing something wrong. When I click "Show More", nothing happens. Any clue what I might be doing wrong? Website: lolmewn.nl/stats (view source, that would be great)Lilliamlillian
sir try removing the question mark at the end of the code you added.Transilluminate
How did that end up there O.o It seems I can't remove it for some reason, it keeps coming back. It's not in my source code, but it is on the webpage. Weird.. EDIT: Ah, found it. I removed it, but it still doesn't seem to work..Lilliamlillian
now that's creepy. The question mark is the reason for an error, according to the inspector.Transilluminate
I just removed it, but it doesn't seem to work. I'm sorry for bothering you so much with this.. Is there anything else you can think of why it doesn't work.Lilliamlillian
Ok now I think the reason that it is not working is that you have not included the jQuery library, maybe you could link it from google, or upload the js file. The code needs the jQuery library to execute. Sorry for not mentioning, I used jQuery so it will be quick.Transilluminate
+1 for good solution but you should really include some code within your question. If the fiddle ever breaks then your answer isnt much good.Recept
@Recept sorry about that, I was not familiar with the proper ways of suggesting answers back then. Edited with code :)Transilluminate
@Kiiro how can I do this if i'll be using div as the container?Rone
@LuckyAngelo what do you mean? divs instead of lis?Transilluminate
@Kiiro yes indeedRone
@LuckyAngelo then just replace the "li" in the js code and css stylesTransilluminate
Q
3

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;
}
Quaker answered 25/5, 2016 at 15:48 Comment(0)
L
2

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.

Lore answered 8/6, 2012 at 7:14 Comment(1)
This sounds interesting, I will give it a go.Lilliamlillian
Z
1

Have you ever try jquery datatable yet?

Zing answered 8/6, 2012 at 7:8 Comment(2)
First of all, thanks for your answer. I have seen it, and got it recommended too. However, I am completely unfamiliar with JQuery/Javascript. I'll give it another go, but I'm not sure if it'll work this time.Lilliamlillian
@Lolmewn, it's a bit easy. I think you can read the documentation and some customization with too few javascript/jquery code. And you can replace those table data by your php code to retrieve from the database.Zing
W
1

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);
Wrongdoing answered 8/6, 2012 at 7:14 Comment(3)
Hi, thank you for your answer. I have added the code to the webpage, but nothing seems to be changing. It might just be me failing at Javascript, but I'm not sure.Lilliamlillian
I've tested it on Firefox so it should work. Does it throw some error?Wrongdoing
Nope, it just doesn't hide anything. I've added it to the webpage that can be found here: lolmewn.nl/statsLilliamlillian
R
0

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.

Raddy answered 8/6, 2012 at 7:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.