Hide slide controls if slider length < 2 - javascript

So I've got this slider, and I want to hide its controls if it only has one element inside it.
Markup:
<div class="grid carousel-controls">
<span class="control prev"></span>
<span class="control next"></span>
</div>
<div class="carousel">
<img src="//placecage.com/440/660"/>
</div>
jQuery:
$(function(){
var count = $('.carousel').children().length;
if (count < 2) {
$('.carousel-controls').hide();
}
});
Any takers? ❤️
Edit: Worth adding that it's inside a tab nav, wherein the other carousel has > 2 children, in which case I obviously want the controls to be visible.

You are looking for $.each():
$(function(){
$('.carousel').each(function(i, c){
var count = $(c).children().length;
// if the .carousel-controls is a children of .carousel
if (count < 3)
$(c).find('.carousel-controls').hide();
// if the .carousel-controls is a siblings of .carousel
if (count < 2)
$(c).siblings('.carousel-controls').hide();
// comment out the inappropriate syntax above.
});
});
find() is relative to .carousel and depends where .carousel-controls is placed. If .carousel-controls is inside .carousel, it would also be consider a children of .carousel so you need to count less than 3.

I can give you an idea.
Assumption: only one tab will be active at a time
find carousel-controls of active tab only. and then you can controls hide them based on logic.
$('a[data-toggle="tab"]').on('shown', function (e) {
// access carousel here then you can find children here using $(this);
// your logic goes here.
});
This piece of code is for reference only.

Related

HTML/jQuery Limit no. of divs in container

(firstly I recommend seeing the related image)
I have 3 container having same class .container. Also, user can add child divs dynamically into the containers. The user will start adding divs (that is .parent) by clicking '.add' div inside each '.parent'.
The containers can have at max 3 div. If the user has added 3 divs already then the next div should go in the second container and so on. Once the last container(the third one) is full, an alert should pop up saying "You cannot add anymore divs."
I have two questions:
Using jquery how can I limit the number of '.parent' divs per container to 3. If the user tries to add another it is added to container 2 (unless container 2 has 3 child divs, then it would go to container 3)?
Once the container of page 3 is full (3 divs) an alert should pop up saying "You cannot add anymore divs".
The only snippet of code that I have is not working. Please help me with the code. I am novice in all this stuff.
Thanks in advance.
Related image: [1]: http://i.stack.imgur.com/zi78d.png
Sample code:
<html>// the containers
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>//divs that are supposed to be appended
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>. . .
</html>
.
<script>
var $pages = $('.container');
var child = '$('.add ').parent()';
$(".add").on('click', function () {
var childAdded = false;
$pages.each(function () {
var $container = $(this);
if ($container.children().length < 3) {
$container.append.('child');
childAdded = true;
return false;
}
});
if (!childAdded) {
alert("You can not add any more divs");
}
});
</script>
Several problems in your code
You want the instance of the parent class when you click on the button, not all .parent
You have syntax errors using quotes around jQuery objects that shouldn't be there.
Here's a simple approach using filter() method.
$(".add").on('click', function () {
/* filter $pages down to first available one with space */
var $page=$pages.filter(function(){
return $(this).children().length < 3;
}).first();
if( !$page.length ){ /* if no elements returned from filter, they are all full */
alert("You can not add any more divs");
}else{
/* get instance of parent based on button that was clicked which is "this" */
var $parent=$(this).closest('.parent');
$page.append( $parent );
}
});
DEMO
filter() API docs
You have to track the amount of divs you have added yourself. Then, use this information to determine which .container you should put it in. Something like this:
var added = 0;
...
$(".add").on('click', function () {
var target;
if(added<3) {
target = $pages[0];
} else if (added<6) {
target = $pages[1];
} else if (added<9) {
target = $pages[2];
} else {
alert("You can not add any more divs");
return
}
$(target).append($(this).parent());
added += 1;

How do I apply jQuery's slideToggle() to $(this) and do the opposite to all other elements?

What I'd like to do is have all elements of class collapsible_list not displayed by default (with one exception... see below*), and then toggle their display when their parent <div class="tab_box"> is clicked. During the same click, I'd also like for every other element of class collapsible_list to be hidden so that only one of them is expanded at any given time.
*Furthermore, when the page initially loads I'd also like to check to see if an element of collapsible_list has a child a element whose class is activelink, and if there is one then I'd like that link's parent collapsible_list element to be the one that's expanded by default.
Here's some sample html code:
<style>
.collapsible_list {
display: none;
}
.collapsible_list.active {
display: block;
}
</style>
<div id="sidebar">
<div class="tab_box">
<div class="collapsible_tab">2014</div>
<div class="collapsible_list panel-2014">
1
2
3
</div>
</div>
<div class="tab_box">
<div class="collapsible_tab">2013</div>
<div class="collapsible_list panel-2013">
<a class="activelink" href="/2013/1">1</a>
2
3
</div>
</div>
</div>
And here's where I'm currently at with the javascript (although I've tried a bunch of different ways and none have worked like I'd like them to):
$(document).ready(function() {
// This looks redundant to me but I'm not sure how else to go about it.
$(".collapsible_list").children("a.activelink").parent(".collapsible_list:not(.active)").addClass("active");
$(".tab_box").click(function() {
$(this).children(".collapsible_list").toggleClass("active").slideToggle("slow", function() {
$(".collapsible_list.active:not(this)").each(function() {
$(this).slideToggle("slow");
});
});
});
});
I hope that's not too confusing, but if it is then feel free to let me know. Any help is much appreciated.
Since you have a dom element reference that needs to be excluded use .not() instead of the :not() selector
jQuery(function ($) {
// This looks redundant to me but I'm not sure how else to go about it.
$(".collapsible_list").children("a.activelink").parent(".collapsible_list:not(.active)").addClass("active").show();
$(".tab_box").click(function () {
var $target = $(this).children(".collapsible_list").toggleClass("active").stop(true).slideToggle("slow");
//slidup others
$(".collapsible_list.active").not($target).stop(true).slideUp("slow").removeClass('active');
});
});
Also, instead of using the slide callback do it directly in the callback so that both the animations can run simultaniously
Also remove the css rule .collapsible_list.active as the display is controlled by animations(slide)
Try This.
$('.collapsible_tab a').on('click', function(e){
e.preventDefault();
$('.collapsible_list').removeClass('active')
$(this).parent().next('.collapsible_list').toggleClass('active');
});
Fiddle Demo
I think your code would be less complicated if you simply remembered the previously opened list:
jQuery(function($) {
// remember current list and make it visible
var $current = $('.collapsible_list:has(.activelink)').show();
$(".tab_box").on('click', function() {
var $previous = $current;
// open new list
$current = $('.collapsible_list', this)
.slideToggle("slow", function() {
// and slide out the previous
$previous.slideToggle('slow');
});
});
});
Demo

filter out which span to update

I have the following div collection in my HTML. It's designed to dynamically replicate according to user interaction.
<div class="bill-item">
<!-- Section for a single item -->
<div class="bill-item-img">
<!-- Section for Item pic -->
</div>
<div class="bill-item-description">
<!-- Section for Item description and pricing -->
<div class="bill-item-name">
<p class="bill-item-name-left">Normal Cofee</p><p class="bill-item-name-right">170.00</p>
<div class="clear"></div>
</div>
<div class="bill-item-price">
<span>170.00 USD</span>
</div>
<div class="bill-item-amount">
<span>2</span>
</div>
</div>
<div class="bill-amount-selection">
<!-- Section where the increment & decrement of item amount goes -->
<a class="amount-increase" href="#"></a>
<a class="amount-decrease" href="#"></a>
</div>
</div>
This is the HTML Rendered image of the elements.
I've written the following script to increase the bill-item-amount span value.
$(".amount-increase").click(function(){
x+=1;
$(".bill-item-amount span").html(x);
});
$(".amount-decrease").click(function(){
if(!x<=0){
x-=1;
$(".bill-item-amount span").html(x);
}
});
This works great but, it updates the value of both the span elements. what I want is to catch the event of the clicked element (which I do now) and increase the span value of the respective span. How can I filter out which span to update using javascript.?
Something like $(this).parents('.bill-item').find('.bill-item-amount span') should select the right element.
Inside your callback this is assigned to the eventSource.
You should walk the dom tree from the clicked element up until you reach the .bill-item element and the go down to the .bill-item-amount span node
$(".amount-increase").click(function(){
var $span = $(this).parent().parent().find(".bill-item-amount span");
var x = $span.html();
x+=1;
$span.html(x);
});
$(".amount-decrease").click(function(){
var $span = $(this).parent().parent().find(".bill-item-amount span");
var x = $span.html();
if(!x<=0){
x-=1;
$span.html(x);
}
});
Hi dimal update your code:
$(".amount-increase").click(function(){
x+=1;
$(".bill-item-amount").html(x);
});
$(".amount-decrease").click(function(){
if(!x<=0){
x-=1;
$(".bill-item-amount").html(x);
}
});
dont add span inside the selector [ it changes entire span values]
$(".amount-increase").click(function(){
x+=1;
$("use ur increase span id here").html(x); //
});
$(".amount-decrease").click(function(){
if(!x<=0){
x-=1;
$("use ur decrease span id here").html(x);
}
});
Inside each function the selector $(".bill-item-amount span") will find all the <span> amounts in the document. You can walk the DOM to find the correct <span> using jQuery or plain JavaScript. You seem to be using jQuery functions so my answer also uses jQuery.
The following code combines the two actions into a single function that increases or decreases the amount based on the class name of the <a> clicked. I also added a return false so that the browser will not follow the href="#" on the anchor.
$('.bill-amount-selection').on('click', 'a', function(){
var change = this.className == 'amount-increase' ? 1 : -1
var $amount = $(this).closest('.bill-item').find('.bill-item-amount span')
var amount = parseInt($amount.html(), 10) + change
$amount.html(amount < 0 ? 0 : amount)
return false
});
The use of .on() means that jQuery v1.7+ is required. I can supply a compatible function with lower jQuery versions if necessary.

Unable to get correct offset of floated div

<div id="content">
<div class="oddpost">
<div class="arrow"></div>
</div>
<div class="oddpost">
<div class="arrow"></div>
</div>
<div class="oddpost">
<div class="arrow"></div>
</div>
<div class="oddpost">
<div class="arrow"></div>
</div>
</div>
$(function() {
if (($(".oddpost").position().left + $(".oddpost").width()) >= $("#content").width()) {
$('.arrow').hide();
}
});
http://jsfiddle.net/Ek5Gy/52/
In the code, I have a div(.arrow) nested on another div(.oddpost). What I want to do is hide the .arrow of the left .oddpost only. The idea is .arrow hides when .oddpost is near the left side of #content.
I've tried using offset but it gives the same offset().left value on all the oddpost div so all the arrow div still hides, even the one on the right.
Can anybody tell me how to fix this?
Your main problem lies in your selector usage:
// selecting stuff
$(".oddpost")
// doing stuff on the selection
.position().left
But, you'll have to know how those helper methods work on the given set. position (and many others) will only work on the very first element in the set. Not on every element.
So what you have to do is, iterate over each element in the set and do the test for every element independently, like:
$(".oddpost").each(function () {
if ($(this).prev().length === 0 || $(this).offset().left < $(this).prev().offset().left) {
$('.arrow', this).hide();
}
});
// or
$(".oddpost").each(function () {
if ($(this).position().left === 0) {
$('.arrow', this).hide();
}
});
http://jsfiddle.net/Ek5Gy/53/
The position() call returns values for the first selected element (it doesn't work on all selected elements as many other jQuery calls). Check Javadoc.
This is working for me:
$(function(){
$(".oddpost").each (function (idx, el) {
if ($(el).position().left < $(el).width()) {
$('.arrow', el).hide();
}
});
});
The modified jsfiddle: http://jsfiddle.net/Ek5Gy/54/
In your code, $('.arrow').hide() will always act on all DOM elements that match that particular selector (.arrow). Also, your calculations are only performed once, for the first .oddpost element, since that's the behavior of the position() jQuery function.
I just did not follow exactly what you meant by "near the left of content". I've altered your code a bit to reflect all these changes and prepared a little jsFiddle. Check it here.
Your example works fine.
In your example the value of:
$(".oddpost").position().left + $(".oddpost").width() // Equals 100
This is less the total of #content which is 270px. Your asking if it's greater than or equal too. If you want to hide the arrow when it's near the left try this:
if ($(".oddpost").position().left === 0) {
$('.arrow').hide();
}
EDIT:
$(function(){
$(".oddpost").each(function(){
var position = $(this).position().left;
alert (position);
if(position === 0){
// Do what you need to here.
}
});
});
This is what your looking for...

How to detect mouseleave() on two elements at once?

Answer can be in vanilla js or jQuery. I want to hide a div with the id "myDiv" if the user is no longer hovering over a link with the id "myLink" or a span with the id "mySpan". If the user has his mouse over either element "myDiv" will still show, but the second the user is not hover over either of the two (doesn't matter which element the user's mouse leaves first) "myDiv" will disappear from the face of existence.
In other words this is how I detect mouse leave on one element:
$('#someElement').mouseleave(function() {
// do something
});
but how to say (in a way that will actually work):
$('#someElement').mouseleave() || $('#someOtherElement').mouseleave()) {
// do something
});
How to detect this?
Something like this should work:
var count = 0;
$('#myLink, #mySpan').mouseenter(function(){
count++;
$('#myDiv').show();
}).mouseleave(function(){
count--;
if (!count) {
$('#myDiv').hide();
}
});
jsfiddle
You could use a multiple selector:
$("#someElement, #someOtherElement").mouseleave(function() {
// Do something.
});
You can beautifully use setTimeout() to give the mouseleave() function some "tolerance", that means if you leave the divs but re-enter one of them within a given period of time, it does not trigger the hide() function.
Here is the code (added to lonesomeday's answer):
var count = 0;
var tolerance = 500;
$('#d1, #d2').mouseenter(function(){
count++;
$('#d3').show();
}).mouseleave(function(){
count--;
setTimeout(function () {
if (!count) {
$('#d3').hide();
}
}, tolerance);
});
http://jsfiddle.net/pFTfm/195/
I think, it's your solution!!!
$(document).ready(function() {
var someOtherElement = "";
$("#someElement").hover(function(){
var someOtherElement = $(this).attr("href");
$(someOtherElement).show();
});
$("#someElement").mouseleave(function(){
var someOtherElement= $(this).attr("href");
$(someOtherElement).mouseenter(function(){
$(someOtherElement).show();
});
$(someOtherElement).mouseleave(function(){
$(someOtherElement).hide();
});
});
});
----
html
----
<div id="someElement">
<ul>
<li>element1</li>
<li>element2</li>
</ul>
</div>
<div id="tab1" style="display: none"> TAB1 </div>
<div id="tab2" style="display: none"> TAB1 </div>
While the answer from lonesomeday is perfectly valid I changed my html to have both elements in one container. I originally wanted to avoid this hence I had to do more refactoring for my clients in other html templates, but I think it will pay out on the long term.
<div id="my-container">
<div class="elem1">Foo</div>
<div class="elem2">Bar</div>
</div>
$('#my-container').mouseleave(function() { console.log("left"); });

Categories

Resources