Simply jQuery problem - Hide / Show

Hi all

I basically have a class which shows the hidden text when the link is clicked, everything works but, my problem is when I click one link, all the hidden text gets shown instead of just the one that I’ve clicked. I’ve tried adding (this) but can’t seem to get things to work, where to put things.

<p>Some text here, some more text here.</p>
<p class="hidden-text">Some text here, some more text here.</p>
<p><a href="#" class="extra-reading"></a></p>

<p>Some text here, some more text here.</p>
<p class="hidden-text">Some text here, some more text here.</p>
<p><a href="#" class="extra-reading"></a></p>
$(document).ready(function() {
          $('.hidden-text').hide();
          
          $('.extra-reading').click(function() {
            $('.hidden-text').slideToggle('slow', 'linear');
            
            return false;
          });
        });

Thanks, Barry

The trick is that you have to tell jQuery specifically which element to slideToggle. The event listener is being attached to the <a> element, which means that “this” will refer to that <a>.

So the lame, hard-coded way to do it would be to go up to the element’s parent (the <p>), and then back to the previous sibling (the <p class=“hidden-text”>) using the “parent” and “prev” functions.

Thanks sdleihssirhc

I thought something like the below would do the job, no?

$('.extra-reading', this).click(function() {

I’m hoping to create a function so I can just add .extra-reading to any element in the DOM and the hide/show will work.

Can you supply an examples?
What do you think?

Many thanks.

The second argument in the jQuery function is for the context of the selector. It’s supposed to be a DOM element, or a Document, or even another jQuery object.

The “this” that you’re looking for is inside the click event listener:


$('.extra-reading').click(function () {
    $(this).parent().prev().slideToggle('slow', 'linear');
    return false;
});

But keep in mind that it assumes the corresponding “hide-text” element is always going to be the previous sibling of the link’s parent.

Thanks, having some strange effects.
I’ll have to keep trying to understand the code and see if I can figure this out.

Cheers

Ok, I’ve got this far.
This no works and toggles the individual element, but its removing the link not showing the hidden text.
Kind of back to front.
Any suggestions?

$(document).ready(function() {
          $('.hidden-text').hide();
          
          $('.extra-reading').click(function () {
            $('.hidden-text');
            $(this).slideToggle('slow', 'linear');

            return false;
            });
        });

Thanks, Barry

The line “$(‘.hidden-text’);” doesn’t do anything: it creates a jQuery object, but you don’t assign it to a variable or do anything with it, so nothing happens.

The next line is closer, but not quite it. Inside this event listener, like I said earlier, “this” refers to the <a> element that you just clicked. So “$(this)” creates a jQuery object with that <a>. But you don’t want the <a>: You want the sibling of the <a>'s parent.

Again, try using the “parent” and “prev” functions.

Ok.

$('.hidden-text').hide();
          
          $('.extra-reading').click(function () {
            $(this).parent().prev().slideToggle('slow', 'linear');

            return false;
            });

The first link does not work and the second link works but removes the <h2> element further up the page, instead of showing the hidden text ?
As before, isn’t there a way of creating a function without the parent().prev() so I can add this to any element?
Thanks again.

Can you post a link to a live example? I made a jsFiddle that uses your original HTML and your latest JavaScript, and it works. So my guess is your actual HTML is slightly different, somehow.

(Full disclosure: It’s not quite your original markup; the links had no text, so there was no to click them.)

thanks a lot, just tested your code on jsFiddle seems like a good example, is jsFiddle a testing platform?

I’m running things locally but here is my html, you’ll see what I mean when you run this in jsFiddle about the <h2>
I have the hidden-text in two different places, while I was testing for the best position, must have something to do with the parent() prev()


<h2><a href="/">title 1</a></h2>
<p>Simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
<p class="hidden-text">hidden text to show here</p>
<p><a href="javascript;" class="extra-reading">read more..</a></p>
             
<h2><a href="/">title 2</a></h2>
<p>Simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.  <a href="javascript;" class="extra-reading">read more..</a></p>
<p class="hidden-text">hidden text to show here</p>

Appreciate your help sdleihssirhc

And that brings me to, if this only works with parent() and prev() how could I set this up so I can use it on any element so it doesn’t conflict like the <h2> issue?

I was afraid of that. If you really want something stable, something you can put literally anywhere on the page, then forget about searching through the DOM. Even if it worked, it wouldn’t be pretty.

The easiest way is to just explicitly link the two elements together. The paragraph of hidden text will have an id, and the link that reveals that paragraph will have an attribute that is set to that id. Does that make sense? Here’s an example:


<p class="hidden-text" id="someUniqueId">blah blah blah</p>
<a href="javascript;" class="extra-reading" data-for="someUniqueId">read more..</a>

(In the example, I used “data-for”. But you can call it just about anything you want. The “data-” prefix is an HTML5 solution for an essentially non-existent problem, but this is one such instance. If you wanted, you could even make up your own attribute name; you just wouldn’t have valid HTML.)

Then, when any “.extra-reading” link is clicked, this is all your JavaScript has to do:

  • get the “data-for” attribute (or whatever groovy name you gave it) off the link
  • slideToggle the element that has that id

The advantage to this technique is that you can put the link and the paragraph anywhere. Anywhere. They don’t even have to be next to each other. And it’ll still work! Much better.

[QUOTE=sdleihssirhc;4995771]The easiest way is to just explicitly link the two elements together. The paragraph of hidden text will have an id, and the link that reveals that paragraph will have an attribute that is set to that id. Does that make sense? Here’s an example:


<p class="hidden-text" id="someUniqueId">blah blah blah</p>
<a href="javascript;" class="extra-reading" data-for="someUniqueId">read more..</a>

Here’s an idea, make use of the href attribute instead, so that you end up with more robust HTML code too.


<p class="hidden-text" id="someUniqueId">blah blah blah</p>
<a href="#someUniqueId" class="extra-reading">read more..</a>

Additionally, if you don’t use CSS to hide it then it don’t be forever invisible to those not using scripting. Instead, you can use JS to hide that content instead.

Thanks guys.
been a busy night for myself so will have to look more into this tomorrow.

Although, I do have things working ok, showing the hidden text from above the anchor prev() and below next(), some wrapped in <div> (for bigger partitions).
The idea was to create one function and simply apply the class to whatever element I needed the functionality on.

I didn’t really want to create a load of different IDs so at present this solution seems to be good.

forget about searching through the DOM. Even if it worked, it wouldn’t be pretty.
loading time?

And thanks Paul, yes, if javascript is disabled everything will be shown, just a bit more bulky.

Learned a lot tonight, thank you.

in practice i use stuff like

<p id=“p211” onclick=“toggleView(‘p211’);”><img height=“200px” width=“auto” src=“http://cdn.zmescience.com/wp-content/uploads/2011/03/penguin.jpg” /></p>
<p id=“p212” onclick=“toggleView(‘p212’);”><img height=“200px” width=“auto” src=“http://images.paraorkut.com/img/pics/images/m/march_of_the_penguins-12130.jpg” /></p>

function toggleView(id) {
$(“#”+id).toggle();
};