Showing posts with label modal. Show all posts
Showing posts with label modal. Show all posts

Wednesday, 5 September 2007

RedBox Rules!

Note: The RichText blog has moved to www.ricroberts.com

As you might have noticed from previous posts in this blog, I'm somewhat interested in modal dialogs in Ruby On Rails.

Up until now, I've been happily using the Prototype Window Class. However, it's quite a lot of js (a lot of which I don't use), and I've recently found a few small bugs in it. I'm not denying it's an impressive piece of work - it's just that there were a few niggles (Check out the forums).

Anyway, I've been investigating a few other options (namely: SubModal, ThickBox, LivePipe's Control.Modal, LightBox Gone Wild, StickyWin) and then I eventually found RedBox.

Most of the options I considered are variations on the LightBox theme, but RedBox stood out for me because of it's simplicity and ease of use with RoR. It doesn't do anything particularly fancy, but it ticked all my boxes (i.e. easily customisable, works well with Rails, small size of javascript, no obvious bugs).

It really couldn't be simpler to use RedBox with Rails.

To install the RedBox plugin, in Terminal just run:

script/plugin install svn://rubyforge.org/var/svn/ambroseplugins/redbox


...from your Rails project folder. This will stick stuff in your vendor folder. Then, from the vendor/plugins/redbox folder, you can run:

rake update_scripts


...to copy the files to the relevant places in your project. (i.e. the public/javascripts, stylesheets folders etc.).

Now all that's left is to stick the javascript and stylesheet links into your layout:

<%= stylesheet_link_tag 'redbox' %>
<%# we need to include prototype, etc... %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag 'redbox' %>


To create a link to a RedBox, you can use the helpers that the author provides, the most useful of which I found to be the 'link_to_remote_redbox' helper. This allows you to launch a RedBox with some content from another page. For example:

<%= link_to_remote_redbox("redbox",
:url => {:controller=>'my_controller', :action=>'my_action',
:id=>'my_id'}) %>


Then, in the resulting RedBox dialog, you need some way of closing the it. To just close is very simple...

<%= link_to_close_redbox "Cancel" %>


It's also pretty easy to get it to do stuff after closing. For example, you could call a rails action, via an ajax call...

<%= link_to_close_redbox "OK", {:onclick => remote_function(
:url => {:controller=>'my_controller', :action=>'my_action',
:id=>'my_id'},
:complete => "$('spinner').hide();",
:before => "$('spinner').show();")
} %>


If you want, the rails action could do some rjs to update some of the main page.
(Of course, you could use a similar technique to submit a form on the dialog too).

One of my additional requirements was to be able to guide the users through a two-step process, within the constrains of the modal dialog (something I found fiddly with other modal dialog solutions). Here's how I did this with RedBox...

<%# to link to another page inside RedBox %>
<%= link_to_remote( 'hello',
:url => url_for(
:controller => "my_controller",
:action => "my_action",
:id => "my_id"),
:update => 'modal_content', # the div used by default for the dialog
:complete => 'RedBox.setWindowPosition();'#make sure it's centered
) %>


Notice how I call the RedBox's setWindowPosition() function once the update is complete. This is because the new page being shown might be a different size to the first one, and although the dialog automatically resizes to fit the content (which is nice), it doesn't automatically recenter itself. (Without this step, the dialog's top-left corner just stays in the same position).



Digg Technorati del.icio.us Stumbleupon Reddit Blinklist Furl Spurl Yahoo Simpy

Please also visit the Swirrl blog

Tuesday, 10 July 2007

More on modal dialogs in rails

Note: The RichText blog has moved to www.ricroberts.com

Almost a year ago (blimey!), I posted about modal dialogs. For various reasons, the part of the application about which I wrote ended up being done a bit differently to how I described. I've recently had a lot more time to work on rails and the other day, I came across a different reason to use modal windows.

The Xilinus Prototype Window Library is now at version 1.3, and has some nice additions since I last used it. There is also a link to a rails helper for launching windows and dialogs, which although doesn't fully support all of the options, is a good point to build from.

Now, to finally answer Michael Kovacs's question from that original post, I found it handy to make use of the callbacks (onOK & onCancel for dialogs and closeCallback for windows) when dealing with ajax.

For example, suppose you want the user to impart some information in one of your modal dialogs. And then you would like to save this information and cause an update to a portion of the page from which you launched the dialog, as a result of what the user did...

One solution is, in the callback function, to interrogate the contents of the dialog for what the user entered (using prototype, say) and then call a remote_function to save the info to a database. This remote_function could then use rjs to update the original page.

The erb in your view to launch the dialog might look a bit like this...

<%=
url = (url_for :controller => 'my_controller', :action => 'dialog_action')
link_to_prototype_dialog(
"link text here",
{
#content
:url=>url,
:options=>{:method=>'get'}
},
'confirm', #dialog-kind
{
# dialog options
:className=>"alphacube",
:width=>680,
:height=>220,
:onOk="function(win)
{
val1 = $F('val1');
val2 = $F('val2');" +
remote_function(
:url => {:controller=>'my_controller', :action=>'do_something'},
:with => "'val1=' + val1 + '&val2=' + val2",
:complete => "$('spinner').hide();",
:before => "$('spinner').show();") +
";
return true; // remember to return true to allow the dialog to close
}"
}
%>



Note that in order to get this to work properly I had to tweak the rails helper to slightly to correctly format the generated javascript, but you get the general idea.

UPDATE: you might also want to try RedBox modal dialogs.



Digg Technorati del.icio.us Stumbleupon Reddit Blinklist Furl Spurl Yahoo Simpy

Please also visit the Swirrl blog

Saturday, 23 September 2006

let's get modal

Note: The RichText blog has moved to www.ricroberts.com

UPDATE 12 July 07: Check out this more recent post for more info on modal dialogs.

In the Ruby On Rails project on which I'm currently working, I felt the need to introduce the concept of a modal dialog box. This is a common requirement in traditional client-applications, in order to restrict a user's actions to a certain area of the screen. However, until the advent of Web 2.0 it has been tricky implement in internet-based applications.

I tried a few different approaches, but finally settled on using the Xilinus Prototype Window javascript libraries to help me out.

A bit of background...

In my project, I orginally had a table which contained links to allow the user to edit the (often complex) contents of some of the table-cells. The links would causethe user to be navigated away from the page, and so after they had finished doing their editing they would have to navigate back. This is all very well, apart from the fact that if we wanted the site to remember other values that the user had entered on the first page, it meant storing hoards of things in the session. I stuck with this approach for a while, but the more functionality I added to the page, the more work I had to put into maintaining state in the session. Something had to change!

My solution

1. First download the Prototype Window libraries from here. (I used version 0.96.2).

2. The download zip-file contains a bunch of folders. Put the window.js file from the javascripts folder into your rails project's public/javascripts folder. (You will also need the prototype.js file, but this should already be there for you if you generated your project from a skeleton). The stylesheets folder in the zip-file contains all the different themes that are demonstrated on the xilinus prototype window samples page. The styles that you want to use need to go into your rails project's public/stylesheets folder. (I made a window subfolder to keep things tidier).

3. So that your views can use the prototype window javascript, put a javascript include tag in the head of the appropriate layouts file. For the sake of this example, put it in the application.rhtml layout file.

<%= javascript_include_tag "prototype", "effects", "window" %>
Also put in a stylesheet link to the style of modal dialog log you want.
<%= stylesheet_link_tag "/stylesheets/window/default" %>
We're going to use some javascript later, so put a content_for_page_scripts tag in the head of the layout too.
<script type="text/javascript"><%=@content_for_page_scripts %></script> 

4. In the view from which you wish to launch the modal dialog, we need some javascript. Write a function, and put it inside a content_for page_scripts block. Here, the function launches a modal dialog containing the web page at the url passed in.
<% content_for("page_scripts") do -%>

function show_Array_Window(myUrl)
{
  win = new Window('window_id', {title: "Array", width:300, height:500, url:myUrl});
  win.setDestroyOnClose();
  win.showCenter();
}

<% end -%>

5. Now set up a link for the user to click on, and set the onclick event to the function we just wrote. In the example below, we're building up a table with a link to a different object in each row's cell. (If you just want a permanent link to a single modal dialog, you dont need to go to the trouble of building up a dynamic onclick string).
<table>
  <% for i in 0...@my_array.length do %>
    <tr>
      <td>
        <%=
          # other code here if you like
          "<a href = \"#\" onclick='show_Array_Window(
\"" + url_for(:controller => 'my_controller',
:action => 'my_Action', :id => i) + "\")'>
Go Modal!</a>"
        %>
      </td>
    </tr>
  <% end %>
</table>

6. You can now do whatever you want in the page that's shown. In my case, this involved allowing the user to edit the complex data structure that was represented by the object in the table.

... and that's it.

The advantage of using the Xilinus Prototype Window libraries over other modal dialog approaches like lightbox gone wild is that because you just point the dialog to a url, the page that is shown inside can include its own javascript. This allows you to do ajax stuff inside your dialog like it was any other rails page. (I wont go into the whole ajax thing here).



Digg Technorati del.icio.us Stumbleupon Reddit Blinklist Furl Spurl Yahoo Simpy

Please also visit the Swirrl blog