Elegant way to toggle visibility of divs in the same display area - javascript

I have 3 divs that contain a hidden field each:
<div class="item-wrapper">
<div class="item-title">Button 1</div>
<div class="hidden-field>Some hidden data</div>
</div>
<div class="item-wrapper">
<div class="item-title">Button 2</div>
<div class="hidden-field>Some more hidden data</div>
</div>
<div class="item-wrapper">
<div class="item-title">Button 3</div>
<div class="hidden-field>Even more hidden data</div>
</div>
My jQuery looks like this:
$( ".item-title" ).click(function() {
$( this ).next().slideToggle( "slow" );
$( this ).toggleClass( "item-active" );
});
The hidden-field divs have an absolute position and are displayed below the three wrappers. I want to find a way to show only one hidden field at a time, which basically means that if any hidden-field is visible at the time of the click, it needs to be hidden first.
Is there an elegant way of doing this or will I have to switch from slideToggle() to hide() and show() with conditionals?

Toggle is not always a good option. It is only useful for simple open/close items.
Try something that operates specifically on the chosen item and all the unselected ones (using not).
http://jsfiddle.net/gu6w8Lxb/
$( ".item-title" ).click(function() {
var $this = $(this);
$( ".item-title" ).not($this).removeClass("item-active").next().slideUp();
$this.addClass("item-active").next().slideDown();
});
Which can shorten further to:
var $items = $(".item-title");
$items.click(function() {
var $this = $(this);
$items.not($this).removeClass("item-active").next().slideUp();
$this.addClass("item-active").next().slideDown();
});
if you want the current item to toggle open/closed, test for its active class:
http://jsfiddle.net/gu6w8Lxb/1/
var $items = $(".item-title");
$(".item-title").click(function () {
var $this = $(this);
if ($this.hasClass("item-active")) {
$this.removeClass("item-active").next().slideUp();
} else {
$items.not(this).removeClass("item-active").next().slideUp();
$this.addClass("item-active").next().slideDown();
}
});

Related

Get parent of the parent of div

I have searched and tried many things to do this such as closest() and parents() and parent() and find() But i couldnt make it to work at all .
I have this html
<div class='message_holder area2 user45 chatid32'>
<a class='avatar' title='jhon'>
<img height='28px' width = '28px' src="link to image" />
</a>
<div class='flag_holder'>
<div class='edited png32'></div>
<div class=' png32'></div>
</div>
<div class='message user_chat'> hghgghgh</div>
<div class='like_holder'>
<div class='chattime'>02-12 22:16</div>
<div class='likepng'></div>
<div class='likescore'>5</div>
<div class='unlikescore'>0</div>
<div class='unlikepng'></div>
<div class="like">
<div class="editpng"></div>
<div class="deletepng"></div>
</div>
</div>
</div>
So what i want is when i click on on div class deletepng i want to remove the two divs unlikepng and likepng .
this js
$(document).on ("click", ".deletepng", function () {
$this = $(this);
//alert( $this.closest(".like").html()); I could just make this to work
// alert( $this.parents(".like_holder").html()); wont work
// alert( $this.closest(".like_holder").html()); wont work
// alert( $this.parent().parent().html()); wont work
// alert( $this.closest(".like_holder").find(".like_holder").html()); wont work
});
I just wonder why they dont work those my trying . Where it can be my mistake ?
EDIT:
i dont know if this have a role or not , i have what i tried inside Dialog box like that
$(document).on ("click", ".deletepng", function () {
$this = $(this);
$('<div>' + c_delete + '</div>').dialog({
resizable: false,
buttons: {
"Yes": function() {
chat_text_h.html('<div class="removed"> Removed</div>'); // do something here
$(this).dialog("close");
//alert( $this.closest(".like").html()); I could just make this to work
// alert( $this.parents(".like_holder").html()); wont work
// alert( $this.closest(".like_holder").html()); wont work
// alert( $this.parent().parent().html()); wont work
// alert( $this.closest(".like_holder").find(".like_holder").html()); wont work
}
}
});
});
use closest then use the second argument as the context.
$(document).on("click", ".deletepng", function() {
var $holder = $(this).closest('.like_holder');
$('.likepng, .unlikepng', $holder).remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='message_holder area2 user45 chatid32'>
<a class='avatar' title='jhon'>
<img height='28px' width='28px' src="link to image" />
</a>
<div class='flag_holder'>
<div class='edited png32'></div>
<div class=' png32'></div>
</div>
<div class='message user_chat'>hghgghgh</div>
<div class='like_holder'>
<div class='chattime'>02-12 22:16</div>
<div class='likepng'>like</div>
<div class='likescore'>5</div>
<div class='unlikescore'>0</div>
<div class='unlikepng'>unlike</div>
<div class="like">
<div class="editpng"></div>
<div class="deletepng">delete</div>
</div>
</div>
</div>
EDIT
Since your update, you need to set a global variable to remember $this or the container/holder. try this:-
var $holder;
$(document).on("click", ".deletepng", function() {
$holder = $(this).closest('.like_holder');
$('<div>' + c_delete + '</div>').dialog({
resizable: false,
buttons: {
"Yes": function() {
chat_text_h.html('<div class="removed"> Removed</div>');
$(this).dialog("close");
$('.likepng, .unlikepng', $holder).remove();
}
}
});
});
$this.closest(".like").html(); => this will return HTML of parent div, where delete button is. Not removing the element
$this.parents(".like_holder").html() => this will return html of div.message_holder. Not removing the element.
$this.closest(".like_holder").html() => this will return html of div.like_holder
$this.parent().parent().html(); close enogh, but still far => html of div.like_holder
$this.closest(".like_holder").find(".like_holder").html(); return null => no child element with class like_holder in div.like_holder.
Kind of example
$(document).on ("click", ".deletepng", function () {
var $parent = $(this).parent().parent();
$parent.find('.likepng').remove();
$parent.find('.unlikepng').remove();
});
.deletepng{
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='message_holder area2 user45 chatid32'>
<a class='avatar' title='jhon'>
<img height='28px' width = '28px' src="http://www.gettyimages.pt/gi-resources/images/Homepage/Hero/PT/PT_hero_42_153645159.jpg" />
</a>
<div class='flag_holder'>
<div class='edited png32'></div>
<div class=' png32'></div>
</div>
<div class='message user_chat'> hghgghgh</div>
<div class='like_holder'>
<div class='chattime'>02-12 22:16</div>
<div class='likepng'> like me</div>
<div class='likescore'>5</div>
<div class='unlikescore'>0</div>
<div class='unlikepng'> unlike me</div>
<div class="like">
<div class="editpng"></div>
<div class="deletepng">delete button</div>
</div>
</div>
</div>
UPDATE
If you want to make it from dialog box, or other things - you can't use this variable. This is not making any sense. You should provide unique id to your message_box and then use it, like
$(id_of_message_box).find('.likepng, .unlikepng').remove()
or as I can see from your code:
var $parent = $this.parent().parent();
$parent.find('.likepng, .unlikepng').remove();
It means you should use $this in your function instead of $(this)
You can access the parents parent of your $(this) like:
var likeholder;
likeholder = $(this).parent().parent();
However this is generally ill advised. You'll have a jquery object though.
Let me know how you get on
In order to select the parent of a parent of an element you try this:
$(document).on ("click", ".deletepng", function () {
alert( $($(this).parent()).parent().html());
});
Since you can only execute the parent() method on Jquery Objects.
Here's an example unrelated to your code. JSFiddle.
Try this, you need sibling of parent;
alert( $this.closest(".like").parent().find(".unlikescore").html());
alert ($this.closest('.like').siblings('.unlikepng').html()) ;
working js fiddle

jquery toggle visibility if has class

I've collected all my portfolio items into an array as seen here.
function SetPortfolioItems(filter) {
items = $( ".portfolio-item" );
items.toggle("slow");
}
The function parameter is a string class name for example "Print". What I want to do is hide the portfolio items which don't have the class 'filter' and the ones that do, make them visible.
For your question:
What I want to do is hide the portfolio items which don't have the class 'filter' and the ones that do, make them visible.
You can make this:
function SetPortfolioItems(filter) {
var str = filter.toLowerCase();
var invalidItems = $( ".portfolio-item:not(."+str+")");
invalidItems.hide("slow");
var validItems = $( ".portfolio-item." + str );
validItems.show("slow");
}
SetPortfolioItems('filter');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="portfolio-item">item 1</div>
<div class="portfolio-item filter">item 2</div>
<div class="portfolio-item">item 3</div>
<div class="portfolio-item filter">item 4</div>
<div class="portfolio-item">item 5</div>
<div class="portfolio-item">item 6</div>
Use jQuery not() function.
function SetPortfolioItems(filter) {
items = $( ".portfolio-item" );
items.not('.' + filter).hide("slow");
}
Use hasClass by jQuery :
jQuery Docs
function SetPortfolioItems(filter) {
items = $( ".portfolio-item" );
if (items.hasClass(filter)) {
...
} else {
...
}
}

toggling div and adding and removing class

i have some divs i wanna toggle i am able to toggle but unable to remove classes when ever i click on the next div
index.php
<div id="menu_top1" class="menu_top1">LINK 1</div>
<div id="menu_top" class="menu_top">LINK 2</div>
<div id="content_area1" style="display:none;">
THIS IS LINK 1
</div>
<div id="content_area2" style="display:none;">
THIS IS LINK 2
</div>
Jquery.js
$('#menu_top1').click(function() {
$('#content_area1').toggle('slow', function() {
$('.menu_top1').toggleClass('active');
});
});
Here is a Fiddle https://fiddle.jshell.net/kunz/t5u6mcmn/
if you are trying to show corresponding content_area when you click on link and make the link active? you can check this
fiddle
i saw you using same id for multiple elements.just edited them.
still you want same id for all elements(strictly not recommended) check this fiddle
check this updated fiddle
$('.menu_top').click(function() {
var index = $( this ).index() + 1;
console.log(index);
$('[id^="content_area"]' ).hide();
$('#content_area' + index ).toggle('slow', function() {
$('.menu_top').toggleClass('active');
});
});

jquery class and display change.

I'm trying to make 1 form in multiple screens whit 1 submit button.
This is what i got this far but i'm stuck in jquery and hoped that someone could help me an say what i'm doing wrong here.
<html>
<body>
<form action="" method="post">
<ul id="stappen">
<li id="step_1" class="selected">1. step_1</li>
<li id="step_2" class="">2. step_2</li>
<li id="step_3" class="">3. step_3</li>
<li id="step_4" class="">4. step_4</li>
</ul>
<div id="stappen">
<div id="content_step_1" class="content_step" style="display: block;">content step 1</div>
<div id="content_stap_2" class="content_step" style="display: none;">content step 2</div>
<div id="content_stap_3" class="content_step" style="display: none;">content step 3</div>
<div id="content_stap_4" class="content_step" style="display: none;">content step 4</div>
</div>
</form>
</body>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'></script>
<script>
(function() {
var body = $('body');
$('.step_2').bind('click', function(){
body.toggleClass('step_2');
return false;
});
})();
</script>
</html>
The thing what i wan't to do is:
When li step_2 is clicked li id="step_2" class=""- changes "class" to "selected" and "display" changes "none" to "block" like in this code is at the moment step 1 is selected and display: block.Afther all of this changes everything from step 1 must be the same as everything else :) -->class empty and display to none.
I know there is something wrong whit the jquery code but i don't know how to make it wright.
every try i did converted in an error or din't work, this is why ifilled in the script whish i know is partialy good.
I hope somebody can help me and/or point me in the right direction.
thnx in advanced.
As #Ricardo says, you can not use same ID as for UL as for DIV. You have to fix it. Here example of improved you code version:
HTML
<body>
<form action="" method="post">
<ul id="ul_stappen">
<li id="step_1" class="selected">1. step_1</li>
<li id="step_2" class="">2. step_2</li>
<li id="step_3" class="">3. step_3</li>
<li id="step_4" class="">4. step_4</li>
</ul>
<div id="div_stappen">
<div id="content_step_1" class="content_step" style="display: block;">content step 1</div>
<div id="content_stap_2" class="content_step" style="display: none;">content step 2</div>
<div id="content_stap_3" class="content_step" style="display: none;">content step 3</div>
<div id="content_stap_4" class="content_step" style="display: none;">content step 4</div>
</div>
</form>
</body>
CSS
.selected{color:red}
JAVSCRIPT
(function() {
$('#ul_stappen>li').on('click',function(){
if(!$(this).hasClass('selected')){
$('.selected').removeClass('selected');
$(this).addClass('selected');
$('#div_stappen>div').filter(function(){return $(this).css('display')==='block'}).hide();
$('#div_stappen>div').eq($(this).index()).show();
}
});
})();
And Working JSFIDDLE example
Hope this help you
You should not repeat IDs in HTML. The id "stappen" is repeated for both UL and DIV below that.
Let's assume that UL id is "ul_stappen" and DIV id is "div_stappen":
<ul id="ul_stappen">
...
</ul>
<div id="div_stappen">
..
</div>
Now we can achive your required effect with the jQuery code below:
$( '#ul_stappen' ).on('click', 'li', function() {
if ( $(this).hasClass('selected') ) {
return;
};
// show hide proper content divs
var oldIndex = $ulStappen.find( 'selected' ).index();
var newIndex = $(this).index();
$( '#div_stappen li' ).eq( oldIndex ).hide();
$( '#div_stappen li' ).eq( newIndex ).show();
// add/remove 'selected' for proper li's
// this must be the last part to be done
$( '#ul_stappen' ).find( 'selected' ).removeClass( 'selected' );
$(this).addClass( 'selected' );
});
Good luck, have fun!
First issue: you have two elements with the same id (steppen). It's a mistake. For my code to work you need to change the second element id in "steppendiv".
Second issue: the first content id is step, while the other three are stAp (with the "a" instead "e"). For my code to work you need to change them and make all "content_step_1" (_2 _3 and so on)
$(document).ready(function () {
$( "#stappen" ).on( "click", "li", function() {
$( "#stappen li" ).removeClass( "selected" );
$( this ).addClass( "selected" );
var liId = $( this ).attr( "id" );
var splittedId = liId.split( "_" );
var newId = "#content_step_" + splittedId[ 1 ];
$( "#stappendiv > div" ).hide();
$( newId ).show();
});
});

How can I dynamically generate a jQuery selector?

I have a page with multiple divs generated dynamically via PHP/MySQL. The div class names are also generated dynamically.
<div class="1er45">Test 1</div>
<div class="25dd58">Test 2</div>
<div class="87f77">Test 3</div>
<div class="87fffas">Test 4</div>
<div class="1er45">Test 1</div>
<div class="25dd58">Test 2</div>
<div class="87fffas">Test 4</div>
<div class="8asdf">Test 5</div>
<div class="25dd58">Test 2</div>
<div class="87fffas">Test 4</div>
<div>...</div>
How can I modify this jQuery selector to match all of the dynamically generated div class names above? I only want to show the first div if there are multiple divs with the same class name.
<script>
$('.classname').not(':first').hide();
</script>
From what I understand probably you need to iterate over all div's and hide all same class names occurrences grater than 1 :
$( 'div[class]' ).each( function() {
$( 'div.' + $( this ).attr( 'class' ).replace( /\s/g, '.' ) + ':gt(0)' ).hide();
});
jsFiddle
I don't really see the point of having a class being dynamically generated.
If you know the pattern of these "ids", you can catch them with a regex.
Assuming that you are only ever going to have one class value in each of those <div>'s, you could acheive what you are asking for in the following code:
var $firstDiv = $("div:first");
var sFirstClass = $firstDiv.attr("class");
if ($("." + sFirstClass).length < 2) {
$firstDiv.hide();
}
That code would:
Retrieve the first div
Get it's class attribute value
Checks to see if there is more than one element with that class value
Hides the first element, if there is not
Iterate through each div, counting occurrences of each class name. Then for each collected class name, hide repeats.
var classNames = {};
$('div').each(function(){
var c = $(this).attr('class');
classNames[c] ? classNames[c]++ : classNames[c] = 1;
});
for (var c in classNames) {
if (classNames[c] > 1)
$('div.' + c).not(':first').hide();
}
http://jsfiddle.net/ne770a5g/

Categories