zepto javascript show x elements - javascript

Using zepto.js, how can You show X items from a ul, hide the rest and show them
only when the user clicks "show more" Link/button?
10X!

Here's one way to accomplish what you're asking.
$(function() {
$('li').slice(5).toggle();
$('span').click(function() {
$('li').slice(5).toggle();
});
});​
The first .slice(5).toggle() functions take all the list items selected, narrow them down to a subset of elements that starts at index 5 through the end. Then it toggles the visible state of the first element it finds in that subset.
We then attach a function to the click event on the span, which is our Show/Hide element. That function is actually just the same as the initial function we ran to hide all the elements past index 5.
Check out this JS Fiddle for a working example. Also, for further reference here are the docs on .slice() and here are the docs on .toggle().
Hope that helps!

Basically there are 2 ways.
Use zepto to toggle a class and use css to define what to hide
/* show only the first 3 list items */
ul.collapsed li:nth-child(n+4) {
display: none;
}
var $list = $(ul.collapsed); // initially the list is collapsed
// use a show-more link to toggle display of remaining items
$("a.show-more").click(function(){
// get the current state of the list by querying the className
var shouldShow = $list.hasClass("collapsed") == true;
$list.toggleClass("collapsed");
// set the link text according to the task (show or hide)
$(this).html(shouldShow ? "Show less" : "Show more");
// its a link, don't follow it
return false;
});
Use zepto "standalone"
var $list = $(ul);
// use the link to set the css properties directly
$("a.show-more").click(function(){
var shouldShow = $list.hasClass("collapsed") == true;
$("li:nth-child(n+4)", $list).css({
"display": shouldShow : "" : "none"
});
$(this).html(shouldShow ? "Show less" : "Show more");
return false;
});

Related

Checking if Element hasClass then prepend and Element

What I am trying to achieve here is when a user clicks an element it becomes hidden, once this happens I want to prepend inside the containing element another Element to make all these items visible again.
var checkIfleft = $('#left .module'),checkIfright = $('#right .module');
if(checkIfleft.hasClass('hidden')) {
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if(checkIfright.hasClass('hidden')) {
right.prepend('<span class="resetRight">Reset Right</span>');
}
I tried multiple ways, and honestly I believe .length ==1 would be my best bet, because I only want one element to be prepended. I believe the above JS I have will prepend a new element each time a new item is hidden if it worked.
Other Try:
var checkIfleft = $('#left .module').hasClass('hidden'),
checkIfright = $('#right .module').hasClass('hidden');
if(checkIfleft.length== 1) {
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if(checkIfright.length== 1) {
right.prepend('<span class="resetRight">Reset Right</span>');
}
else if(checkIfleft.length==0){
$('.resetLeft').remove()
} else if (checkIfright.length==0){
$('.resetRight').remove()
}
Basically if one element inside the container is hidden I want a reset button to appear, if not remove that reset button...
hasClass() only works on the first item in the collection so it isn't doing what you want. It won't tell you if any item has that class.
You can do something like this instead where you count how many hidden items there are and if there are 1 or more and there isn't already a reset button, then you add the reset button. If there are no hidden items and there is a reset button, you remove it:
function checkResetButtons() {
var resetLeft = $('#left .resetLeft').length === 0;
var resetRight = $('#left .resetRight').length === 0;
var leftHidden = $('#left .module .hidden').length !== 0;
var rightHidden = $('#right .module .hidden').length !== 0;
if (leftHidden && !resetLeft) {
// make sure a button is added if needed and not already present
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if (!leftHidden) {
// make sure button is removed if no hidden items
// if no button exists, this just does nothing
$('#left .resetLeft').remove();
}
if (rightHidden && !resetRight) {
$('#right').prepend('<span class="resetRight">Reset Right</span>');
} else if (!rightHidden) {
$('#right .resetRight').remove();
}
}
// event handlers for the reset buttons
// uses delegated event handling so it will work even though the reset buttons
// are deleted and recreated
$("#left").on("click", ".resetLeft", function() {
$("#left .hidden").removeClass("hidden");
$("#left .resetLeft").remove();
});
$("#right").on("click", ".resetRight", function() {
$("#right .hidden").removeClass("hidden");
$("#right .resetRight").remove();
});
FYI, if we could change the HTML to use more common classes, the separate code for left and right could be combined into one piece of common code.
Add the reset button when hiding the .module, if it's not already there :
$('#left .module').on('click', function() {
$(this).addClass('hidden');
var parent = $(this).closest('#left');
if ( ! parent.find('.resetLeft') ) {
var res = $('<span />', {'class': 'resetLeft', text : 'Reset Left'});
parent.append(res);
res.one('click', function() {
$(this).closest('#left').find('.module').show();
$(this).remove();
});
}
});
repeat for right side !
I've recently experimented with using CSS to do some of this stuff and I feel that it works quite well if you're not trying to animate it. Here is a jsfiddle where I can hide a module and show the reset button in one go by adding/removing a 'hideLeft' or 'hideRight' class to the common parent of the two modules.
It works by hiding both reset button divs at first. Then it uses .hideLeft #left { display:none;} and .hideLeft #right .resetLeft { display: block; } to hide the left module and display the reset button when .hideLeft has been added to whichever element both elements descend from. I was inspired by modernizr a while back and thought it was a neat alternative way to do things. Let me know what you think, if you find it helpful, and if you have any questions :)

Add & Remove element IF class has x style...not working properly

I'm using a jquery quick search plugin (https://github.com/riklomas/quicksearch) which filters a list based upon the data entered into an input field.
If there's no results returned, I want to display a message saying so.
The quick search plugin adds display: none to all list elements that aren't to be shown.
Therefore, I tried this:
// load jquery.quicksearch
$('#search').parent().css('display','block').end().quicksearch('#ul'+id+' li');
// show / hide message
$("input#search").keypress(function() {
li = $('.category li');
if (li.css('display') == 'none') {
$('body').append('<div id="noContent">no content</div>');
} else {
$('#noContent').remove();
}
});
The result is a very twitchy / buggy solution. Some times it doesn't append the message even if all li items have display: none. It also doesn't even remove the no content message even when there ARE list items visible.
Any ideas?
Read the docs: you don't need to do what you're doing.
Simply use the noResults option.
Their example:
$('input#search').quicksearch('table tbody tr', {
'delay': 100,
'selector': 'th',
'stripeRows': ['odd', 'even'],
'loader': 'span.loading',
'noResults': 'tr#noresults',
.......
looks like you would want 'noResults': '#noContent'

jQuery toggle select from select option mechanism

I am trying to toggle via a select option. I am having difficulties toggling more than two. My goal is to be able toggle as far as 4 through the select option. For example Categories and subcategories. Here is my example in jsfiddle.
<script type="text/javascript">
var op = $("#tables option[value='options']:selected");
var os = $("#tables option[value='Example2']:selected");
if (op.length)
$("#something").show();
else
$("#something").hide();
if (op == ("#something").show())
$("#something2").show();
else
$("#something2").hide();
}​
</script>
Is this the design pattern you are looking for?
if your object is not selected
if your parent is selected
you are also selected
else
you are selected
else
you are now unselected
This logic will work for any depth of recursion.
EDIT: Assuming each menu is a ul. You'll have to tweak the selectors.
This is just one way to do it. Not the best if you have events firing on visibility, or if you have ui reflow issues.
clickyclicky = function(event) {
var $target = $(event.currentTarget);
if (!$target.hasClass("selected")) {
// hide the old target and its parents
var $oldTarget = $('.selected');
$oldTarget.removeClass("selected").hide().parents('ul').hide();
// show the new target and its parents
$target.show().addClass("selected").parents('ul').show();
} else {
// hide the target
$target.removeClass("selected").hide();
// move the selected token to the parent.
$parent = $target.parent().parent(); // assuming an ul/li tree pattern.
if ($parent.is('ul')) {
$parent.addClass("selected");
}
}
}
I haven't tested this code, it's just a general reference.
EDIT: Here's the Fiddle: http://jsfiddle.net/uA7XD/76/

Collapsible list with jQuery - How to update Expand/Collapse all button

I've got a list of items which can be expanded/collapsed individually or all at once with an Expand All/Collapse All button.
All the items start collapsed, but if you manually expand item so that every item is expanded, the 'Expand All' button should change to 'Collapse All'. Similarly if you collapse all the items it should change to 'Expand All'.
So every time you click on an individual line, it should check to see if ALL the items have now been collapsed/expanded, and if so, update the Expand/Collapse All button.
My problem is that I'm not sure how to iterate over all the items on a click to see if they are collapsed or not and properly update.
Here is a JSFiddle for this: JSFiddle
Here is my current code:
var expand = true;
jQuery.noConflict();
jQuery(function() {
jQuery('[id^=parentrow]')
.attr("title", "Click to expand/collapse")
.click(function() {
jQuery(this).siblings('#childrow-' + this.id).toggle();
jQuery(this).toggleClass("expanded collapsed");
ExpandCollapseCheck();
});
jQuery('[id^=parentrow]').each(function() {
jQuery(this).siblings('#childrow-' + this.id).hide();
if (jQuery(this).siblings('#childrow-' + this.id).length == 0)
jQuery(this).find('.expand-collapse-control').text('\u00A0');
});
jQuery('#childrow-' + this.id).hide("slide", { direction: "up" }, 1000).children('td');
});
function CollapseItems() {
jQuery('[id^=parentrow]').each(function() {
jQuery(this).siblings('#childrow-' + this.id).hide();
if (!jQuery(this).hasClass('expanded collapsed'))
jQuery(this).addClass("expanded collapsed");
});
}
function ExpandItems() {
jQuery('[id^=parentrow]').each(function() {
jQuery(this).siblings('#childrow-' + this.id).show();
if (jQuery(this).hasClass('expanded collapsed'))
jQuery(this).removeClass("expanded collapsed");
});
}
function ExpandCollapseChildren() {
if (!expand) {
CollapseItems();
jQuery('.expander').html('Expand All');
}
else {
ExpandItems();
jQuery('.expander').html('Collapse All');
}
expand = !expand;
return false;
}
function ExpandCollapseCheck() {
if ((jQuery('[id^=parentrow]').hasClass('expanded collapsed')) && (expand)) {
jQuery('.expander').html('Expand All');
CollapseItems();
expand = !expand;
}
else if ((!jQuery('[id^=parentrow]').hasClass('expanded collapsed')) && (!expand)) {
jQuery('.expander').html('Collapse All');
ExpandItems();
expand = !expand;
}
}
A couple of things I see with your code.
It seems that you may have multiple children with the same ID, such as #childrow-parent0. This is not legal HTML, and can lead to problems with JavaScript. Use classes instead.
Manipulating ID's to find children is more difficult than using built-in jQuery selectors to find children. I realize that in this case, they are siblings rather than true children, but you can still use .nextUntil(".parent") to find all of the "children" of a parent.
Use your click handlers to do the expanding/collapsing instead of repeating code. One you have a click handler, you can call .click() on a parent, and it will toggle as if you clicked it.
If half of your elements are collapsed, do you want "Expand All" or "Collapse All"? You might want both.
With all of that in mind, I wrote your code with a lot less lines. To answer your specific question, I just compared the number of '.parent.expanded' elements to the number of '.parent' elements to see if they were all expanded or not. (I changed to using a single .parent class.)
Demo
The relevant code to your question:
$('#expand_all').toggleClass("disabled", $('.parent.expanded').length == $('.parent').length);
$('#collapse_all').toggleClass("disabled", $('.parent.collapsed').length == $('.parent').length);
This uses toggleClass(), with the second argument returning true/false depending on the number of collapsed/expanded parents. This is used by toggleClass to determine whether the disabled class is applied.
Don't bother iterating, just use a selector to get a count of all the elements & their classes:
var $all = jQuery('selector to return all lines');
if($all.length == $all.filter('.collapsed').length)
//all the rows are collapsed
if($all.end().length == $all.filter('.expanded').length)
//all the rows are expanded

jquery how to change class of parent div on toggle

When I slideToggle the simple accordian that I have, I would like to change the class of the link element and the .revealBox div that wraps the whole accordion depending on whether the accordion is opened or closed
my jquery is
$(document).ready(function() {
// choose text for the show/hide link - can contain HTML (e.g. an image)
var showText = 'Hide Information';
var hideText = 'Show Information';
var is_visible = false;
$('.collapseLink').append('<span class="dottedBot">' + showText + '</span>');
$('.revealBoxContents').show();
$('a.collapseLink').click(function() {
// switch visibility
is_visible = !is_visible;
// change the link depending on whether the element is shown or hidden
$(this).html((!is_visible) ? showText : hideText);
// toggle the display - uncomment the next line for a basic "accordion" style
//$('.toggle').hide();$('a.toggleLink').html(showText);
$(this).parent().next('.revealBoxContents').slideToggle('slow');
// return false so any link destination is not followed
return false;
});
// toggle the bottom link
$('.collapseLink').click(function() {
$(this).parents('.revealBoxContents').stop(true, true).slideToggle('slow');
$(".collapseLink").html((!is_visible) ? showText : hideText);
$(this).parent('.item').toggleClass('current');
});
});
my Url is
http://satbulsara.com/NSJ-local/eqs1.htm
Thanks,
Sat
You want to use the addClass() function on the element.
http://api.jquery.com/addClass/
You can also do that using toggleClass() as seen on jQuery documentation :
$('div.foo').toggleClass(function() {
if ($(this).parent().is('.bar')) {
return 'happy';
} else {
return 'sad';
}
});
http://api.jquery.com/toggleClass/
You can make use of jquery's addClass() and removeClass() to add and remove classes .

Categories

Resources