Newbie question - how do I hide/show a div using pure rails?

Right now I’m using this in one of my views:

<% if @isopen %><% end -%>Project name:<% if
@isopen %>
<% end -%>

but having two sets of if/end makes me think that there might be a
better way to be doing this. Unfortunately, I’ve scoured the Rails API,
and I can’t find/figure out the syntax for a “link_to_function” that
uses scriptaculous effects. All there is is a link to the Scriptaculous
page “for more information.”

On the Scriptaculous page, everything is in Javascript, which I already
have covered.

How could I be writing this better?

Thanks!

lookup RJS tutorials with show/hide or toggele.

all you need is a div and in your RJS file something like

page.replace_html ‘project_div’, scriptaclous.Effect.Toggle

or something like that.

Hi Sean,

You could put something like this in you application helper; based on
the condition, it will wrap what’s in the block with your anchor tags.
The key is concating something to the block binding.

def link_if(condition, &proc)
if condition
start_anchor = ‘
end_anchor = ‘

concat(start_anchor, proc.binding)
yield
concat(end_anchor, proc.binding)
else
yield
end
end

Then in your view you’d put this:

<% link_if @isopen do %>
Project name:
<% end %>

That’s a lot cleaner.

Jim

On Jun 1, 2:18 am, Sean C. [email protected]

Great example, Rob. I’ve been trying to make my helpers more generic
lately - your sample code is instructive.

Thanks,
Jim

On Jun 2, 2007, at 11:40 AM, Jimtron wrote:

but having two sets of if/end makes me think that there might be a

def link_if(condition, &proc)
end
Jim
Or put something a lot more general in your helper:

descended from the union of link_to_unless and link_to_function

Since link_to_unless/link_to_if yield to a block if the link isn’t

being

produced, but the link_to_function allows a block to define the

function as

with a “render :update do |page| … end”, there’s a conflict in

what to use

a block for in this link_to_function_if.

I’m going to follow the link_to_function style since it can so much

more

quickly get ugly trying to properly quote a large javascript function.

Usage:

link_to_function_if(condition, name, function=‘’, html_options={})

do |page| … end

The href attribute of the link defaults to ‘#’, but can be

overridden by an

:href in the html_options. If the options contain an :onclick, it

will

preceed the function supplied as an argument or by the block. The

block

take precedent over the function given as an argument.

def link_to_function_if(condition, name, *args, &block)
if condition
html_options = args.last.is_a?(Hash) ? args.pop : {}
function = args[0] || ‘’

 html_options.symbolize_keys!
 function = update_page(&block) if block_given?
 content_tag('a', name,
   html_options.merge({ :href => html_options[:href] || '#',
     :onclick => (html_options[:onclick] ? "#{html_options

[:onclick]}; " : ‘’) + “#{function}; return false;”
})
)
else
name
end
end
END

Then in your view you could have:

<%= link_to_function_if @isopen, ‘Project name:’ do |page|

page.visual_effect :toggle_appear, :edit_project_name, :duration => 0.5
end %>

Gives you this when @isopen == true

Project true:

and this when @isopen == false

Project false:

Still pretty clean, but a lot more useful if you need something
similar in other areas or more than once on a page.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

Wow. Fascinating stuff guys. You’ve given me something to study today.

I had thought that I was simply missing some parameter in the link
function to create the scriptaculous effect properly, but i guess the
problem was more complicated than that after all. Thanks alot!

OK. Quick questions for Jimtron:

In your def, you used concat in a way that I can’t quite figure out. I’m
assuming that you’re using the string concat and not the array one. The
Pickaxe book shows it being used with an object, i.e.
“string.concat(str)” etc. But in your function, you use it with nothing

  • no object. So what exactly gets concatenated to?

And why are there two arguments? I’m not really sure why proc.binding
equals “Project name:” in this case, but I’m guessing that’s what it
comes out to. So it seems like you would be repeating “Project name:”
three times? Assuming that “yield” also equals “Project name:”.

And “yield” just means whatever was inside the block when you called the
function, right?

On Jun 2, 2007, at 2:01 PM, jimtron wrote:

Great example, Rob. I’ve been trying to make my helpers more generic
lately - your sample code is instructive.

Thanks,
Jim

Jim,

You should try to take a look at the “Show Source” in the Rails
RDocs. While it can sometimes seem like you’re falling down a rabbit-
hole as little 3-5 line methods call other methods which call still
others, you can open up the source file and browse through it. Most
of the code is quite well written and it’s a great way to learn more
about Ruby.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

Hi Sean,

The concat method, as it is being used here, is just a way to add
something extra to what’s in the block.
If your method takes a block, then you can add an extra argument
prefixed with an ampersand (&proc
or &block etc) and it will be converted into a lambda so you can alter
it directly. A simple example
would be:

def add_foobar_if(condition, &block)
if condition
concat(“”, block.binding")
yield
concat(“”, block.binding)
else
yield
end
end

So if the condition is false then it does a normal yield:

<% add_foobar_if(false) do %>
hello!
<% end %>

=> hello!

but if the condition is true then we’ve wrapped the contents of the
block with opening and closing ‘foobar’ tags.

<% add_foobar_if(true) do %>
hello
<% end %>

=> hello

A nice little screencast about this very topic was posted today at

Jim