JavaScript: how to give an HTML content to a variable? - javascript

I'm studying JavaScript basics and today I built a simple html page which let the user to add/remove a list item. Well, I think I could be there (I know that there are a lot of better solutions, but hey, I'm just learning).
// the function that adds a list item
function addListItem () {
var newLi = document.createElement("li");
newLi.className = "listItem";
// newLi.innerHTML = "<h3>List item</h3> <p>This is a simple list item</p>";
list.appendChild(newLi);
}
You can see full code here: https://jsfiddle.net/l_wel/cuvc0m5g/
The problem is: how you can see within the first function, I put a commented code. It inserts html content inside the new list item. Is there a better way to do it? I mean, what if i would the new list item to have the number of the list item into the ?
Something like that:
List item 1
List item 2
List item 3
etc.. etc..
I know I should use a counter, but I was not able to let the created list items to have all the original html content from the first list item without the need to rewrite it within the function.
Ok, sorry for my bad english and sorry if you think this is a very simple problem, but I tried for hours. I hope you understood what I'm trying to achieve. I think that without the comment it could work as well, depending on the project.
P.S.
I don't know jQuery yet, I wanted to solve this using vanilla js.

See if this works for you:
// store the list
var list = document.getElementById("list");
var number = 1;
// the function that adds a list item
function addListItem () {
number++;
var newLi = document.createElement("li");
newLi.className = "listItem";
newLi.innerHTML = "<h3>List item</h3> <p>This is a simple list item " + number + "</p>";
list.appendChild(newLi);
}
// the function that removes the last list item
function removeListItem () {
number--;
var ulList = document.querySelectorAll("listItem");
var lastLi = list.lastElementChild;
var containerLi = lastLi.parentNode;
containerLi.removeChild(lastLi);
}
// add a list item
var btnAdd = document.getElementById("btnAdd");
if(btnAdd.addEventListener) {
btnAdd.addEventListener("click", addListItem, false);
} else {
btnAdd.attachEvent("click", addListItem, false);
}
// remove the last list item
var btnRemove = document.getElementById("btnRemove");
if(btnRemove.addEventListener) {
btnRemove.addEventListener("click", removeListItem, false);
} else {
btnAdd.attachEvent("click", removeListItem, false);
}
body {
font-family: monospace;
background: #1e2530;
color: #cce8ff;
}
.top { text-align: center; }
#list {
list-style-type: none;
padding: 0;
margin: 10px;
}
.listItem {
background: #cce8ff;
color: #1e2530;
margin-bottom: 10px;
padding: 5px 0 5px 10px;
border-radius: 5px;
}
<body>
<div class="top">
<h2>challenge #8</h2>
<button id="btnAdd">Add an item list</button>
<button id="btnRemove">Remove an item list</button>
</div>
<ul id="list">
<li class="listItem">
<h3>List item</h3>
<p>This is a simple list item 1</p>
</li>
</ul>
</body>

addListItem is a function which can accept parameters. for example, the forEach command is iterating the array and calling the addListItem for each of the items, forEach is calling the callback with two arguments, the first argument is the item itself, and the second is the index of the item in the array...
then you can use the arguments to display the data...
var items = ['Dog','Cat','Mouse'];
function addListItem( title, index ) {
var newLi = document.createElement("li");
newLi.className = "listItem";
newLi.innerHTML = "<h3>"+title+"</h3> " + index;
list.appendChild(newLi);
}
items.forEach( addListItem );

I know you said you didn't want to use JQuery (http://api.jquery.com/append/), but it does make your life easier. For example, you could use the function below. Writing JavaScript is fun, but reading good open source JavaScript (like reading JQuery source) is a far better learning experience.
you are going to need to create a counter to get the list number:
var lst = $('ul.mylist') //class is my list, if ul.mylist doesn't exist use append to append it to the document
for(let i = 0; i < [number of elements]; i++) {
lst.append('<li>List Item' + i + '</li>);
}

Related

Adding onClick event in a for loop

I am a beginner in Javascript. What I am trying to do is when a user clicks on "Click to start loop", the first <li> will be 1. The second time the user clicks it, it will be 2, and the third time, it will be 3. After the third click, the loop will break.
The issue with my code is that it always displays the number 3 instead of starting from 1 and going all the way to 3.
function myFunction() {
demo = document.getElementById("demo")
ul = document.createElement("ul")
demo.appendChild(ul)
li = document.createElement("li")
ul.appendChild(li)
for (let i = 1; i <= 3; i++){
li.innerText = i
}
}
<p id="demo" onclick="myFunction()">Click to start loop</p>
It is because, there is only one 'li' element created before loop starts and at the end of loop, it is just updating the final innterText.
You can fix it by moving li creation code to loop
function myFunction() {
demo = document.getElementById("demo")
ul = document.createElement("ul")
demo.appendChild(ul)
<--- from here
for (let i = 1; i <= 3; i++){
li = document.createElement("li") <--- to here
ul.appendChild(li)
li.innerText = i
}
}
You just have to save the current loop value in some place:
let i = 1;
function myFunction() {
// Check for i value
if (i === 4) return;
demo = document.getElementById("demo")
ul = document.createElement("ul")
demo.appendChild(ul)
li = document.createElement("li")
ul.appendChild(li)
// Update the i value
li.innerText = i++;
}
<p id="demo" onclick="myFunction()">Click to start loop</p>
One solution could be to create a global variable with initial value set to 1 and increase it every time there is a click on your <p> tag.
I have implemented the same using the global variable counter.
<p id="demo" onclick="myFunction()">Click to start loop</p>
<script>
var counter = 1;
function myFunction() {
if(counter === 4){
return;
}
demo = document.getElementById("demo");
ul = document.createElement("ul");
demo.appendChild(ul);
li = document.createElement("li");
ul.appendChild(li);
li.innerText = counter;
counter++;
}
</script>
I think you should put li = document.createElement("li") inside of the loops
index.js
function myFunction(status) {
demo = document.getElementById("demo")
ul = document.createElement("ul")
demo.appendChild(ul)
for (let i=1; i<=3; i++) {
li = document.createElement("li")
li.innerText = i
ul.appendChild(li)
}
}
This is unclear, are you looking for javascript function generator ?
const
ul_List = document.body.appendChild( document.createElement('ul') )
, generator = (function* ()
{
for (let i = 0; (++i < 4);)
{
ul_List.appendChild( document.createElement('li') ).textContent = i
yield
}
})()
<p id="demo" onclick="generator.next()" >Click to 3 times loop</p>
Counters
A function that deals with an incrementing variable (aka counter) usually declares or defines it as a number outside of a loop then iterates the variable with a ++ or += operator within the loop. But would a loop within an event handler that increments a number by +1 per click make much sense? So forget about iterations based on a single run of a function/event handler.
The next problem is that once the function/event handler is done, the counter is garbage collected (deleted from memory), so on the next click it is back to what it was initially (usually 0) -- so you need the user to click a HTML element, increase a number by one, and increase it by one per click thereafter. There a few ways to keep the counter's last value:
HTML/DOM
Store the last value in a HTML form control by [value]
let counter = 0;
counter++;
document.forms[0].count.value = counter;
....
<input id='count' type='hidden' value='0'><!--value will be '1'-->
Store the last value in any other type of HTML element by [data-*]
or text content
document.querySelector('.count').dataset.idx = counter;
....
<nav class='count' data-idx='1'></nav>
document.querySelector('aside').textContent = counter;
....
<aside>2</aside>
Keep in mind any value stored in HTML is converted into a string so when getting the variable counter value you must convert it back into a real number:
parseInt(document.forms[0].count.value);
parseFloat(document.querySelector('.count').dataset.idx);
Number(document.querySelector('aside').textContent);
Closures
A better way IMO is to deal with variable scope. If you noticed in the previous code, let and const are used instead of var. The reason for this is scope.
Function Scope: If var was used, then all variables would be influenced by anything inside or the immediate outside of the function it is in. If completely outside of all functions then it is global (much more susceptible to side effects and buggy behavior).
Block Scope: let and const scope is block which means they can only be accessed within the brackets they are located in:
var G = `any function, method, expression, etc can affect it or be affected
by it`;
function clickHandler(e) {
var L = `vulnerable to anything within the function and immediately
outside the function`;
if (e.target.matches('button')) {
let A,
const B = `only affects or get affected only by things within the
brackets`;
var C = `even buried deep within a function it will be hoisted to be
accessible to everything within this function`;
}
function addItem(node, count) {
/* Although a function defined within another function it cannot access
A or B*/
}
}
Wrapping a function/event handler in another function in order to provide an isolated scope and an environment wherein variables can exist past runtime and avoid garbage collection is a closure. The following examples are closures #1 is simple and #2 is more refined (user can edit each list item directly). Go here for details on scope and closures.
Example 1
function init() {
const ul = document.querySelector('ul');
let i = 0;
function clickHandler(e) {
i++;
addItem(this, i);
}
ul.onclick = clickHandler;
};
function addItem(list, counter) {
const li = document.createElement('li');
list.append(li);
li.textContent = counter;
};
init();
<ul>Click to Add Item</ul>
Example 2
function init() {
const ui = document.forms[0];
let counter = 1;
function addItem(event) {
const clicked = event.target;
if (clicked.matches('legend')) {
const list = clicked.nextElementSibling;
let marker = `${counter++}`.padStart(2, '0');
list.insertAdjacentHTML('beforeEnd', `<li contenteditable data-idx="${marker}"></li>`);
}
}
ui.onclick = addItem;
};
init();
form {
font: 1.5ch/1 Consolas;
}
legend {
font-size: large;
font-weight: bold;
user-select: none;
cursor: pointer;
}
legend::after {
content: 'Click to Add Item';
font-size: small;
}
ul {
list-style: none;
}
li {
margin: 5px 11px 5px 9px;
padding: 4px 8px;
border-bottom: 1px solid #980;
}
li::marker {
display: list-item;
content: attr(data-idx)'.';
margin-bottom: -2px;
}
<form>
<fieldset>
<legend>List<br></legend>
<ul></ul>
</fieldset>
</form>

How to remove <li> list items and make the remaining ones change their position and id?

Tricky question and far too advanced for my level (js student).
Lets say I use the append method to generate <li> items inside an <ol>, and I need each one of those li items to have a unique id, so I thought to get the amount of <li> (length) items I generated by saying this : var index = document.getElementById("ol1").getElementsByTagName("li").length+1; and use this number to create unique id's for every item I generate by doing this: li.id="li"+index; so the first one I generate becomes #li1 (since the amount of li items is one), the next one #li2 and so on. *btw, is it the right approach to do this?
Now lets say I want to remove #li1, then #li2 would replace it in position 1 of the list, but its id will still be #li2 since it has gotten it already.
For example what I ultimately want is when I remove #li1, then #li2 becomes #li1, #li3 becomes #li2, #li4 becomes #li3.....and so on.
What would be the right logic approach to do such a gimmick?
function append() {
var index = document.getElementById("ol1").getElementsByTagName("li").length + 1;
var ol = document.getElementById("ol1");
var li = document.createElement("li");
li.id = "li" + index;
li.innerHTML = (`LIST ITEM <input value=this is id: #li${index}><button class=remove id= button${index} onclick=remove${index}()>REMOVE</button>`);
ol.append(li)
}
function remove1() {
var rem = document.getElementById("li1");
rem.remove();
}
function displayIndex() {
var index = document.getElementById("ol1").getElementsByTagName("li").length;
alert(index);
}
#li1 {
color: red;
}
#li2 {
color: green;
}
#li3 {
color: blue;
}
ol button {
color: red;
visibility: hidden;
}
#button1 {
color: red;
visibility: visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
<button id="btn1" onclick="append()">Append</button>
<button id="btn2" onclick="displayIndex()">Index</button>
</head>
<body>
<ol id="ol1">
</ol>
</body>
</html>
First off:
There are no "right" approaches. Only working implementations. How it is achieved might differ from developer to developer, and as long as it works, it should be considered the "right" way (however, not necessarily the most efficient or optimized or any other way).
One way would be to use a remove() function that re-assigns the ID's of the remaining <li>s (after the removal, obviously) as a side-effect.
function removeItemOf(list, listItem) {
if (!list.contains(listItem)) return;
listItem.remove();
indexItemsOf(list);
// For displaying the removed ID on-screen
document.querySelector('div').append(
document.createElement('br'),
document.createTextNode(`Removed <li> with id '${listItem.id}'`)
);
}
function indexItemsOf(list) {
for (var i = 0; list.children[i]; ++i) {
list.children[i].id = (list.id || list.tagName) + '-li' + i;
// For displaying the <li>'s ID on-screen
list.children[i].textContent = `With ID '${list.children[i].id}'`;
}
}
var list = document.querySelector('ol');
indexItemsOf(list);
setTimeout(() => {
removeItemOf(list, list.children[0]);
}, 2000);
setTimeout(() => {
removeItemOf(list, list.children[1]);
}, 4000);
<ol>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
<div></div>
However, re-assigning a previously used ID makes it not unique to one element, as it now identifies another element it hasn't identified before. For environments where this would be important (e.g. relying on an element to reference certain other elements, or to have a certain event-listener, etc.), re-using an ID would break the environment.
To circumvent this problem, one could keep track of how many unique items a list had over its entire lifetime, and create the next item with an ID using that amount, and then increase the amount by one.
Here is an example:
var list = document.querySelector('ol');
list.uniqueItems = 0;
// Here: Using Event-Delegation for removing a <li>
list.addEventListener('click', function(evt) {
if (evt.target.classList.contains('btn-delete'))
evt.target.closest('li').remove();
});
document.querySelector('button').addEventListener('click', function() {
var item = document.createElement('li');
item.id = 'li-' + list.uniqueItems;
item.textContent = `Has the ID '${item.id}' `;
var btnDelete = document.createElement('button');
btnDelete.classList.add('btn-delete');
btnDelete.textContent = 'Delete Item';
item.append(btnDelete);
list.append(item);
list.uniqueItems++;
});
<button>New Item</button>
<ol></ol>
You can just loop through each list item after your remove one and regenerate the IDs for each.
ol = document.getElementById("ol1");
function indexLIs(){
i = 1;
ol.querySelectorAll("li").forEach(function(li){
id = "li" + i;
li.setAttribute("id",id);
li.querySelector("input").value = "this is id: #" + id;
i++;
});
}
function append() {
var index = document.getElementById("ol1").getElementsByTagName("li").length + 1;
var li = document.createElement("li");
li.id = "li" + index;
li.innerHTML = (`LIST ITEM <input value=this is id: #li${index}><button class=remove id= button${index} onclick=remove${index}()>REMOVE</button>`);
ol.append(li)
}
function remove1() {
var rem = document.getElementById("li1");
rem.remove();
indexLIs();
}
function displayIndex() {
var index = document.getElementById("ol1").getElementsByTagName("li").length;
alert(index);
}
#ol1 li:nth-child(1) {
color: red;
}
#ol1 li:nth-child(2) {
color: green;
}
#ol1 li:nth-child(3) {
color: blue;
}
ol button {
color: red;
visibility: hidden;
}
#button1 {
color: red;
visibility: visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
<button id="btn1" onclick="append()">Append</button>
<button id="btn2" onclick="displayIndex()">Index</button>
</head>
<body>
<ol id="ol1">
</ol>
</body>
</html>
Your approach is fine. It would be easier for you to keep counting from the last element without changing the other elements even if you remove an element. In that situation use a global variable and initialize it with the length of your initial list. Something like that should do the work:
var index = 1; // or the index you wish to start from
function append(){
var ol = document.getElementById("ol1");
var li = document.createElement("li");
li.id="li"+index;
li.innerHTML = (`LIST ITEM <input value=this is id: #li${index}><button class=remove id= button${index} onclick=remove${index}()>REMOVE</button>`);
ol.append(li);
// now we will increment our index for the next iteration
index++;
}
Hope this was useful.

How to loop through anchor tags within div tags which have the same class name

My header on my website has 5 tabs (they are div tags all named "dropdown". Under each tab are clickable links (the anchor tags). I am trying to write some code that will print text in the console when a link is click and tell the user about where it was clicked (it uses the innerText). For instance, if a user clicks a link under the first tab, it will log "column 1| Link1" or if a user clicks on a link in the second tab "column 2| link 3". All I have is the nested for loop that will loop through the anchor tags under each div tag but I am not sure if its correct. This is what I have:
var dropdownDivs = document.getElementsByClassName('dropdown');
for(i = 0; i < dropdownDivs.length;i++) {
var lnks =
document.getElementsByClassName('dropdown').getElementsByTagName('a');
for(i = 0; i < dropdownDivs.length;i++){
for (var l in lnks) {
}};
In order to get the placement index of the DIV and the Link(anchor tag) on the page you're going to need to collect at least one of them into an array to grab their index using the indexOf method.
You can use querySelectorAll to more easily grab the elements needed to do the work.
Note: querySelectorAll returns an HTMLCollection, not an Array. They both have a forEach method so I just wanted to point this out.
// get all anchor elements within an element with the class dropdown
let collection = document.querySelectorAll(".dropdown a");
// iterate over links in elements with dropdown class
// parameters for forEach are (element, index)
collection.forEach((ele, ind) => {
// we get the parent node(the element with the dropdown class)
// then we figure out what number element(div) we're on by looking at the array
// of all elements with the dropdown class
let p = ele.parentNode;
let p_ind = Array.from(document.querySelectorAll('.dropdown')).indexOf(p);
//we add 1 to the indices because there is a 0 index and we
//would like to start at the first DIV/Link being a 1, not 0
ind++;
p_ind++;
//add an event listener to the links that alerts the results
//on click
ele.addEventListener('click', () => alert("link " + ind + " in div" + p_ind))
})
let collection = document.querySelectorAll(".dropdown a");
collection.forEach((ele, ind) => {
let p = ele.parentNode;
let p_ind = Array.from(document.querySelectorAll('.dropdown')).indexOf(p);
ind++;
p_ind++;
ele.addEventListener('click', () => alert("link " + ind + " in div" + p_ind))
})
div {
border: 1px solid black;
width: 75px;
margin: 10px;
padding: 10px;
}
<div class="dropdown">
hi
bye
</div>
<div class="dropdown">
hi
bye
</div>
<div class="dropdown">
hi
bye
</div>
<div class="dropdown">
hi
bye
</div>
<div class="dropdown">
hi
bye
</div>
From looking at your code, I'd suggest changing
document.getElementsByClassName('dropdown').getElementsByTag‌​Name('a')
with
dropdownDivs[i].getElementsByTagName('a')
I say this because document.getElementsByClassName('dropdown') will return an array again (an array you've already got by the way) rather than the element in question, which would be represented by
dropdownDivs[i]

adding and removing elements of an array from unordered list or ordered list

I have this unordered list with random elements:
<ul id="uList">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
<p>You have selected: </p><p id="result"></p>
I added an Event Listener on all of the elements of unordered list.
var elems = document.getElementsByTagName('li');
var selected;
var arr1 = [];
Array.from(elems).forEach(v => v.addEventListener("click", onClickItems,false));
I created a function that toggle when I click on unordered list elements,so i can add and remove the element into/from array.
function onClickItems() {
this.classList.toggle('selected');
if (this.classList.contains('selected')){
selected = this.innerHTML;
arr1.push(selected);
document.getElementById("result").innerHTML = arr1.join("<br>");
} else {
lookValueArray(returenIndex());
document.getElementById("result").innerHTML = arr1.join("<br>");
}
}
the adding part works perfect but when the user selected the same elements from the unordered list to remove it, it won't work. it only removes the last element has been add to the array.
so, I created these two function:
First one, to store the index of the selected element when it enters the array.
function returenIndex () {
var indexx = arr1.indexOf(selected);
return(indexx);
}
second one, to look for the value of the selected index from unordered list and remove it if it is equal to the selected one.
function lookValueArray (inde1) {
if (arr1[inde1].value = selected) {
arr1.splice(inde1, 1);
}
}
still the same output. it adds perfectly but it wont remove it.Moreover, it will only remove the last element was entered into the array even if I selected the second one to be removed.
BTW, I tried to use arr1.splice(0, 0, selected) instead of arr1.push(selected) ,so I can have the element entered the array in specific position but that wont work too.
In your code your selected variable is undefined when you first click one of your elements. You need to add a value to selected when you first click one of the elements so you just need to move selected = this.innerHTML; outside the if statement. You also do not need the if statement inside the lookValueArray() function, which already is wrong because you're doing an asignment instead of verifying using(== or ===). See the working snippet below please:
var elems = document.getElementsByTagName('li');
var selected;
var arr1 = [];
Array.from(elems).forEach(v => v.addEventListener("click", onClickItems, false));
function onClickItems() {
selected = this.innerHTML;
this.classList.toggle('selected');
if (this.classList.contains('selected')) {
//selected = this.innerHTML; //commented this line and added it above, outside the if statement
arr1.push(selected);
document.getElementById("result").innerHTML = arr1.join("<br>");
} else {
lookValueArray(returenIndex());
document.getElementById("result").innerHTML = arr1.join("<br>");
}
}
function lookValueArray(inde1) {
arr1.splice(inde1, 1);
}
function returenIndex() {
var indexx = arr1.indexOf(selected);
return (indexx);
}
.selected {
color: #f00;
}
<ul id="uList">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
<p>You have selected: </p>
<p id="result"></p>

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";
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>
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.
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;
}
Have you ever try jquery datatable yet?
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);
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.

Categories

Resources