I'm making a non responsive site responsive. For the mobile view I'm trying to show 3 li elements on landing, click "show more" another 3 load and so forth. Hit show less and 3 li items should be removed.
I'm working on a project with a lot more li items but was wondering if the issue I am experiencing is a scope problem? And if there is a way to fix it.
The project I'm working on features a scrollable div displaying the li items in one div and hiding the rest until the user clicks an arrow. (this is why I havent rewritten the code from my predecessor original site is here to illustrate what I mean http://www.asla.org/sustainablelandscapes/index.html)
Is there a solution here?
I have recreated my issue (simplified) in a fiddle
http://jsfiddle.net/gward90/xgmdkpb8/
EDIT: To further clarify, as seen with the fiddle all the li elements show on landing this should not be the case. Show less removes more than 3 items as well.
<div class="row">
<div class="col-md-12">
<ul class="thumbnails">
<li><div class="red"></div></li>
<li><div class="red"></div></li>
<li><div class="red"></div></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-12">
<ul class="thumbnails">
<li><div class="blue"></div></li>
<li><div class="blue"></div></li>
<li><div class="blue"></div></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-12">
<ul class="thumbnails">
<li><div class="green"></div></li>
<li><div class="green"></div></li>
<li><div class="green"></div></li>
</ul>
</div>
</div>
<div id="loadMore">Load more</div>
<div id="showLess">Show less</div>
$(document).ready(function () {
$('.thumbnails li:lt(3)').show();
$('#showLess').hide();
var items = 9;
var shown = 3;
$('#loadMore').click(function () {
$('#showLess').show();
shown = $('.thumbnails li:visible').size()+3;
if(shown< items) {$('.thumbnails li:lt('+shown+')').show();}
else {$('.thumbnails li:lt('+items+')').show();
$('#loadMore').hide();
}
});
$('#showLess').click(function () {
$('.thumbnails li').not(':lt(3)').hide();
});
});
Not sure if this is what you are aiming for, but this does something at least:
var totalCount; //Keeps track of the total number of li's, shown or hidden.
var currentCount; //Keeps track of the number of li's currently shown.
$(document).ready(function () {
//Count how many li's there are in total.
totalCount = $('.thumbnails li').size();
//Start by showing three of them.
currentCount = 3;
adjustLiShown();
$('#loadMore').click(function () {
//Increase by three and update.
currentCount += 3;
adjustLiShown()
});
$('#showLess').click(function () {
//Decrease by three and update.
currentCount -= 3;
adjustLiShown()
});
});
function adjustLiShown() {
//Hide all and then show the one with index under total count.
$('.thumbnails li').hide().filter(':lt(' + currentCount + ')').show();
//Only show "load more" if we haven't reached the total yet.
$('#loadMore').toggle(currentCount < totalCount);
//Only show "show less" if we are above the starting number.
$('#showLess').toggle(currentCount > 3);
}
Fiddle.
Try utilizing .slice()
$(document).ready(function () {
$('.thumbnails li:lt(3)').show();
// hide `.thumbnails` greater than 3
$('.thumbnails li:gt(2)').hide();
$('#showLess').hide();
var items = 9;
var shown = 3;
$('#loadMore').click(function (e) {
$('#showLess').show();
$(".thumbnails li:not(:visible)").slice(0, 3)
.show(function() {
if ($(".thumbnails li:visible").length === items) {
$(e.target).hide()
}
})
});
$('#showLess').click(function (e) {
$('.thumbnails li:visible').slice(-3).hide(function() {
if ($(".thumbnails li:visible").length === 0) {
$(e.target).hide()
};
if ($('.thumbnails li:visible').length < items) {
$("#loadMore").show()
}
});
});
});
jsfiddle http://jsfiddle.net/xgmdkpb8/6/
Try this,
$(document).ready(function () {
$('.row').hide();
$('.row:eq(0)').show();
var totalElements = $(".thumbnails li").length;
var elementsInEachRow = 3;
$('#loadMore').click(function () {
var lastVisibleElement = $(".thumbnails li").index($(".thumbnails li:visible").last()) + 1;
var indexOfRowToHide = (lastVisibleElement / 3);
$(".row:eq("+indexOfRowToHide+")").show();
$('#showLess').show();
});
$('#showLess').click(function () {
var lastVisibleElement = $(".thumbnails li").index($(".thumbnails li:visible").last()) + 1;
var indexOfRowToHide = (lastVisibleElement / 3) - 1;
$(".row:eq("+indexOfRowToHide+")").hide();
$('#loadMore').show();
});
});
Pen: http://codepen.io/vbrmnd/pen/ZbWEYW
Related
I want to show and hide a div on click of previous and next. I am using jQuery toggle to achieve this. Below is what I have tried so far.
HTML code
<div id="one">a</div>
<div id="two">b</div>
<div id="three">c</div>
<div id="prev">prev</div>
<div id="next">next</div>
jQuery Script
jQuery(function(){
jQuery("#two, #three").hide();
jQuery("#next").on("click", function(){
jQuery("#one, #two, #three").toggle();
});
});
Fiddle link
https://jsfiddle.net/mqns2hy4/
So as you can see from the above, when I click on "next", I want only b to come and then when I click again, I wish to have c only and so on. Similarly on click of "Prev", I want the above to move in reverse and so on.
You could create one variable that holds index of active element and change that variable on click. Then you can hide all elements except one with the current active index.
let active = 0;
let el = $("div");
let total = el.length - 1;
const toggle = (el, index) => {
el.hide()
el.eq(index).show()
}
toggle(el, active)
$('button').on('click', function() {
this.id === 'prev' ? active -= 1 : active += 1;
if(active > total) active = 0;
if(active < 0) active = total
toggle(el, active)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="one">a</div>
<div id="two">b</div>
<div id="three">c</div>
<button id="prev">prev</button>
<button id="next">next</button>
You could keep the index of the currently shown div:
jQuery(function(){
let index = 0;
// you could also use a class to select them:
let divs = ["#one", "#two", "#three"].map(it => jQuery(it));
divs.forEach(it => it.hide());
jQuery("#next").on("click", function(){
divs[index].show();
if(index > 0) divs[index - 1].hide();
index++;
});
});
$(document).ready(function() {
$(".page").hide();
$("#page1").show();
});
$(document).on('click', "#next", function(){
var pageCount = $(".page").length;
var position = $(".page:visible").data('position');
$(".page:visible").hide();
if(position < pageCount){
$("#page" + (position+1)).show();
}
else
{
$("#page1").show();
}
});
$(document).on('click', "#prev", function(){
var position = $(".page:visible").data('position');
var pageCount = $(".page").length;
$(".page:visible").hide();
if(position > 1){
$("#page" + (position-1)).show();
}
else
{
$("#page" + pageCount).show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="page1" data-position="1" class="page">a</div>
<div id="page2" data-position="2" class="page">b</div>
<div id="page3" data-position="3" class="page">c</div>
<div id="prev">prev</div>
<div id="next">next</div>
Im using Dragula JS for the drag and drop functionality and I would like to also have the option to move back and forth the elements in my list with the mouse click without loosing the drag and drop functionality.. How can I achieve this?
so I click on element 1 and it moves to the list.
I click it back from that list and it moves back.
That's the idea.
I prepared a fiddle with the basic drag and drop if it helps.
http://jsfiddle.net/vf6dnwxj/10/
my structure in the fiddle above:
<div class="wrapper panel panel-body">
<ul id="left1" class="cont-dragula">
</ul>
<ul id="right1" class="cont-dragula">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3.</li>
<li>Item 4.</li>
<li>Item 5.</li>
<li>Item 6.</li>
</ul>
</div>
JS:
dragula([left1, right1]);
Well dragula doesn't do anything special it just moves items around. So You can simply move them around Yourself:
var leftList = document.querySelector('#left1');
var rightList = document.querySelector('#right1');
var list = document.querySelectorAll('#right1 li, #left1 li');
for (var i = 0; i < list.length; i++) {
list[i].addEventListener('click', function(){
if (this.parentNode.id == 'right1') {
leftList.appendChild(this);
} else {
rightList.appendChild(this);
}
});
}
demo fiddle
If You want dragulas callbacks to fire before manipulating DOM add drake.start(this) and after manipulation drake.end():
drake = dragula([left1, right1]);
drake.on('drop', function(el, target, source, sibling){
console.log(el);
console.log(target);
console.log(source);
console.log(sibling);
});
var leftList = document.querySelector('#left1');
var rightList = document.querySelector('#right1');
var list = document.querySelectorAll('#right1 li, #left1 li');
for (var i = 0; i < list.length; i++) {
list[i].addEventListener('click', function(){
drake.start(this);
if (this.parentNode.id == 'right1') {
leftList.appendChild(this);
} else {
rightList.appendChild(this);
}
drake.end();
});
}
Is it possible to hide certain <li> of an <ol> without changing the numbers in front of each list item? I'm trying to make a search function which only shows the <li> which match the input of the user. However if for example the second <li> was to be hidden it would change number in front of the third <li> to a 2, but it should remain a 3.
If possible, I'm looking for an answer without the use of jQuery (Prototype is fine though). But if it can't be done without jQuery then it is acceptable to use jQuery.
HTML:
<label>Search: <input type="text" id="search"/></label>
<button id="clear">Clear</button>
<div id="list">
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ol>
</div>
Javascript:
window.onload = function(){
document.getElementById("search").onkeyup = updateList;
document.getElementById("clear").click = clearInput;
}
function updateList(){
var list = document.getElementById("list");
var listitems = list.getElementsByTagName("li");
for(var i = 0; i < listitems.length; i++) {
var current = listitems[i].innerHTML.toLowerCase();
if(current.indexOf(document.getElementById("search").value.toLowerCase()) != -1) {
listitems[i].style.display = "list-item";
} else {
listitems[i].style.display = "none";
}
}
}
function clearInput(){
document.getElementById("search").value = "";
updateList();
}
http://jsfiddle.net/CYs46/
visibility + height ;-)
A little change from your code as fiddle
if(current.indexOf(document.getElementById("search").value.toLowerCase()) != -1) {
listitems[i].style.visibility = "visible";
listitems[i].style.height = "auto";
} else {
listitems[i].style.visibility = "hidden";
listitems[i].style.height = "0px";
}
I would change a class name of the items if I wanted to hide it and make the items visually disappear without use of display: none:
var value = document.getElementById("search").value.toLowerCase();
if (value && current.indexOf(value) != -1) {
listitems[i].className = "hidden";
} else {
listitems[i].className = "";
}
CSS
.hidden {
position: absolute;
top: -1000px;
left: -1000px;
}
Also I fixed you code a little: you need to check that search terms is not empty before you show/hide items.
Demo: http://jsfiddle.net/43PcY/2/
Set visibility to hidden, and height to zero (only height might also work):
document.getElementById('hideme').style.visibility = 'hidden';
document.getElementById('hideme').style.height = '0px';
document.getElementById('button').onclick = function() {
document.getElementById('hideme').style.visibility = '';
document.getElementById('hideme').style.height = '';
};
JSFiddle
Edit: Without jQuery
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.
I have 2 tabs at the top of a page. When one tab is clicked, I would like that tab to have an "active" class and the other tab to have an "inactive" class so that the user can see what tab is currently selected. How can I go about doing this with javascript/css?
<div class="tabActive">
Option 1
</div>
<div id="tabInactive">
Option 2
</div>
another non-jQuery solution could be the following that works with more than two div:
function changeClass(elClass) {
var divsLenght = document.getElementsByTagName("div").length;
for (var i = 0; i < divsLenght; i++) {
document.getElementsByTagName("div")[i].className = "tabInactive";
}
elClass.className = "tabActive";
}
Demo: http://jsbin.com/opetec/2
<div class="tabInactive" onclick="this.classname='tabActive'"></div>
if using jquery:
$("div.tabInactive").click(function() {
$("div.tabInactive").removeClass("tabActive");
$(this).addClass("tabActive");
});
here's a solution that doesn't use any jQuery! it does assume there is only 2 tabs thought.
http://jsfiddle.net/nYpV3/
<div id="tab1" onclick="setToActive(this, 'tab2');">
Option 1
</div>
<div id="tab2" onclick="setToActive(this, 'tab1');">
Option 2
</div>
function setToActive(me, otherId){
me.className='active';
document.getElementById(otherId).className='inactive';
}
Give your tabs a class of "tab"...
HTML:
<div class="tab">
...
</div>
<div class="tab">
...
</div>
JS:
function getByClass(_class, elem) {
var i, result = [], elems = document.getElementsByTagName("div"); //get the elements
for (i = 0; i < elems.length; i++) {
if (elems[i].className.indexOf(_class) !== -1) { //if the elements have the class passed in, add it to the result array
result.push(elems[i]);
}
}
return result;
}
var i, tabs = getByClass("tab", "div"); //get all divs with class tab
for (i = 0; i < tabs.length; i++) { //for each tab...
tabs[i].onclick = function() { //wire up it's click event...
//to clear the other tabs...
var j;
for(j=0; j < tabs.length; j++) {
tabs[j].className = tabs[j].className.replace(" active", "");
}
this.className += " active"; //where active is a class predefined in the CSS
};
}
http://jsfiddle.net/thomas4g/pqMq2/12/
Try this using jQuery
<div class="tab active">
Option 1
</div>
<div class="tab">
Option 2
</div>
<script>
$(function(){
$(".tab").live("click", function(){
$(".tab").removeClass("active");
$(this).addClass("active");
});
});
</script>
This is my guess:
$('.tabActive, #tabInactive').click(function() {
$(this).toggleClass('active');
}