Limit the items shown in a ul element - javascript

Here's my code to limit the number of visible list items in a ul:
$wnd.$(el)
.find('li:gt(9)')
.hide()
.end()
.append(
$wnd.$('<li>+More</li>').click( function(){
$wnd.$(this).siblings(':hidden').show().end().remove();
})
);
When +More is clicked it will show all the items immediately.
What should be added in the code such when +More is clicked it will not show everything yet, just the next 10 items? Then, when all items are shown, a +Less option should be shown to just show the first 10 items, as it was before.

That's a strange syntax, but something like this maybe
$wnd.$(el)
.find('li:gt(9)')
.hide()
.end()
.append(
$wnd.$('<li>+More</li>').click(function () {
$wnd.$(this).remove().siblings(':hidden').slice(0, 10).show();
if ($wnd.$(el).find('li:hidden').length === 0) {
$wnd.$(el).append(
$wnd.$('<li>+Less</li>').click(function () {
$wnd.$(el).find('li:gt(9)').hide();
})
)
}
})
);

This is one way:
$( 'li:gt(9)' )
.hide()
.parent()
.append(
$( '<li>more</li>' ).on( 'click', function() {
var el = $( this ).siblings( ':hidden' );
if ( el.length ) el.slice( 0, 10 ).show();
else $( 'li:gt(9)' ).not( this ).hide();
$( this ).text( $( this ).siblings( ':hidden' ).length ? 'more' : 'less' );
})
);
FIDDLE

How about this? https://jsfiddle.net/0hyL9ngr/
HTML
<ul id='some-list'>
<li class='list-item'>1</li>
<li class='list-item'>2</li>
<li class='list-item'>3</li>
...
<li class='list-item'>39</li>
<li class='list-item'>40</li>
<li class='list-item'>41</li>
<li id='show-more'>More</li>
<li id='show-first-ten'>Less</li>
</ul>
JavaScript
$('#show-more').on('click', function () {
$('.list-item:hidden:lt(10)').show();
if ($('.list-item:hidden').length == 0) {
$(this).hide();
$('#show-first-ten').show();
}
});
$('#show-first-ten').on('click', function () {
$('.list-item:gt(9)').hide();
$(this).hide();
$('#show-more').show();
});
CSS
#show-more {
cursor: pointer;
}
#show-first-ten {
display: none;
cursor: pointer;
}
.list-item:nth-child(n+11) {
display: none;
}

Related

Draggable LI's connected by SVG-Lines using JavaScript

following is the image of till now done want to connect those parent and child ul li
hi,
will appreciate you help.
I want to create a extendable list, in wich the children-li's are connected to their parant-li's trough a SVG-Line. The li-Elements should also be draggable. Here an example, which is close to my vision.
Here my working code without the SVG-Lines and undraggable li's.
var chidID = 0;
$('body').on('click', '.ul-appending', function() {
var levelID = $(this).attr('data-levelnumber');
var parentID = $(this).attr('data-parentNumber');
createNode(levelID,parentID,chidID,this);
//getParent(this);
});
function createNode(levelID,parentID,chidID,elem){
console.log(levelID,parentID,chidID);
levelID++;
parentID++;
$(elem).parent().append(
$('<ul>').addClass('newul')
.append(
$('<li>')
.append(
$('<button>').addClass('ul-appending').text("Add UL").addClass('marginBottomUl').attr('data-parentNumber',parentID).attr('data-levelnumber',levelID)
)
)
);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul>
<li><button class="ul-appending" data-parentNumber='0' data-levelnumber='0'>Main Parent</button> </li>
</ul>
</div>
Here's a working example for your vision. Not everything works as you want it to, but I think with that, you can go on and solve your issue.
Here the snippet:
$(document).ready(function(){
var chidID = 1;
$('body').on('click', '.ul-appending', function() {
var levelID = $(this).attr('data-levelnumber');
var parentID = $(this).attr('data-parentNumber');
chidID++;
createNode(levelID,parentID,chidID,this);
//getParent(this);
});
function createNode(levelID,parentID,chidID,elem){
levelID++;
parentID++;
var btnNew = $('<button>').addClass('ul-appending').text("Add UL").addClass('marginBottomUl').attr('data-parentNumber',parentID).attr('data-levelnumber',levelID).attr("id", chidID);
$(elem).parent().append(
$('<ul>').addClass('newul')
.append(
$('<li>')
.append(
btnNew
)
)
);
var mySVG = $('body').connectSVG();
mySVG.drawLine({
left_node:'#'+$(elem).prop("id"),
right_node:'#'+chidID,
horizantal_gap:10,
error:true,
width:1
});
$( '#'+$(elem).prop("id") ).draggable({
cancel: false,
drag: function(event, ui){
mySVG.redrawLines();
}
});
$( '#'+chidID ).draggable({
cancel: false,
drag: function(event, ui){
mySVG.redrawLines();
}
});
}
});
button {
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://www.jqueryscript.net/demo/jQuery-Plugin-To-Connect-Two-Html-Elements-with-A-Line/required/script/jquery.svg.min.js"></script>
<script src="http://www.jqueryscript.net/demo/jQuery-Plugin-To-Connect-Two-Html-Elements-with-A-Line/required/script/jquery.connectingLine.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<div>
<ul>
<li><button id="1" class="ul-appending" data-parentNumber='0' data-levelnumber='0'>Main Parent</button>
</li>
</ul>
</div>

JQuery click event and toggleClass method

I created a simple lottery ticket and I made selector with toggle method.
This is my code.
$( "span" ).click(function() {
$( this ).toggleClass( "span-selected" );
});
The toggle functionality works fine but I want to add a limitation so that only 7 numbers can be chosen in one container. Is there a way to achieve this.
Here is my JSBIN > http://jsbin.com/menawu/1/edit?js,output
You need to check if there are already 7 elements checked in that container, like so:
$( "span" ).click(function() {
if (
$(this).hasClass("span-selected") ||
(!$(this).hasClass(".span-selected") && $(this).closest(".num-cont").find(".span-selected").length < 7)
) {
$( this ).toggleClass( "span-selected" );
}
});
So your criteria are:
if it's not selected, check if there are less than 7: if yes, toggle, otherwise don't do anything
if it is selected, unselect it.
You can use this code;
$( "span" ).click(function() {
if($(this).parent().parent().find('.span-selected').length===7){
alert('Limit');
}
else{
$( this ).toggleClass( "span-selected" );
}
});
Yes,
you can cumulate the count of tickets chosen in a variable and allow toggling only when count is less than 7, based on the jQuery hasClass method to check if your span was previously selected:
var countTicket = 0;
$( "span" ).click(function() {
if($(this).hasClass( "span-selected")) {
countTicket--;
$( this ).toggleClass( "span-selected" );
} else if(countTicket<7) {
$( this ).toggleClass( "span-selected" );
countTicket++;
}
});
Here an example, with multiple case for controle your numbers.
You can easily know if it's unselect/select or if more than 7 span are selected by using hasClass/removeClass/addClass
$("span").click(function(){
if($(this).hasClass("selected"))
{
$(this).removeClass("selected");
}
else{
if($("span.selected").length<7)
{
$(this).addClass("selected");
}
else
console.log("7 span selected");
}
});
span{
width:50px;
height:50px;
margin:10px;
background-color:#eee;
display:inline-table;
}
.selected{
background-color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
just insert count and max variables
var max = 7;
var count = 0;
$("span").click(function() {
if (count < max) {
$(this).toggleClass("span-selected");
count++;
}
});
You can get the number of selected item using the parent container and count them:
$( "span" ).click(function() {
if($(this).closest('.num-cont').find('.span-selected').length==7){
alert('Limit');
}
else{
$( this ).toggleClass( "span-selected" );
}
});

jQuery keep parent highlight on submenu hidden navigation arrows

I need some help in jQuery and I really hope that I could find some help here. I would like when I use my navigation arrows (next/previous) when I am on a hidden item that the parent item stays highlight. For the first item home, it works but for the rest not. Does anybody can help me please?
here my fiddle
<div id="cssmenu">
<ul id="list">
<li>Home</li>
<ul class="hide"><li></li></ul>
<li>Newsletter</li>
... </div>
I tried to fiddle something :
$(document).ready(function(){
$('#cssmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents('li').addClass('active');
});
I manage my next and previous button like that :
$( "#next, #prev" ).click( function ( event ) {
var
positionActiveClass = menu.find( "> li.active" ).index(),
menuLength = menu.find( "> li" ).length - 1,
buttonId = $( this ).attr( "id" );
if ( buttonId === "next" ) {
if ( positionActiveClass === ( menuLength ) ) {
newElementActiveClass = menu.find( "li" ).eq( 0 );
newPositionActiveClass = newElementActiveClass.find( "> a" ).attr( "href" );
animation( newPositionActiveClass );
} else {
newElementActiveClass = menu.find( "li" ).eq( positionActiveClass + 1 );
newPositionActiveClass = newElementActiveClass.find( "> a" ).attr( "href" );
animation( newPositionActiveClass );
}
} else {
if ( positionActiveClass === 0 ) {
newElementActiveClass = menu.find( "li" ).eq( menuLength );
newPositionActiveClass = newElementActiveClass.find( "> a" ).attr( "href" );
animation( newPositionActiveClass );
} else {
newElementActiveClass = menu.find( "li" ).eq( positionActiveClass - 1 );
newPositionActiveClass = newElementActiveClass.find( "> a" ).attr( "href" );
animation( newPositionActiveClass );
}
}
event.preventDefault();
} );
There is an extra ul after the first li which has a class hide. What is that for? Just remove that ul and everything works fine.

jQuery ui selectable: function does not react to deselection when there is only one element selected

The following is a code for jQuery ui´s selectable plugin. The code allows me to select more than one selectable object with the mouse without the lasso and without the keyboard. The console.log message does come up in firebug when I select. It also comes up when I have more than one selectable selected and deselect some of them.
The problem is, when there is only one element selected and I deselect it, nothing happens. I need the console.log message to come up also in that situation.
Any help appreciated
<style>
#feedback { font-size: 1.4em; }
#selectable .ui-selecting { background: #FECA40; }
#selectable .ui-selected { background: #F39814; color: white; }
#selectable { list-style-type: none; margin: 0; padding: 0; width: 60%; }
#selectable li { margin: 3px; padding: 0.4em; font-size: 1.4em; height: 18px; }
</style>
<script type="text/javascript">
$(function() {
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
stop: function() {
var result = $( "#select-result" ).empty();
$( ".ui-selected", this ).each(function() {
var index = $( "#selectable li" ).index( this );
result.append( " #" + ( index + 1 ) );
console.log("test")
});
}
});
});
</script>
<p id="feedback">
<span>You've selected:</span> <span id="select-result">none</span>.
</p>
<ol id="selectable">
<li class="ui-widget-content">Item 1</li>
<li class="ui-widget-content">Item 2</li>
<li class="ui-widget-content">Item 3</li>
<li class="ui-widget-content">Item 4</li>
<li class="ui-widget-content">Item 5</li>
<li class="ui-widget-content">Item 6</li>
</ol>
Your problem is that your console.log function fires only for each of the selected items because the selector there is ".ui-selected". When you deselect the last one, there aren't any selected so the function doesn't fire at all.
You can bind another function for each of the non-selected items, like this:
$(function() {
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
stop: function() {
var result = $( "#select-result" ).empty();
$( ".ui-selected", this ).each(function() {
var index = $( "#selectable li" ).index( this );
result.append( " #" + ( index + 1 ) );
console.log("selected");
});
$( ".ui-selectee", this ).each(function() {
var index = $( "#selectable li" ).index( this );
result.append( " #" + ( index + 1 ) );
console.log("not selected");
});
}
});
});
You can make it more dynamic by firing a function for each item that you just selected or unselected. For this you can use the selected and unselected events of selectable. This fires at the same time as stop and fires for each item that you just selected or unselected, depending on which one you use. So for example:
$(function() {
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
stop: function() {
// fires at stop
var result = $( "#select-result" ).empty();
},
selected: function(event, obj) {
// this function will fire for each item that was just selected
// obj is the selected object
console.log("selected");
console.log(obj);
// Not sure if this bit will work, could try this instead of obj
var index = $( "#selectable li" ).index(obj);
$('#result').append( " #" + ( index + 1 ) );
},
unselected: function(event, obj) {
// this function will fire for each item that was just deselected
// obj is the unselected object
console.log("deselected");
console.log(obj);
// Not sure if this bit will work
var index = $( "#selectable li" ).index(obj);
$('#result #" + ( index + 1 )').remove();
}
});
});

jQuery: change css of the page number when scrolling

I'm trying to figure how to change the css class of #pg2 to 'active' when the user scrolls to #bx2 and change #pg3 to 'active' when the user scrolls to #bx3 and so on...
<ul id="navi" style="position:fixed;top:0">
<li>1</li>
<li>2</li>
<li>3</li>
...
<li>100</li>
</ul>
<div class="tallbigblock" id="bx1">...</div>
<div class="tallbigblock" id="bx2">...</div>
<div class="tallbigblock" id="bx3">...</div>
...
<div class="tallbigblock" id="bx100">...</div>
Here is my jquery:
$( window ).scroll( function() {
var t = $( "#bx1" ).offset().top;
if( $(this).scrollTop() > t )
{
$( "#navi li a" ).removeClass( "active" ).hasClass( "active" );
$( "#pg1" ).addClass( "active" );
}
var t = $( "#bx2" ).offset().top;
if( $(this).scrollTop() > t )
{
$( "#navi li a" ).removeClass( "active" ).hasClass( "active" );
$( "#pg2" ).addClass( "active" );
}
var t = $( "#bx3" ).offset().top;
if( $(this).scrollTop() > t )
{
$( "#navi li a" ).removeClass( "active" ).hasClass( "active" );
$( "#pg3" ).addClass( "active" );
}
});
The thing is, if I have a 50 ".tallbigblock" divs... or dynamically generated ".tallbigblock" divs...
I've been trying to figure out how to make the jquery work for n number of ".tallbigblock" divs without coding the jquery for each div manually...
hope you guys can help me out...
Thanks a bunch!!
This is untested but the only difference from the original code is that it's not hard-coded and only allows one box to be active at a time.
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
$('#navi li a').removeClass('active');
$('.tallbigblock').each(function()
{
if(scrollTop > $(this).offset().top)
{
$('#pg'+this.id.split('x')[1]).addClass('active');
return false; // this breaks the each loop
}
});
});
Based on the code #summoner posted, I've modified and tested the following code:
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
$(".tallbigblock").each(function() {
if(scrollTop > $(this).offset().top)
{
var i = $(this).attr('id');
var nid = "#pg" + i.replace("bx", "");
$("#navi li a").removeClass("active").hasClass("active");
$(nid).addClass("active");
}
});
});

Categories