How do I toggle one element without the others with jQuery? - javascript

I was wonder how I can toggle one element without toggling others... I just don't want to do this every time:
HTML:
<div class="share-toggle as-1"></div>
<div class="audio-share as1">
<p>Some Text</p>
</div>
<div class="share-toggle as-2"></div>
<div class="audio-share as2">
<p>Some Text</p>
</div>
JS:
$('.as-1').click(function() {
$('.as1').slideToggle('fast');
});
$('.as-2').click(function() {
$('.as2').slideToggle('fast');
});
Is there a way to write this in short? pls help... thx

You can use jQuery to select all elements, which className contains a certain substring:
$('*[class*="as-"]')
This will select all Elements in the DOM (*), of which the className ([class=""]) has "as-" anywhere (*) in it.
And then you can use the Element passed as this to get the number of the element after the "as-" and toggle the wanted element:
$('*[class*="as-"]').click(function () {
let elemNum = this.className.match(/as-(\d+)/)[1];
$("as"+elemNum).slideToggle('fast');
});

I know you already accepted an answer, but anyway…
Here is, in my opinion, a better solution.
Why is that?
Only 3 lines of code, and not using any regex or partial class names…
See comments in my code for more details:
// You could use class^=[as-] to filter on the classes that start with as-,
// (the ^ would be better than a *, because more specific)
// But I suggest you to use the 'share-toggle' class, there's no need to complicate things here:
$('.share-toggle').on('click', function(){
// The following will get the .audio-share element that is after the element we just clicked,
// If your HTML structure is gonna stay well structured like this, it's the finest solution:
$(this).next('.audio-share').slideToggle('fast');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="share-toggle as-1">[ CLICK HERE ]</div>
<div class="audio-share as1">
<p>Some Text</p>
</div>
<div class="share-toggle as-2">[ CLICK HERE ]</div>
<div class="audio-share as2">
<p>Some Text</p>
</div>
I hope you will consider this answer.
And I hope it will help!

Related

jQuery: Select grandparent's h1 tag

I'm working within a really rigid framework (NetSuite) and there's a small section that I have direct control over which is the h3 and p text below. The structure is similar to this:
<div class="grandparent">
<h1>Title Text</h1>
<div class="otherstuff">Some text</div>
<div class="parent">
<h3>Text I have control over</h3>
<p>More text I have control over</p>
</div>
</div>
I want to hide the title text and the contents of '.otherstuff' for this page. There are multiple pages similar to this so I'm looking for a clean way of getting it done.
I've tried giving the h3 tag a class, then the following:
$('h3.myclass').parent().closest('h1').css('display','none);
and variations of that but without any luck. I've looked into the .parentUntil() function but I run into the same problem. I have no problem grabbing ancestor elements but run into trouble when trying to grab elements of those ancestors.
Can anyone help me out?
EDIT: Thank you everyone for your time and effort in answering my question. I really appreciate it!
Use closest() to traverse up to the grandparent
Use find() to select the desired elements
You can use hide() in place of css('display', 'none') as they are equivalent
var grandparent = $('.myclass').closest('.grandparent');
grandparent.find('h1, .otherstuff').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="grandparent">
<h1>Title Text</h1>
<div class="otherstuff">Some text</div>
<div class="parent">
<h3 class="myclass">Text I have control over</h3>
<p>More text I have control over</p>
</div>
</div>
I can think of two selectors that might work assuming you put .myclass back in.
$('.myclass').closest('.grandparent').find('h1').css('display','none');
or
$('.myclass').parent().siblings('h1').css('display','none');
have direct control over which is the h3
Try utilizing .parent() , .siblings()
$("h3").parent().siblings().hide(); // `$(".parent").siblings().hide();` ?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="grandparent">
<h1>Title Text</h1>
<div class="otherstuff">Some text</div>
<div class="parent">
<h3>Text I have control over</h3>
<p>More text I have control over</p>
</div>
</div>
You may use:
$('.myclass').closest('.grandparent').find('>h1,>.otherstuff').hide();
> is for direct descendant element.
closest() selects ancestors, what you want is siblings().
So:
$('.your_h3_class').parent().siblings('h1')
will return an array of h1 siblings of the parent div, and in your case the first item of that array is your h1.
And you can iterate through those and hide them (in case there is ever more than one)
If the title is always immediately before the div with the "otherstuff" class, then you could use this:
$('.otherstuff').prev('h1').css('display', 'none');
Documentation here: https://api.jquery.com/prev/

Selecting only one div of entire css class in jQuery

my goal is to show an overlay on a div when that div is hovered on. The normal div is called .circleBase.type1 and the overlay is circleBase.overlay. I have multiple of these divs on my page. When I hover over one .cirlceBase.type1, overlays show on every .circleBase.type1. How do I prevent this?
Here is some code:
HTML
<div class="circleBase type1">
<p class="hidetext">Lorem ipsum</p>
<hr size="10">
<strong class="gray hidetext">gdroel</strong>
</div>
<div class="circleBase overlay">
<p class="date">11/12/14</p>
</div>
and jQuery
$(document).ready(function(){
$('.overlay').hide();
$('.date').hide();
$(".circleBase.type1").mouseenter(function(){
$(".overlay").fadeIn("fast");
$('.date').show();
$('.hidetext').hide();
});
$(".overlay").mouseleave(function(){
$(this).fadeOut("fast");
$('.date').hide();
$('.hidetext').show();
});
});
Use $(this) to get current element reference and do like this:
$(".circleBase.type1").mouseenter(function(){
$(this).next(".overlay").fadeIn("fast");
$(this).next(".overlay").find('.date').show();
$(this).find('.hidetext').hide();
});
and:
$(".overlay").mouseleave(function(){
$(this).fadeOut("fast");
$(this).find('.date').hide();
$(this).prev(".circleBase").find('.hidetext').show();
});
usually when I want to target something specific you just give it an ID.
ID's play better in JavaScript than classes.
If you had a specific container, using the container as your starting point is a good route as well
$('#container').find('.something.type1').doSomething();
This is much more efficient for jquery, because it only searches .something.type1 inside of #container.
Well I'm not sure exactly what you're looking to do, but it looks like you want to replace content in some kind of circle with a hover text, but with a fade. To do that you'll have to add some CSS and it would be best to change your HTML structure too.
The HTML should look like this:
<div class="circleContainer">
<div class="circleBase">
<p>Lorem ipsum</p>
<hr>
<strong class="gray">gdroel</strong>
</div>
<div class="overlay" style="display: none;">
<p class="date">11/12/14</p>
</div>
</div>
so your js can look like this:
$(function(){
$(".circleContainer").mouseenter(function(){
$(this).find(".overlay")
$(this).find('.circleBase').hide();
});
$(".circleContainer").mouseleave(function(){
$(this).find('.circleBase').show();
$(this).find(".overlay").hide();
});
});
Here's a working solution that includes some CSS to make it nice. Try taking it out and running it, you'll see the problems right away.

jQuery: get a reference to a specific element without using id

I'm tinkering a bit with jquery to show a hidden div when a link is clicked. This should be fairly simple, but there's a flaw to it in this case. I have the following markup:
<div class="first-row">
<div class="week">
<p>Uge 2</p>
<p>(08-01-11)</p>
</div>
<div class="destination">
<p>Les Menuires</p>
<p>(Frankrig)</p>
</div>
<div class="days">4</div>
<div class="transport">Bil</div>
<div class="lift-card">3 dage</div>
<div class="accommodation">
<p><a class="show-info" href="#">Hotel Christelles (halvpension)</a></p>
<p>4-pers. værelse m. bad/toilet</p>
</div>
<div class="order">
<p>2149,-</p>
<p class="old-price">2249,-</p>
</div>
<div class="hotel-info">
<!-- The div I want to display on click -->
</div>
</div>
When I click the "show-info" link I want the "hotel-info" div to display.
My backend devs don't want me to use ids (don't ask me why..) and the above markup is used over and over again to display data. Therefore I need to be able to access the "hotel-info" div in the "first-row" div where the link is clicked.
I've tried to do something like:
$(document).ready(function() {
$('.show-info').click(function() {
var parentElement = $(this).parent().parent();
var lastElementOfParent = parentElement.find(".show-hotel");
lastElementOfParent.show();
});
});
But without a result :-/ Is this possible at all?
Any help is greatly appreciated!
Thanks a lot in advance!
Try this:
$('.show-info').click(function() {
$(this).closest('.accommodation').siblings('.hotel-info').show();
});
Even better imo, as it would be independent from where the link is in a row, if every "row div" has the same class (I assume only the first one has class first-row), you can do:
$(this).closest('.row-class').find('.hotel-info').show();
Reference: .closest, .siblings
Explanation why your code does not work:
$(this).parent().parent();
gives you the div with class .accommodation and this one has no descendant with class .hotel-info.
It is not a good idea to use this kind of traversal for more than one level anyway. If the structure is changed a bit, your code will break. Always try to use methods that won't break on structure changes.
You're right in not using an ID element to find the DIV you want :)
Use closest and nextAll
Live demo here : http://jsfiddle.net/jomanlk/xTWzn/
$('.show-info').click(function(){
$(this).closest('.accommodation').nextAll('.hotel-info').toggle();
});

jQuery: A shortcut to create a div container after a cue word

I'm creating a shortcut for a blog theme where I want to generate a div container around elements after using a cue word. For example, my blog entry would like this:
<div class="entry">
<p>First Paragraph</p>
<p>[box]</p>
<p>Second Paragraph</p>
<p>Third Paragraph</p>
</div> <!-- .entry -->
I'm hoping with some jQuery magic it could turn into this:
<div class="entry">
<p>First Paragraph</p>
<div class="box">
<p>Second Paragraph</p>
<p>Third Paragraph</p>
</div> <!-- .box -->
</div> <!-- .entry -->
One more rule: When I create a container box, I know I will always generate it before the closing div.entry. I'm hoping this restriction will make it easier to write the rules for jQuery. For example, I will never want the markup to look like this where there is content proceeding the div.box container:
<!-- I will never mark it up this way -->
<div class="entry">
<p>First Paragraph</p>
<div class="box">
<p>Second Paragraph</p>
</div> <!-- .box -->
<p>Third paragraph</p>
</div> <!-- .entry -->
I think your best bet is the jQuery :contains() selector.
With it you could do things like this (note: it matches any paragraph that has [box] in its HTML and maybe you need to escape the brackets):
$("p:contains('[box]')").wrap($('<div>').addClass('box'));
And btw. accepting answers and proving that you already put effort in your
problem will make it much more likely to get a helpful reply.
It will be something like this:
$("div.entry").append(
$("<div>").addClass("box").append("p:contains([box])+*");
);
$("p:contains([box])").remove();
See an example of the following here.
You can find the index() of the [box] paragraph and then wrapAll() the <p> after using :gt() to get all the parapgraphs following it:
var boxAt;
$('p').each(function(){
var $t = $(this);
if ($t.html() === '[box]') {
boxAt = $t.index();
$t.remove();
}
});
$('p:gt(' + (boxAt - 1) + ')').wrapAll('<div class="box">');
Thanks everyone for your help! It helped me also come up with another strategy that worked for me as well:
$('.entry p:contains([box])').each( function() {
$(this).prevAll().wrapAll('<div class="lefty">');
});
$('.entry p:contains([box])').each( function() {
$(this).nextAll().wrapAll('<div class="righty">');
});
$("p:contains([box])").remove();
What this does is create two separate boxes: 1. elements preceding [box], 2. elements proceeding [box]

How to loop though a jQuery result set

I'm trying to learn jquery and I'm having some difficulty figuring out how to deal with a set of jquery results. Let's say I have some html like:
<div class="divClass">
<p class="pClass1">1</p>
<p class="pClass2">Some text.</p>
</div>
<div class="divClass">
<p class="pClass1">2</p>
<p class="pClass2">Some text.</p>
</div>
<div class="divClass">
<p class="pClass1">3</p>
<p class="pClass2">Some text.</p>
</div>
I want to loop through the div's with a class of "divClass", get the value contained in the child p with a class of "pClass1". Getting the set of div's with a class of "divClass" is easy with something like:
divs = $(".divClass");
But I'm not sure how to loop through "divs" and find the "pClass1" child, then get its value. Any help would be much appriciated.
You can use the each method, and then, look for the '.pClass' elements, in the context of this, which is the currently div being iterated:
var divs = $(".divClass");
divs.each(function () {
alert($('p.pClass1', this).text());
});
Check the above example here.
Use the each method:
$(".divClass").each(function() {
});
There are lots of ways.
For your specific scenario, I would try something like this:
$(".divClass .pClass1").each(function() {
// Do whatever
});
If you wanted to do something with the div tags and the p tags, you could try the find method:
$(".divClass").each(function() {
var p1Tags = $(this).find(".pClass1");
});

Categories