JQuery toggle with multipls divs and icon - javascript

I've found examples where you can use a selectors to have multiple divs expand/collapse, but haven't seen one with the use of an icon when collapsed and one when expanded.
How can I adjust the following so that it allows me to expand and collapse multiple divs? ie: if you open one it won't open ALL the others.
<!-- HTML -->
Show
<div class="slidingDiv" style="display: block;">
Check out
</div>
<!-- CSS -->
.show_hide{
background:url(http://img37.imageshack.us/img37/1127/plusminus.png) no-repeat;
padding-left:20px;
}
<!-- JS -->
$(document).ready(function(){
$(".slidingDiv").hide();
$('.show_hide').click(function(){
$(".slidingDiv").slideToggle();
var isShow = $(this).text() == 'Show';
$(this).text(isShow ? 'Hide' : 'Show').css({backgroundPosition:'0 '+ (isShow?-18:0) +'px'});
});
});

You are asking for a complex solution, here are some tips:
1 - Use different icons on hide/show:
Use a different class for showing and hiding, than use removeClass & addClass to change your "a" class. Ex:
$('a.group1').removeClass('hiding').addClass('showing');
2 - To not hide/show multiple divs, use a second class to group them.
Ex:
<a class="show_hide group1">
<div class="slidingDiv group1"> div1 </div>
<div class="slidingDiv group1"> div2 </div>
...
$('.slidingDiv.group1').hide();
Than, you can select them by using "a.group1", and ".slidingDiv.group1"...
Thus slidingDiv can determine how to hide, and group1 determines what should be hidden/shown.
See:
Add class: http://api.jquery.com/addClass/
Remove class: http://api.jquery.com/removeClass/
Multiple classes HTML: https://stackoverflow.com/a/8722205/506625
Multiple selector jquery: http://api.jquery.com/multiple-selector/
Element visibility jquery: http://api.jquery.com/visible-selector/

$(document).ready(function(){
$(".show_hide").click(function(){
$("div").slideToggle();
});
});
Try this
http://jsfiddle.net/DRAJI/Q8tFh/4/
This is an Example jsfiddle, refer this

What you are looking for is an accordion. Search for "jQuery Accordion" and you will find many solutions.
Here is a small idea to get you going if you want to do it yourself:
HTML:
<div id="container">
<div class="header">H1</div>
<div class="content">c1</div>
<div class="header">H2</div>
<div class="content">c2</div>
<div class="header">H3</div>
<div class="content">c3</div>
</div>
CSS:
.container { height: 600px; width: 400px; }
.header { height: 32px; background: url(plus.png) no-repeat right center; }
.selectedHeader { background: url(minus.png) no-repeat right center !important; }
.content { height: 200px; }
Javascript:
$('#container').live("click", function (e) {
var $item = $(e.target);
if ($item.hasClass("header")) {
$item.addClass("selectedHeader").siblings().removeClass("selectedHeader"));
$content.not($item.next()).slideUp();
$item.next().slideDown(UxSpeed);
}
}
// this will hide all contents initially and show only the first one
$('.header').not($('.header').first()).next().hide();
Hope this helps.

Use slideToggle with $(this) instead of using with $(".slidingDiv")
$(document).ready(function(){
$(".slidingDiv").hide();
$('.show_hide').click(function(){
$(this).slideToggle();
var isShow = $(this).text() == 'Show';
$(this).text(isShow ? 'Hide' : 'Show').css({backgroundPosition:'0 '+ (isShow?-18:0) +'px'});
});
});

Check this one, DEMO http://jsfiddle.net/yeyene/FPGH4/
Add target attribute to target multiple divs.
HTML
<a class="show_hide" target="slidingDiv1">Show</a>
<div id="slidingDiv1" class="slidingDiv">
Check out 1
</div>
<a class="show_hide" target="slidingDiv2">Show</a>
<div id="slidingDiv2" class="slidingDiv">
Check out 2
</div>
<a class="show_hide" target="slidingDiv3">Show</a>
<div id="slidingDiv3" class="slidingDiv">
Check out 3
</div>
JQUERY
$(document).ready(function(){
$('.show_hide').on('click',function(){
$('.show_hide').text(isShow ? 'Hide' : 'Show').css({backgroundPosition:'0 '+ (isShow?-18:0) +'px'});
$(".slidingDiv").slideUp(100);
$('#'+$(this).attr('target')).slideDown(300);
var isShow = $(this).text() == 'Show';
$(this).text(isShow ? 'Hide' : 'Show').css({backgroundPosition:'0 '+ (isShow?-18:10) +'px'});
});
});

Related

jquery slideToggle opens all divs instead of just the div that is required

I have a page that can have a variable number of <div> the idea is people can click the + symbol which is an <img> then the div that is linked to the img tag will display.
I currently have:
PHP/HTML
$plus = '<img src="images/plus.png" class="clickme" width="20px" height="20px">';
$table .= '<div>'.$plus.'</div>';
$hidden .= '<div class"diary">-Content-</div>';
JS
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function(){
$( ".clickme" ).click(function() {
$( ".diary" ).slideToggle( "slow", function() {
});
});
});
</script>
This obviously opens all divs and not just the one that is clicked on. I have looked at other similar questions on here and have tried a number of variations such as:
$(document).ready(function(){
$(".clickme").click(function(){
$(this).next(".diary").toggle();
});
});
However, when I try these it just stops working altogether. i.e. none of the divs slide up or down. I see the examples work on JS Fiddle but as soon as i apply it to my page I get nothing.
I am possibly doing something really dumb for it not to work but can't see what.
thanks for any help.
The HTML output should look like
<div>
<div>
<table>
<img class="clickme">
</table>
</div>
<div class="diary">
<table> content </table>
</div>
<div>
(based on tht HTML provided)
Best way would be to add an attribute with matching indexes to both elements
<div>test toggle
<div class="clickme" data-index="1">click me</div>
<div class="toggle" id="obj_1">toggled field</div>
</div>
and then in the JQuery:
$(function () {
$(".clickme").click(function () {
//get number from clicked element's attribute
var index =$(this).attr('data-index');
//select element with id that matches index and toggle
$('#obj_'+index).toggle();
});
})
After looking at your code, i can see that the slideToggle call is maded on .diary class which is probably applied on each of your elements.
I suggest you to put your diary div inside the $plus div then use jquery children or simply give your .diary divs a unique id and use the id attribute for your
toggle.
EDIT:
Here is a simple html output:
<div class="clickme">
<div class="diary">CONTENT HERE</div>
</div>
Add this in the CSS:
.clickme {
background: url('images/plus.png') no-repeat top left;
min-width: 20px;
min-height: 20px;
cursor: pointer;
}
Script tag:
<script>
$(function() {
$(".clickme").click(function() {
$(this).children().slideToggle("slow");
});
});
</script>
Note that i'd let the diary class for your usage and styling purpose but it's not used anywhere.

Javascript - How to turn this into a simple function

$(document).ready(function()
{
// $('.pull-me').click(function()
// {
// $('.login').slideToggle('slow')
// });
$('#thumbnail1').mouseenter(function()
{
$('#thumbnailTitle1').css('visibility', 'visible')
});
$('#thumbnail1').mouseleave(function()
{
$('#thumbnailTitle1').css('visibility', 'hidden')
})
$('#thumbnail2').mouseenter(function()
{
$('#thumbnailTitle2').css('visibility', 'visible')
});
$('#thumbnail2').mouseleave(function()
{
$('#thumbnailTitle2').css('visibility', 'hidden')
})
$('#thumbnail3').mouseenter(function()
{
$('#thumbnailTitle3').css('visibility', 'visible')
});
$('#thumbnail3').mouseleave(function()
{
$('#thumbnailTitle3').css('visibility', 'hidden')
})
});
I'm very new to Javascript but am trying to learn. I aware this is jQuery but would like to know if there is a quicker way to do this code, like create a smaller function that i can call up to display/hide the text.
Because i will be adding more thumbnails and i don't want to have to write it all out for every photo and text that i display on the photo.
You can use bind a single event handler using Multiple Selector, In the event handler create the targeted selector using the current element this id property.
$('#thumbnail1, #thumbnail2, #thumbnail3').hover(function(){
var selector='#thumbnailTitle'+ this.id.replace(/[^\d.]/g,'');
$(selector).css('visibility','visible');
}, function(){
var selector='#thumbnailTitle'+this.id.replace(/[^\d.]/g,'');
$(selector).css('visibility','hidden');
})
However I would recommend you to establish the relationship using custom data-* prefixed attribute. Here example
$('.thumbnail').hover(function() {
$('#' + this.dataset.target).toggleClass('hidden');
}, function() {
$('#' + this.dataset.target).toggleClass('hidden');
})
.hidden {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="thumbnail" data-target="thumbnailTitle1">thumbnail 1</span>
<span class="thumbnail" data-target="thumbnailTitle2">thumbnail 2</span>
<span class="thumbnail" data-target="thumbnailTitle3">thumbnail 3</span>
<div class="hidden" id="thumbnailTitle1">thumbnailTitle1</div>
<div class="hidden" id="thumbnailTitle2">thumbnailTitle2</div>
<div class="hidden" id="thumbnailTitle3">thumbnailTitle3</div>
The following is an option.
( function( $, window, undefined ) {
var handle_mouse_events = function handle_mouse_events( thumbnail_selector, thumbnail_title_selector ) {
$( thumbnail_selector ).mouseenter(
function() {
$( thumbnail_title_selector ).css( 'visibility', 'visible' );
}
);
$( thumbnail_selector ).mouseleave(
function() {
$( thumbnail_title_selector ).css( 'visibility', 'hidden' );
}
);
};
handle_mouse_events( '#thumbnail1', '#thumbnailTitle1' );
handle_mouse_events( '#thumbnail2', '#thumbnailTitle2' );
handle_mouse_events( '#thumbnail3', '#thumbnailTitle3' );
} )( jQuery, this );
.image_container > div {
display : inline-block;
width : 150px;
height : 200px;
}
span {
visibility : hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image_container">
<div id="thumbnail1">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=150%C3%97150&w=150&h=150" />
<span id="thumbnailTitle1">Title #1</span>
</div>
<div id="thumbnail2">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=150%C3%97150&w=150&h=150" />
<span id="thumbnailTitle2">Title #2</span>
</div>
<div id="thumbnail3">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=150%C3%97150&w=150&h=150" />
<span id="thumbnailTitle3">Title #3</span>
</div>
</div>
Use classes instead of ID's if you want to target similar elements with a behaviour.
The function itself is correct. The problem is that you have structured your HTML with unique ID's for every image. Trying to fix the problem by writing functions that target your unique ID's is the wrong approach, the underlying problem is your usage of ID's to target the element in the first place.
$(document).ready(function() {
$('.thumbnail').on('mouseenter', function() {
$(this).find('.thumbnail-title').css('visibility', 'visible');
})
$('.thumbnail').on('mouseleave', function() {
$(this).find('.thumbnail-title').css('visibility', 'hidden');
})
});
In the code snippet above you can see that every element with a class of thumbnail is selected. When the user hovers over a thumbnail you can reference the currently hovered element (with $(this)) and find the child element with the class thumbnail-title.
This is the simplest approach to sharing behaviour across elements of the same type.
Here's a working fiddle: https://jsfiddle.net/wq5r97ep/2/
EDIT: You can of course abstract this away into a plugin or just a general function. But this is the basic idea.
Something like this:
function handleEventsFor(index) {
$('#thumbnail' + index).mouseenter(function() {
$('#thumbnailTitle' + index).css('visibility', 'visible')
});
$('#thumbnail' + index).mouseleave(function() {
$('#thumbnailTitle' + index).css('visibility', 'hidden')
})
}
And call it like this:
handleEventsFor(1);
handleEventsFor(2);
Or like this:
for(var i = 0; i < 5; ++i) {
handleEventsFor(i);
}
You can try like this also,
Lets say your HTML
<div id="thumbnails">
<div><img class="thumbnails" src="" /></div>
<div><img class="thumbnails" src="" /></div>
<div><img class="thumbnails" src="" /></div>
<div><img class="thumbnails" src="" /></div>
</div>
Jquery
$(document).ready(function(){
$("#thumbnails").find('.thumbnails').mouseenter(function(){
var visibility = $(this).css('visibility');
if(visibility == 'hidden'){
$(this).css('visibility', 'visible');
}
});
$("#thumbnails").find('.thumbnails').mouseleave(function(){
var visibility = $(this).css('visibility');
if(visibility == 'visible'){
$(this).css('visibility', 'hidden');
}
});
});
I would write a simple visibleHover plugin for it. Using it will work like this
$(selectorForThumbnails).visibleHover(selectorForText);
Or as the example shows
// '.thumbnail' is the class of the parent elements
// 'span' is the selector for the children text elements
$('.thumbnail').visibleHover('span');
You can customize these inputs to match any HTML structure you have.
Click the Run code snippet button below to see it work
(function($) {
$.fn.visibleHover = function(selector) {
return this.each(function(idx, elem) {
$(elem).hover(
function() { $(selector, elem).css('visibility', 'visible'); },
function() { $(selector, elem).css('visibility', 'hidden'); }
);
});
};
})(jQuery);
$('.thumbnail').visibleHover('span');
.thumbnail {
float: left;
margin-right: 10px;
}
.thumbnail .image {
width: 100px;
height: 100px;
background-color: #eee;
}
.thumbnail span {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="thumbnail">
<div class="image"></div>
<span>Text A</span>
</div>
<div class="thumbnail">
<div class="image"></div>
<span>Text B</span>
</div>
<div class="thumbnail">
<div class="image"></div>
<span>Text C</span>
</div>
Referencing by ID (i.e. $('#thumbnailn')) is very specific. You can make broader references by accessing tags or other attributes such as class instead.
Something like:
HTML:
<div id="thumbnail1" class="thumbnails"><span id="thumbnailTitle1"></span>...</div>
<div id="thumbnail1" class="thumbnails"><span id="thumbnailTitle2"></span>...</div>
<div id="thumbnail1" class="thumbnails"><span id="thumbnailTitle3"></span>...</div>
JavaScript:
$(".thumbnails").mouseenter(function() {
$(this).children("span").css('visibility', 'visible');
}).mouseleave(function() {
$(this).children("span").css('visibility', 'hidden');
});
In the above example I show how to reference a class (i.e. $(".thumbnails")) and a tag (i.e. ("span")) using JQuery
Using JQuery
$('#thumbnail3').mouseleave(function(e)
{
$(e.target).hide();
})
Using css.
#thumbnail3:hover {display:none}
Writing the whole thing inside a loop is one option.
for(var i = 1; i <= whatever_your_length_is; i++) {
$('#thumbnail' + i).mouseenter(function() {
$('#thumbnailTitle' + i).css('visibility', 'visible');
};
$('#thumbnail' + i).mouseleave(function() {
$('#thumbnailTitle' + i).css('visibility', 'hidden');
});
}

jquery detect class and add css to div

This is an example of a scenario I have got:
<div id="portfolio">
<a class="show-project" href="#">
<!-- some content here -->
</a>
<div class="scrollable">
<!-- full height container with scroll -->
</div>
</div>
When link is clicked, additional class is added to "scrollable move-left".
I would like to detect when it is added and replace css "overflow-y: auto;" with "overflow-y: hidden;"
I am trying to achieve this with:
<script>
$(document).ready(function () {
$("#portfolio .show-project").click(function(){
if ($("#portfolio .scrollable").hasClass("move-left")) {
$("#portfolio").css("overflow-y", "hidden");
} else {
$("#portfolio").css("overflow-y", "auto");
}
});
});
</script>
Could you advice me how to fix this please?
Very appreciated!
You can use jQuery toggleClass and hasClass in order to toggle the class on the element and change the overflow-y attribute accordingly.
Ref:
Add or remove one or more classes from each element in
the set of matched elements, depending on either the class's presence
or the value of the state argument.
Code:
$(document).ready(function () {
$("#portfolio .show-project").click(function () {
$("#portfolio .scrollable").toggleClass('move-left');
var overflow;
($("#portfolio .scrollable").hasClass("move-left")) ? overflow = 'hidden' : overflow = 'auto';
$("#portfolio").css("overflow-y", overflow);
});
});
Demo: http://jsfiddle.net/IrvinDominin/n0d5jxe8/

How to change CSS of child element <span> inside parent <div> element Using jQuery onclick event?

I have two menu icons, both classed .menuentry, with the IDs #topicicon and #searchicon, in a menubar. Beneath them are two larger divs, #topiclist and #searchform, both initially set to display:none;.
What I would like to do is click each menu icon and display the corresponding larger div underneath, as well as getting rid of the other larger div if it has been display previously.
So, for example, when I click #topicicon, it displays #topiclist and hides #searchform.
The code is being used on this website, in the menubar at the top: http://bonfiredog.co.uk/bonfog
And this is the code that I am using.
HTML:
<div id="topicicon"><img src="topic_icon.png" /></div>
<div id="searchform"><img src="search_icon.png" /></div>
<div id="topiclist"></div>
<div id="searchform"></div>
CSS:
#topiclist {
display:none;
}
#searchform {
display:none;
}
jQuery:
$("#topicicon").click(function(){
$("#topiclist").css("display", "visible");
$("#searchform").css("display", "none");
}, function(){
$("#formlist").css("display", "hidden");
});
Not working as of now...
You have to make two click handlers for #topicicon and #searchform and use .hide() and .show() as shown :-
$("#topicicon").click(function(){
$("#topiclist").show();
$("#searchform1").hide();
});
$("#searchform").click(function(){
$("#topiclist").hide();
$("#searchform1").show();
});
and you are using two div's with same id's i.e searchform so change the id of second searchform div to say searchform1 and try above code.
You could avoid having to write multiple click handlers, and reuse across different components with the following:
$(function () {
$('.showRelated').click(function () {
var relatedId = $(this).data('rel');
$('.related').hide(); // hide all related elements
$(relatedId).show(); // show relevant
});
});
.related {
display: none;
margin-top: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<div id="topicicon" class="showRelated" data-rel="#topiclist"><i class="fa fa-newspaper-o"></i></div>
<div id="searchicon" class="showRelated" data-rel="#searchform"><i class="fa fa-search"></i></div>
<div id="topiclist" class="related">Topic List</div>
<div id="searchform" class="related">Search Form</div>
"visible" is not correct value for display propriety. You should add "display: block", or "display: inline-block", or "display: inline" or any other value that is admitted by display propriety.

I can't get all the div's to show up with the same #id

http://jsfiddle.net/bDQt7/4/
This doesn't work, hello2 and hello3 won't show up. It has to do with the '#id can only be used once' ? Changing it to class doesn't work, how to fix this?
HTML
Toggle
<div id="menu" class="hidden">hello</div>
<div id="menu" class="hidden">hello2</div>
<div id="menu" class="hidden">hello3</div>
CSS
.hidden {
display: none;
}
.unhidden {
display: block;
}
JS
function unhide(divID) {
var item = document.getElementById(divID);
if (item) {
item.className = (item.className == 'hidden') ? 'unhidden' : 'hidden';
}
}
IDs must be unique.
Try this:
HTML:
<div class="hidden">hello</div>
<div class="hidden">hello2</div>
<div class="hidden">hello3</div>
JS:
$(document).ready(function(){
$("a").click(function(){
$("div").toggleClass("hidden unhidden");
});
});
Fiddle here.
A Jquery solution for you, I just replaced your id with another unique class. Just refer the code below to get a grip over it.
HTML
Toggle
<div class="xTest hidden">hello</div>
<div class="xTest hidden">hello2</div>
<div class="xTest hidden">hello3</div>
JQUERY
$("a").click(function(){
var xObj = $(".xTest");
if(xObj.hasClass("hidden"))
{
xObj.removeClass("hidden").addClass("unhidden");
}
else
{
xObj.removeClass("unhidden").addClass("hidden");
}
});
DEMONSTRATION
Why don't your wrap all your divs inside another div?
http://jsfiddle.net/bDQt7/7/
it has more sense to have menu and items inside it (I guess you need anchors and not divs inside the menu div)
That way you don't need jquery if you still don't know what it is.
<div id='menu' class='hidden'>
<a href='#'>menu</a>
<a href='#'>menu2</a>
<a href='#'>menu3</a>
</div>

Categories

Resources