Rails 3.1 - Need to show a JS pop-up with the contents of a field - can it be easily done?

I have limited screen space for a table that I’m displaying, so I’m showing a truncated view of a description field:

<%= simple_format car.description.truncate(200, :separator => ' ') %>

I need a mouse over or click event to generate a simple pop up window (an “alert”, a “tool tip”, a “dialog”, etc.) displaying the full contents of the car.description field.

I’m an admitted JS rookie. All the JS-Rails tutorials/information that I’m seeing are focused on unobtrusive JS, focused mostly on AJAX/remote server interactions. I’m not seeing anything that helps understand how you can use data from your Rails application in rich JS UI features within your views. I saw a tool tip gem, but with that gem, tool tip content is statically generated, and tool tips are held in their own table. No way to generate a tool tip on the fly, based on a field pulled from the database.

Is there some very, very simple way to have JS pop up the text held in a Rails field?

What about fancybox? fancybox.net

I use it for simple pop-up’s

Javier Q

I have limited screen space for a table that I'm displaying, so I'm showing a truncated view of a description field:

  <td><%= simple_format car.description.truncate(200, :separator => ' ') %></td>

I need a mouse over or click event to generate a simple pop up window (an "alert", a "tool tip", a "dialog", etc.) displaying the full contents of the car.description field.

I'm an admitted JS rookie. All the JS-Rails tutorials/information that I'm seeing are focused on unobtrusive JS, focused mostly on AJAX/remote server interactions. I'm not seeing anything that helps understand how you can use data from your Rails application in rich JS UI features within your views. I saw a tool tip gem, but with that gem, tool tip content is statically generated, and tool tips are held in their own table. No way to generate a tool tip on the fly, based on a field pulled from the database.

Is there some very, very simple way to have JS pop up the text held in a Rails field?

If you use the Title attribute on the shortened example, you could get a poor-man's popup for free:

<td><span class="more" title="<%=simple_format car.description %>"><%= simple_format car.description.truncate(200, :separator => ' ') %></span></td>

Then you could layer over that some JavaScript to pull the title content into a rich popup if you like. But all alone, this will give you an accessible solution with minimal code. If you added some CSS to the .more class, you could change the cursor on mouseover to clue the user, or add some color or underline to make it really apparent.

Walter

Javier - Thanks for the suggestion on fancy box.net. Unfortunately, for me the challenge is that I do not understand the simple basics of how to use a JS library in my view. I understand that I need to load the JS library into my rails app by adding the library to: app/assets/javascripts/application.js , but once it is there, how do I access the library’s functions from within my view? Could you please post a snippet of html.erb code that shows how you’ve accessed a fancybox function in one of your views? Sorry to be asking what I know must be a very basic question, but I just can’t seem to find this documented anywhere.

Walter - this is a perfect work-around; thanks for the great idea. I’ll use it in the short term, until I can figure out my real issue. There is something very basic that I’m not getting/finding. How do I access JS libraries for enhancing my UI from within a html.erb view? If you can point me to any resources or code examples that would be great.

Don

>
> I have limited screen space for a table that I'm displaying, so I'm showing a truncated view of a description field:
> <td><%= simple_format car.description.truncate(200, :separator => ' ') %></td>
> I need a mouse over or click event to generate a simple pop up window (an "alert", a "tool tip", a "dialog", etc.) displaying the full contents of the car.description field.
> Is there some very, very simple way to have JS pop up the text held in a Rails field?

If you use the Title attribute on the shortened example, you could get a poor-man's popup for free:

<td><span class="more" title="<%=simple_format car.description %>"><%= simple_format car.description.truncate(200, :separator => ' ') %></span></td>

Then you could layer over that some JavaScript to pull the title content into a rich popup if you like. But all alone, this will give you an accessible solution with minimal code. If you added some CSS to the .more class, you could change the cursor on mouseover to clue the user, or add some color or underline to make it really apparent.

Walter

Walter - this is a perfect work-around; thanks for the great idea. I'll use it in the short term, until I can figure out my real issue. There is something very basic that I'm not getting/finding. How do I access JS libraries for enhancing my UI from within a html.erb view? If you can point me to any resources or code examples that would be great.

Don

You can add libraries to the application.html.erb outer template by defining content_for :head with the link, or you can simply apply that library to every page (it's a toss-up whether having it cached will be faster in the long run than loading the library on only the pages you need it)

<%= content_for :head, javascript_include_tag( 'your-library-name-here' ) %>

If this is the only view where you need this functionality, then you can simply add the JavaScript to call that library directly into your view, below the part of the HTML where you define the elements you're affecting. If you were to carry my example forward, and you were using Prototype (I don't know the jQuery equivalent off-hand), you could do the following:

< your table or list of elements here >
<script type="text/javascript">
if(!$('overlay')){
  $$('body').invoke('insert',new Element('div',{id: 'overlay',style: 'display:none;'}));
  $('overlay').insert(new Element('div',{id: 'message'}));
}
document.observe('click',function(evt){
  var elm;
  if (elm = evt.findElement('span.more')){
    $('message').update(elm.readAttribute('title'));
    $('overlay').show();
  }else if(elm = evt.findElement('#overlay')){
    elm.hide();
  }
});
</script>

Add some css to make this a proper 'dim out the page' overlay, and you're done. Or simply style it as a popup. That part is entirely up to how you want it to appear. If you wanted to kill the mouseover effect of showing the title as a browser tooltip, you could do a setup as the page loads to shuffle the title value off to a private variable on the span, and update your click observer appropriately.

$$('span.more').each(function(elm){
  elm.store('popup',elm.readAttribute('title');
  elm.writeAttribute('title',null);
});
document.observe('click',function(evt){
  var elm;
  if (elm = evt.findElement('span.more')){
    $('message').update(elm.retrieve('popup'));
    $('overlay').show();
  }else if(elm = evt.findElement('#overlay')){
    elm.hide();
  }
});

The benefit to this layered approach is that you don't hide anything from screen readers or Google.

Walter

Wow! Walter, thank you so much for taking the time to put all this together for me.

I’ve looked it over, and although my JS skills are meager at best, I believe I see the mechanism now. This is the piece of your code that helped me see the bridge between JS and my model data, namely ‘title’ :

if (elm = evt.findElement(‘span.more’)){
$(‘message’).update(elm.readAttribute(‘title’));
$(‘overlay’).show();
}else if(elm = evt.findElement(’#overlay’)){
elm.hide();
}

I don’t think I would have got it without seeing this code segment tied into my example. Thanks again. Very, very much appreciated.

Don

Wow! Walter, thank you so much for taking the time to put all this together for me.

Happy to help. Hope it works for you.

Walter