Use jQuery to check if all div's are hidden - javascript

How would I check if all the div's with class test are hidden. And if they are all hidden set wrap1 to hidden. Thanks.
<div id='wrap1'>
<div class="header">Header 1</div>
<div class='test'>Test 1</div>
<div class='test'>Test 2</div>
<div class='test'>Test 3</div>
</div>
UPDATE:
Thanks everyone for the really quick answers, I got it working. They were all very helpful.

You can do the check as by using selector as suggested above and to it like this:
if ( $("div.test:visible").length === 0)
$("#wrap1").hide( );

This snippet will loop all <div id="wrap#"> and hide them if the test are hidden.
$("div[id^='wrap']").each(function() {
var wrap = $(this);
if(wrap.children("div[class^='test']:visible").length == 0) {
wrap.hide();
} else {
wrap.show();
}
});
If you still want to keep your <div id="wrap#"> visible if there are no test at all (as in none in the markup), you can use the following modified snippet:
$("div[id^='wrap']").each(function() {
var wrap = $(this);
if(wrap.children("div[class^='test']").length > 0 &&
wrap.children("div[class^='test']:visible").length == 0) {
wrap.hide();
} else {
wrap.show();
}
});
There is no compelling reason to number classes (other than in edge cases). Your numbering complicates the above code as well as your CSS. It would be easier just to remove the numbering from test. (You don't need it as you can always select a subset of them using :lt(index), :gt(index), :eq(index), :first and :last.
As for numbering ids, that's fine since each id must be unique.

Better way to see if they are all visible is the count for visibility the same as the total count.
$("#wrap1 div:visible").length == $("#wrap1 div").length

jQuery("#wrap1").find("div").each(function()
{
if ($(this).is(':hidden'))
{
}
}
);

Related

How to check if a specific div element is created or not?

I want to check if following code is dynamically created or not :
<div id="js_contact_error_message" style="display: block;">
<div class="error_message"> <!-- For this div only I want to apply the above written inline css-->
Please enter full name
</div>
How should I check this in jQuery? If it's present execute the if condition.
Thanks.
The condition that <div class="error_message">...</div> is present within <div id="js_contact_error_message" style="display: block;">...</div> must get checked.
I tried below code but it didn't work for me:
if ($("#js_contact_error_message").find("div.error_message").length != 0) {
alert("Bestow");
}
You can do this:
var hasDiv = $("#js_contact_error_message div").length > 0 ? true : false;
$("#js_contact_error_message").toggle(hasDiv);
Note:
You need to place this line of code where you have done your js validations.
or you may try with this:
$(document).on('DOMSubTreeModified propertychange',function(){
var hasDiv = $("#js_contact_error_message div").length > 0 ? true : false;
$("#js_contact_error_message").toggle(hasDiv);
});
Try,
For using if-else condition.
if($("#js_contact_error_message").find(".error_message").length > 0)
{
alert("div present");
}
else
{
alert("div not present");
}
But as you stated in your question, you want to apply specific inline css. Make a class for the style what you have and you can use the ollowin code.
$("#js_contact_error_message").find(".error_message").addClass("your_style_class");
This code will apply your css class only for those divs which match the condition.
EDIT:
If you want to add your style to the div, you can try defining it in your page, which will apply as soon as the div is added dynamically.
<style>
#js_contact_error_message .error_message
{
/*your inline style*/
}
</style>
if($("#js_contact_error_message .error_message").length > 0)
{
alert("div is present");
}
else
{
alert("div is not present");
}
Demo
You can check it in many ways.. few of them are :
Use $("#js_contact_error_message").has('div') function of jquery to get the specific element Has in JQuery
If the error message div is the only div to be inside the main div then you can check it as :
Check the element $("#js_contact_error_message").html() is blank or use $("#js_contact_error_message").children() (Children in JQuery) to check if it has any childrens.
Hope this helps :)
make sure your html composition is correct , opening and closing. Then try this code.
if($("#js_contact_error_message").length > 0)
{
$("#js_contact_error_message").find(".error_message").addClass("style_class");
}

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

Collapse HTML if no content found

I want to be able to remove HTML elements if they contain no content.
Let's say we have some markup and are targeting all 'collapse' classes:
<div class='collapse'>[CONTENT?]</div>
If there is some content then don't do anything.
But if there is no content - no string characters or whitespace - then remove the div element completely.
This is easy to implement in the simple cases but with nested content it's slightly more more tricky.
Here is a demo, if you try removing the [CONTENTX?] strings and then seeing what the HTML structure is you'll notice that it doesn't work completely.
If a div only has other divs with no content then that should be treated as no characters or whitespace.
If we remove all [CONTENTX?] strings then we should see no HTML structure.
What ways are there to handle this?
jsFiddle: http://jsfiddle.net/97udq/
HTML:
<div id='container'>
<div class='collapse'>
[CONTENT1?]
</div>
<div class='collapse'>
[CONTENT2?]
<div class='collapse'>
[CONTENT3?]
<div class='collapse'>[CONTENT4?]</div>
<div class='collapse'>[CONTENT5?]</div>
</div>
</div>
</div>
Javascript:
$(function(){
// function
collapse();
// Show HTML structure
alert($('#container').html());
});
function collapse(){
// Loop thru all collapse elements
$('.collapse').each(function(){
// Check for pure whitespace
if($(this).html().replace(/\s+/g, '').length==0){
// Nothing to see, so remove.
$(this).remove();
}
});
}
CSS:
.collapse{
height:20px;
border:1px solid red;
}
I think this does the job;
It just uses text() instead of html();
Here's the documentation.
This one adds the trim(), but I thik that's not what you want.
function collapse(){
$('.collapse').each(function(){
if($(this).text().length==0){
$(this).remove();
}
});
}
Here's another way of accomplishing what you want. It recurses down the DOM pruning nodes from the bottom up. Hope this helps.
function prune(root) {
$.each($(root).children(), function(){
prune($(this));
});
if($(root).html().replace(/\s+/g, '').length==0 && $(root).hasClass("collapse")){
$(root).detach();
}
}
Code integrated into your JSFiddle
You need to recreate the .each() loop, but reversed. Just like that :
function collapse(){
var el = $('.collapse');
for(var i = el.length - 1; i >= 0; i--){
if(el[i].innerHTML.replace(/\s+/g, '').length==0){
$(el[i]).remove();
}
}
}
It will remove the childrens first, then check for parent.
Here a fiddle : http://jsfiddle.net/97udq/5/
EDIT :
I missunderstood your question, here's the right solution :
function collapse(){
$('.collapse').each(function(){
var $this = $(this)
var clone = $this.clone();
clone.children().remove();
if(clone.html().replace(/\s+/g, '').length==0){
$this.children().appendTo($this.parent());
$this.remove()
}
})
}
Basicly, you clone the current div, remove its children and then check if there is some text. If there's none, you append his children to his parent
Fiddle : http://jsfiddle.net/97udq/9/

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...

jQuery toggle() text in separate element

I am having some trouble getting a toggle function to work and need someone to help explain it to me.
My HTML (simplified):
<div id="filter_names"></div>
<div class="item">Option 1</div>
<div class="item">Option 2</div>
<div class="item">Option 3</div>
<div class="item">Option 4</div>
My jQuery (simplified)
$(".item").click(function(){
var tagname = $(this).html();
$('#filter_names').append(' > '+tagname);
$(".loading").show();
});
As you can see I am appending clicked items' value to the div at the top. This works fine, but i need it to be removed when i click it again.
I am pretty sure it needs a toggle() function but so far my attempts have been pretty fruitless.
Some guidance would be greatly appreciated.
EDIT: You can see what i want to achieve in this JSfiddle. It's working exactly how i want it to by appending a value to the end (like a breadcrumb link), but is not being removed when i click it again.
You need to look at the #filter_names contents and check if the clicked tag's value is already included, then remove it if it is, or add it otherwise:
if (filternames.indexOf(tagname) === -1) {
$('#filter_names').append(' > '+tagname);
} else {
$('#filter_names').text(filternames.replace(' > '+tagname, ''));
}
Working fiddle: http://jsfiddle.net/passcod/Kz3vx/
Note that you might get weird results if one tag's value is contained in another's.
<script type="text/javascript">
$(function(){
$(".item").click(function(){
var $this=$(this);
var tagname = ' > ' +$this.html();
//if has item-check class remove tag from filter_names
if($this.hasClass("item-click")){
var h=$("#filter_names").text();
$("#filter_names").text(h.replace(tagname, '' ));
}
else{
$('#filter_names').append(tagname);
}
$(this).toggleClass("item-click").toggleClass("item");
});
});
</script>
try this one...
$(this).toggleClass("item-click item");
this will add these classes alternatively when you click on div. or if you just want to remove this class on second click then you should write this in your click handler.
if( $(this).hasClass("item-click")){
$(this).removeClass("item-click");
}
EDITED -----
to remove appended html you can try this...
if($(this).hasClass("item-click")){
$("#filter_names").text("");
}
else{
$('#filter_names').append(tagname);
}
it's working HERE
hope this helps you!!
I like passcod's solution - here's an alternative that wraps the elements in divs and puts them in alphabetical order.
JSFiddle here. The sort function is from http://www.wrichards.com/blog/2009/02/jquery-sorting-elements/.
$(".item").click(function(){
var tagname = $(this).html();
var target = $('#filter_names').find('div:contains("> ' + tagname + '")');
if (target.is('*')) {
target.remove();
}
else $('#filter_names').append('<div class="appended"> > '+ tagname +'<div>');
function sortAlpha(a,b) {
return a.innerHTML > b.innerHTML ? 1 : -1;
}
$('#filter_names div').sort(sortAlpha).appendTo('#filter_names');
});

Categories

Resources