views:

52

answers:

5

http://jsfiddle.net/M6xdq/

What I want to achieve, is - when user clicks the "read more" link:

  1. it's removed
  2. changes it's label to "read less"
  3. this new "read less" link is added to next element of it's parent (readmore_holder)
  4. "readmore_holder" is displayed;

Then there should be the other part with "read less" to swap links back again and to hide readmore_holder, but since I cannot even get the alert() to show up, I'm kinda lost.

What is the problem here?

P.S. If there are ways of simplifying this snippet, would really appreciate it.

Thanks in advance!

EDIT: Code from jsFiddle example.

$('.readmore_holder').hide();
$('.readmore_holder').prev().append(' <a href="javascript:void(0);" class="toggleon">read-more</a>');

$('.toggleon').click(function() {     
    $(this).parent().next().append(' <a href="javascript:void(0);" class="toggleoff">read-less</a>');
    $(this).parent().next().fadeIn();        
    $(this).remove();        
});

$('.toggleoff').click(function() {
    alert('works!');
});​

HTML

<p>Headline is right here</p>
<p class="readmore_holder">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas eget suscipit ante. Pellentesque egestas varius dolor, sit amet blandit erat luctus quis. Nunc semper odio a orci vulputate ut pulvinar mi consequat. Praesent molestie accumsan velit, nec vehicula velit mattis vitae. Proin libero mauris, ultrices eu congue quis, sollicitudin et eros. Phasellus tortor mauris, imperdiet in euismod ut, tempor id ante.</p>​
+6  A: 

You need to use the live() method for the dynamic generated content. See the working demo here

Sarfraz
Oh, nice, never knew there is such a method! +1, thanks!
Tom
@Tom: Welcome...
Sarfraz
A: 

It doesn't work because the toggleoff elements doesn't exist yet when you try to bind the click event to them.

Create the toggleoff elements from the start:

$('.readmore_holder').hide();
$('.readmore_holder').prev().append(' <a href="javascript:void(0);" class="toggleon">read-more</a>');
$('.toggleon').parent().next().append(' <a href="javascript:void(0);" class="toggleoff">read-less</a>');

$('.toggleon').click(function() {     
    $(this).parent().next().fadeIn();        
    $(this).hide();        
});

$('.toggleoff').click(function() {
    alert('works!');
});

I also changed remove to hide to get rid of the read-more link. That way you can just show it when you hide the text instead of recreating it.

Guffa
A: 

Quite simple mistake: when you assigned the click handler for the "read less", it did not yet exist and therefore was not assigned. Just move the assignment into the click handler.

To clean up the code a little, have a look:

$('.readmore_holder').hide().prev().append(' <a href="javascript:void(0);" class="toggleon">read-more</a>');

$('.toggleon').click(function()
{     
    $(this).parent().next().fadeIn();        

    $(this).parent().next().append(' <a href="javascript:void(0);" class="toggleoff">read-less</a>').click(function() {
        alert('works!');
    });
    $(this).remove();
});
Steffen Müller
A: 

Here's my advice. Don't remove the link. Just change the text and modify the code to handle both situations.

This will be much more efficient.

Example: http://jsfiddle.net/M6xdq/14/

$('.readmore_holder').hide()

    .prev().append(' <a href="javascript:void(0);" class="toggle">read-more</a>')

    .find('.toggle').click(function() {
        $(this).text(function(i,txt) { 
           var more = (txt === 'read-more');
            if(more)
                $(this).parent().next().append(this).fadeIn();
            else
                $(this).parent().fadeOut().prev().append(this);
            return (more) ? 'read-less' : 'read-more'; 
        });       
    });​

Or this one where both links are create and .show() and .hide() are used. Either solution would be preferable to destroying and creating the same element.

Example: http://jsfiddle.net/M6xdq/15/

$('.readmore_holder').hide()
        .append(' <a href="javascript:void(0);" class="toggleoff">read-less</a>')
        .find('.toggleoff')
        .click(function() {
             $(this).hide().parent().fadeOut().prev().find('.toggleon').show();
        })

        .parent().prev()
        .append(' <a href="javascript:void(0);" class="toggleon">read-more</a>')
        .find('.toggleon')
        .click(function() {
             $(this).hide().parent().next().fadeIn().find('.toggleoff').show();
        });​
patrick dw
This isn't changing the links position, which is a must in my case. But I've already found a solution, built my script and it's working.
Tom
Fixed the position. Even though you found a solution, I'll leave this here for a while. Seems wasteful to destroy and create elements that you can just move. jQuery's `.live()` lets you get away with it. Also added another solution where you create both links, and just show/hide them.
patrick dw
A: 

Maybe you can try make it different way. jQuery .toggle() function can take 2 (or even 3) function handlers as arguments. After first click first function is called, and after second click, second function is called. So you could do something like:


<style>
.readmore_holder { display: none; }
</style>
...
<p>head line</p>
<p class="readmore_holder">some text</p>
<a href="javascript:void(0)" class="toggle">read more</a>

<script type="text/javascript">
$("a.toggle").toggle(function(){
  $(this).html("hide");
  $(this).prev("p").show();  //for better effect you can use slideDown() here
}, function(){
  $(this).html("read more");
  $(this).prev("p").hide();  //for better effect you can use slideUp() here
});
</script>
Ventus