views:

180

answers:

1

I have a list of items with some details that I would like to reveal upon clicking a show/hide details link. after some experimenting, I've come across two issues.

  1. I'm having trouble making it so that the show/hide link only reveals the div of a specific item. right now, it is revealing all of the divs when clicking any of the show/hide links.

  2. Also, there has got to be a more elegant way to do this without doing a loop to generate a bunch of javascript. I looked into effect.multiple, but I'm not sure how to use it in this context.

some insight or pointing in the general direction would be greatly appreciated! Thanks!

here's the code for reference.

                    <script type="text/javascript">
      function show_details() {
            <% @posts.each do |b| %>
        Effect.BlindDown('details_<%= b.id %>', {duration:0.3});
        $('hide_details_link_<%=  b.id %>').style.display = 'inline';
        $('show_details_link_<%=  b.id %>').style.display = 'none';
        <% end %>
      }

      function hide_details() {
             <% @posts.each do |b| %>
        Effect.BlindUp('details_<%= b.id %>', {duration:0.3});
        $('hide_details_link_<%=  b.id %>').style.display = 'none';
        $('show_details_link_<%=  b.id %>').style.display = 'inline';
        <% end %>
      }
    </script>

 <ul id="posts">
  <% @posts.each do |b| %>
           <li>



    <div id="show_details_link_<%= b.id %>" style="display:inline;">
      <%= link_to_function "show details", 'show_details()' %>
    </div>

    <div id="hide_details_link_<%= b.id %>" style="display:none;">
      <%= link_to_function "hide details", 'hide_details()' %>
    </div>


    <div id="details_<%= b.id %>" style="display:none;">

      <p> <%= b.comments %></p>


    </div>



                    </li>
       <li><%= link_to b.title, {:action => 'show', :id => b.id} -%></li>

      <% end %>
     </ul>
A: 

It looks to me like all your show/hide links are calling the same function (show_details() etc), which shows/hides all posts (because of the loop), not specific ones. Rather than defining a function for each one a more elegant way to solve this would be something like this:

<%= link_to_function "show details", "Effect.BlindDown('details_<%= b.id %>', {duration:0.3});" %>

That's of course not unobtrusive, but it's a start.

EDIT

I just noticed your links that you want to showhide for each div as well. Well, you could throw that right after the Blind effect:

<%= link_to_function "show details", "Effect.BlindDown('details_<%= b.id %>', {duration:0.3});$('hide_details_link_<%=  b.id %>').style.display = 'inline';" %>

etc.

Or you could make a javascript loop in the document onload function which finds all the divs and binds a function to each of them, but that's getting more complex than I want to demonstrate, especially as you don't appear to be using Prototype (although you are using Scriptaculous? That should give you access to .show()/.hide() helpers...)

Also, why use the divs? You can but ids right on the links (see the options on link_to_function)

floyd