jQuery hiding and toggling - javascript

I have multiple rows of article and inside it I have .article-row with .content inside it and then .article-row is clicked. the current jQuery will find the .content and then toggle it. But I would like to change the code so that it would .hide() all instances of .content that are not related to the clicked one
$('.article-row').click(function(){
$(this).parent().find('.content').toggle();
});
<article class="feed1 entry">
<span class="article-row">
<span class="article-row-title">I am the title</span>
<span class="article-row-date">Sat, 07 Sep 2013 02:13:35 -0700</span>
</span>
<div class="content">
<p>I AM THE CONTENT</p>
</div>
</article>
Link Here

$('.article-row').click(function(){
if($(this).parent().find('.content').is(':visible')){
$('.content').hide();
$(this).parent().find('.content').show();
}
});
Hide all elements, then display the clicked one. But first verify if the clicked article is not already the active one to make sure it doesn't flicker or look weird if you animate the transition.

$('.article-row').click(function(){
if($(this).parent().find('.content').is(':visible')){
$('.content').hide();
}else{
$('.content').hide();
$(this).parent().find('.content').show();
}
});

Wouldn't be cleaner this way?
$('article.entry').on('click', '.article-row', function () {
$(this).siblings('.content').show();
$('.content').hide();
});

Related

Using classes instead of IDs

I have two divs in my parent class, one of which is found by $(this).parent('div').next('.deal-rolldown').show(); the other, $(this).parent('div').next('.client-rolldown').show(); does not find what appears to by syntactically equal.
In WordPress I iterate an (unknown) number of posts, each has 2 buttons to reveal more content. Up to now I have run a document ready function in each iteration to address each reveal by IDs but this is inefficient.
So I am trying to write a function using classes. Here's the JavaScript
$('.deal-link').click(function() {
$('.deal-rolldown').hide(); // hide all
$('.client-rolldown').hide(); // hide all
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
$(this).next('.deal-rolldown').show();
}
});
$('.client-link').click(function() {
$('.client-rolldown').hide(); // hide all
$('.deal-rolldown').hide(); // hide all
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
$(this).next('.client-rolldown').show();
}
});
Which is operating on this HTML
<div class="company">
<div class="company-inner">
<h2>Company 1 </h2> Company 1 Summary
</div>
Deal summary
Client review
</div>
<div style="display: none;" class="deal-rolldown">
Company 1 reveal 1 content
</div>
<div style="display: none;" class="client-rolldown">
Company 1 reveal 2 content
</div>
<div class="company">
<div class="company-inner">
<h2>Company 2 </h2> Company 2 Summary
</div>
Deal summary
Client review
</div>
<div style="display: none;" class="deal-rolldown">
Company 2 reveal 1 content
</div>
<div style="display: none;" class="client-rolldown">
Company 2 reveal 2 content
</div>
The addClass('active') works fine so I know I am getting the right button, but the next() function does nothing. No errors. How can I select the appropriate reveal from each button?
Edit following closure: this is a different question to the one marked as duplicate.
First thing, instead of doing
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
You can use $(this).toggleClass('active');
Your problem is that next() returns the immediately following sibling, and .deal-rolldown is not a sibling of your .deal-link element.
What you want to do is
$(this).parent('div').next('.deal-rolldown').show();
The next() function gets the immediately following sibling that matches the selector. The div with class '.deal-rolldown' is NOT a sibling of the '.client-link' or '.deal-link' links. I would suggest using .closest('.deal-rolldown') instead of .next() which will find the closest matching element by traversing up through the current item's ancestors.

jQuery .slideToggle() to also close other tabs

I have two sections, each with 3 divs, opening on slideToggle. How can I close the other 2 divs in each section when 1 is open?
https://jsfiddle.net/koteva/mdx20uqe/2/
<div id="stage1">
<h2 id="location-1">Location</h2>
<div id="location-1t">grjryjj</div>
<h2 id="jersey-1">JERSEY </h2>
<div id="jersey-1t" style="display: none;"> ighlgkiuluil </div>
<h2 id="details-1">details</h2>
<div id="details-1t" style="display: none;">fykyuk </div>
</div>
<div id="stage2">
<h2 id="location-2">Location2</h2>
<div id="location-2t">grjryjj</div>
<h2 id="jersey-2">JERSEY2 </h2>
<div id="jersey-2t" style="display: none;"> ighlgkiuluil </div>
<h2 id="details-2">details2</h2>
<div id="details-2t" style="display: none;">fykyuk </div>
</div>
With your jsFiddle, you could replace all your js code with
$('h2').click(function(event){
var $this = $(event.target),
id = $this.attr('id');
if($('#'+id+'t').is(':visible')){ // To not slide up and down if clicking an already open element.
$this.parent().children('div').slideUp();
} else {
$this.parent().children('div').slideUp();
$('#'+id+'t').slideToggle();
}
});
as seen in this jsFiddle. This hides the content inside the same stage when you click a header, assuming you follow the same naming convention throughout your entire html code.
I would however recommend, if you can, to perhaps clean up your html a little.
Look at this jsFiddle for an example.
Unless your code has to have your current structure, I would recommend refactoring it into using similar classes and as such be able to write cleaner code.
$('.header').click(function(event){
var $this = $(event.target);
$this.siblings().slideToggle();
$this.parent().siblings().children('.content').slideUp();
});
Would with the structure in the jsFiddle html provide you with the functionality you want.
If you want to do it in simple way. You can do it as follows. its just one function written. But it is simple and line of code will be increased
$( "#details-2" ).click(function() {
$( "#location-2t").hide( "slow");
$( "#jersey-2t").hide( "slow");
$("#details-2t").show("slow");
});
For more complex div structure and the Ids are in the same format as you have specified in your sample code following code will be very useful.
<script>
$(document).ready(function(){
$("div h2").click(
function() {
var thisId = $(this).attr("id");
$("#"+thisId+"t").show("slow");
$(this).siblings("div").not($("#"+thisId+"t")).hide("slow");
});
});
</script>

Select contents of div to fadeIn sequentially

I'm not sure the best way to word this, so hopefully this makes sense.
Currently, on my page, all my elements fadeIn on click. What I would like is for a few select elements in an id (#seqFade below) to fade in on their own when that parent fadeIn class is clicked.
I've figured out how to make both of these effects work on separate pages, but I can't figure out how to have them both occur on the same page / combine the two.
Here is more or less how my page is designed, and below is what I have so far for code.
HTML
<div id="content">
<div class="fadeIn">
<p>Hello</p>
</div>
<div class="fadeIn" id="seqFade">
<span>1</span>
<span>2</span>
<span>3</span>
</div>
<div class="fadeIn">
Bye.
</div>
</div>
SCRIPT
$(document).ready(function(){
//hides all fadeIns
$('.fadeIn').hide();
$(document).on('click',function() {
if('#seqFade') {
//sequential fadeIn function (works)
$('span').each(function(i) {
$(this).delay(i*300).fadeIn('slow');
});
}
//fadeIn on click (works)
$('.fadeIn:hidden:first').fadeIn('slow');
})
.click();
Thank you so much in advance.
JSfiddle of full page //
JSFiddle of both effects working
Try this, just add a class on hidden at the beginning for the spans
$(document).ready(function() {
var timeOuts = new Array();
var eT=200;
function myFadeIn(jqObj) {
jqObj.fadeIn('slow');
}
function clearAllTimeouts() {
for (key in timeOuts) {
clearTimeout(timeOuts[key]);
}
}
$(document).on('click',function() {
$('#seqFade span').hide().each(function(index) {
timeOuts[index] = setTimeout(myFadeIn, index*eT, $(this));
});
});
});
http://jsfiddle.net/h67vk02w/2/
HTML
<div id="content">
<div class="fadeIn">
<p>Hello</p>
</div>
<div class="fadeIn" id="seqFade">
<span>L</span>
<span>o</span>
<span>a</span>
<span>d</span>
<span>i</span>
<span>n</span>
<span>g</span>
<span>.</span>
<span>.</span>
<span>.</span>
</div>
<div class="fadeIn" id="bye">
Bye.
</div>
Javascript
$(function() {
$('.fadeIn').find('span').toggle();
$('#hello, #bye').toggle();
$(document).click(function() {
$('#hello').fadeIn('slow');
$('span').each(function(i) {
$(this).delay(i*300).fadeIn('slow', function() {
$(document).unbind('click')
.bind('click', () => $('#bye').delay(300).fadeIn('slow'));
});
});
});
});
JSFiddle: http://jsfiddle.net/6mLgu3om/3/
Or like that?
Use the classes for this (add some fade/noFade classes to elements). ID must be unique. And after that just check if the element has that class like this. Now you have basically unlimited options to do this. Just add more classes / check and do something.
$(".class_of_element").hasClass("your_class")

Jquery - How to prepend elemend before text in div?

I have a problem with my code in Jquery. I need to put one element before text in div. But it stays on same place. Can you help me ? Thank you very much.
Jquery:
$('.content_wrap img').each(function(){
if($(this).nextAll('.darkblue').length !== 0){
$('.darkblue').next('<div>').prepend($(this));
}
});
HTML:
<h2>
<img class="catIcon" alt="Software Maintenance Agreements" src="http://www.example.com/storage/images/article/21-80-3.jpg" style="padding-right: 10px;"> <!-- this is image i want to move before text -->
<a class="darkblue underline ui-link" href="http://www.example.com/gb/en/2099_software-maintenance-agreements-sma.html?do=article">Software Maintenance Agreements (SMA)</a>
</h2>
<div>
Software Maintenance A...roups at a fixed rate. <!-- element should appear before text -->
<a class="small ui-link" href="http://www.example.com/gb/en/2099_software-maintenance-agreements-sma.html?do=article">[more..]</a>
</div>
Try
$('.content_wrap img').each(function () {
$(this).prependTo($(this).parent().next())
});
Demo: Fiddle
If you want to check whether the next element has the class darkblue then
$('.content_wrap img').each(function () {
var $this = $(this);
if ($this.next().hasClass('darkblue')) {
$this.prependTo($this.parent().next())
}
});
Demo: Fiddle
why not just try
$("div").prepend($this)
if that's the only div in your file.
You need to find the parent of nextblue (the h2) then find the next div:
$('.content_wrap img').each(function(){
if($(this).nextAll('.darkblue').length !== 0){
$('.darkblue').closest("h2").next('div').prepend($(this));
}
});
You need to find it's parent's next div not it's next div:
$('.content_wrap img').each(function(){
if($(this).nextAll('.darkblue').length !== 0){
$('.darkblue').parent().next().prepend($(this));
}
});
working Solution: http://jsfiddle.net/avi_sagi/P6LhK/
The <h2> must be inside <a> tag. I checked with the Updated code its fine
<div class="content_wrap">
<img class="catIcon" alt="Software Maintenance Agreements" src="http://www.example.com/storage/images/article/21-80-3.jpg" style="padding-right: 10px;">
<a class="darkblue underline ui-link" href="http://www.example.com/gb/en/2099_software-maintenance-agreements-sma.html?do=article">
<h2>Software Maintenance Agreements (SMA)</h2>
</a>
<div>Software Maintenance A...roups at a fixed rate.
<a class="small ui-link" href="http://www.example.com/gb/en/2099_software-maintenance-agreements-sma.html?do=article">[more..]</a>
</div>
try this
$('.darkblue').parent("h2").next("div").prepend($(this));

How do I use a function argument for this jquery code, or is there a better solution?

I have about 50 p tags and next to these are again 50 divs. on click of each p tag, its div should be shown and the rest hidden. How do i acheive this. I can use something like below:
$(function() {
$('.p1').click(function(){
$('.div1').show();
$('.div2','.div3','.div4','.div5','.div6',.........,'.div50').hide()
})
$('.p2').click(function(){
$('.div2').show();
$('.div1','.div3','.div4','.div5','.div6',.........,'.div50').hide()
})
//////////////
//////
})
but as you see that this is not an effiecient solution. I am also not sure how the jquery each can be leveraged here or how can this implementation be done using arrays. Can somebody point me in the right direction. I think we should use a function and pass that no. as a parameter, but I dont know how to use custom functions in jquery.
UPDATE:
This is what I have done
$(function() {
$('.p1').click(function() {
$('.div').hide();
$('.d1').show();
})
})
I have added the class div to all of my 50 divs and I am showing d1 on click of p1. Now how do I replace 1 for each instance till 50.
I would have a common class to all div and p so that the binding the handler and the hide can be simple. And for the div, I would associate a data-tag to each p to link each p tag to div
<p class="p1 pclass" data-showdiv="div1">
...
</p>
<p class="p2 pclass" data-showdiv="div2">
..
<div class="mydiv div1" ..>
..
</div>
<div class="mydiv div2" ..>
..
</div>
And the script would be,
$(function() {
$('.pclass').click(function(){
$('.mydiv').hide();
$('.' + $(this).data('showdiv')).show();
});
});
As Jason told,
Use this
$('p').click(function() {
$('div').hide();
$(this).next('div').show();
});
If the div is next to each paragraph.
But, if there's an element between p and div, it wont work.
For you problem, you can do,
$('p').click(function() {
$('div').hide();
var divClass = $(this).attr("class").replace('p','div');
$('.' + divClass).show();
});
provided you have only p1, p2 .... in paragrah classes ;)
Update
See this fiddle
Notice , we have <br> tags between <p> and <div> as you wanted.
Assuming your HTML structure is
<p>Some text</p>
<div>More text to hide and show</div>
<p>Some text</p>
<div>More text to hide and show</div>
<p>Some text</p>
<div>More text to hide and show</div>
....
Use the following in your $(function(){}); method:
$('p').click(function() {
$('div').hide();
$(this).next('div').show();
});
var dvs = ['.div1','.div2','.div3','.div4','.div5','.div6',.........,'.div50'];
$('p').click(function() {
var index = parseInt(this.className.replace('p','')) - 1;
$(dvs[index]).show();
$(dvs.join(', ')).not(dvs[index]).hide();
});
The jQuery click event will automatically be registered on all elements that match the selector, so you shouldn't have to use the each() method. I would suggest having two CSS classes to distinguish between elements that have this toggling behaviour and elements that are primary (i.e. should be shown when their parent is clicked).
The markup:
<body>
<p class="togglable">
<div class="primary">
This is the primary div that will be shown when our parent is clicked.
</div>
<div>Regular div child</div>
<p>Nested paragraph</p>
<ul>
<li>A list perhaps</li>
</ul>
</p>
<p class="togglable">
<div class="primary">
This is the primary div that will be shown when our parent is clicked.
</div>
<div>Regular div child</div>
<p>Nested paragraph</p>
<ul>
<li>A list perhaps</li>
</ul>
</p>
<p>This is a normal paragraph</p>
</body>
The code:
$(function () {
$('.togglable').click(function () {
// hide all our children
$(this).children().hide();
// now only show our primary chlid
// NOTE: we pass 'this' as the second argument
// so that the selector will only apply to the
// children of the element that was clicked
// (i.e. we are providing a custom context for the selector).
$('.primary', this).show();
// You could even use the position of the child as well:
// $(this).children().first().show();
// This will show the first child element.
});
});
In this example all elements with the class togglable will show their primary child element when clicked and hide all other child elements.

Categories