Topic: Displaying flash messages

Hi,
I have the following code in application_helper:

module ApplicationHelper
  def flash_show_error
    if flash[:error]
      "<div id=\"error\" > #{flash[:error]}</div>"
    end
  end
 
    def flash_show_notice
    if flash[:notice]
      "<div id=\"notice\" > #{flash[:notice]}</div>"
    end
  end
end

As you can see I have 2 types of messages - error messages, and regular notices.
Is there a way to refactor the 2 functions into one?

Maybe something like

def show_message type
    if flash[:error]
      "<div id=\"type\" > #{flash[:type]}</div>"
    end
end

Re: Displaying flash messages

Something like

def show_message flash_type
 
  "<div id=\"type\" > #{flash[flash_type.to_sym]}</div>" if flash[flash_type.to_sym]

end

def show_flash

  show_message('error')
  show_message('notice')

end


perhaps. Not tested...

Re: Displaying flash messages

def show_flash
  [:notice,:error].each do |type|
    content_tag(:div, flash[type], :class => type) if flash[type]
  end
end

# Usage
<%= show_flash %>

Re: Displaying flash messages

Thanks.
I like Duplex's way. Very clean.
BTW, is there a way to define collections outside methods? say I want something like

flash_types = Collection.new[:notice,:error]

Than I can use flash_types wherever I needed, which will make this much easier to expand.

Re: Displaying flash messages

just define a constant e.g. in your envronment.rb file (outside of the config...end block)

FLASH_TYPES = [:notice,:error]

- Capital start letter means it's a Constant. By convetion, the whole Constant is written in Capitals.
- it's not Collection.new, you simply use an array wink

Re: Displaying flash messages

Cool.
Thanks.

Re: Displaying flash messages

satanir wrote:

I like Duplex's way. Very clean.

Me too. We are not worthy... #smile#

Re: Displaying flash messages

Strange thing is happening...

def display_flash
  FLASH_TYPES.each do |type|
    content_tag(:div, flash[type], :class=>type)
  end
end

I omitted the 'if flash[type]' on purpose.

what I get in the HTML is the text 'noticeerror'.
No divs, no flash, no nothing. I removed the content_tag and left an empty block and got the same result.

Any idea as to what's wrong?

Re: Displaying flash messages

You left off the 'if' statement modifier...

Re: Displaying flash messages

specious wrote:

You left off the 'if' statement modifier...

I know. I did it on purpose. That should generate 2 divs unconditionally, but instead it produces text.
Adding the 'if' doesn't solve it, anyway.

Re: Displaying flash messages

OK. I got it to work.

module ApplicationHelper
  FLASH_TYPES = [:notice, :error]
 
  def display_flash
    flash_tag = ""
    FLASH_TYPES.each do |type|
      flash_tag += content_tag(:div, flash[type], :class=>type) if flash[type]
    end
    flash_tag
  end
end

content_tag doesn't write directly to the HTML... I didn't tell this function to return anything, so I'm guessing by default it returned 'noticeerror'.
Saving the results of 'content_div' into 'flash_tag' solved it.

Re: Displaying flash messages

a method can only have one return value, therefore this won't work. i don't see why it actually produces this concanated string, my best guess is that content_tag maybe returns nil when you do't specify any content, so if the flash is empty, the block returns nothing, and therefore the return value is the FLASH_TYPES array itself. and printing an array results in this type of concanated string.

You would have to do something like this:

def display_flash
  res = ""
  FLASH_TYPES.each do |type|
    res << content_tag(:div, flash[type], :class=>type)
  end
  res
end

Re: Displaying flash messages

Here is the way I deal with flashes.
I setup the notifications method in my ApplicationHelper.rb file

module ApplicationHelper
def notifications
  if flash[:success]
    render :partial => 'layouts/success', :object => flash[:success]
  elsif flash[:notice]
    render :partial => 'layouts/notice', :object => flash[:notice]
  elsif flash[:error]
    render :partial => 'layouts/error', :object => flash[:error]
  end
end
end

Then I have my partials handle the view.
 
# layouts/_success.erb
<span class="success"><%= success %></span>

# layouts/_error.erb
<span class="failure"><%= error %></span>

# layouts/_notice.erb
<span class="notice"><%= notice %></span>

Then I have my application layout render the notification like so:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
</head>
<body>
<div id="main"> 

<%= notifications %>

<%= yield  %>
</div>
</body>
</html>

Last edited by Lake (2008-06-26 12:44:26)

Re: Displaying flash messages

Remember you can treat the flash as a normal hash and iterate through it, you don't need to define each type in a constant:

res = ''
flash.each {|type, message| res << content_tag(:div, message, :class => type) }

Last edited by mipr (2008-08-27 19:16:22)