Topic: Popup forms - can they be done in Rails / AJAX ?

I have up to a couple of hundred appointments on a calendar and each has a link that you can click.  The link leads to a separate screen with the appointment details on for you to create or change - but it looks a bit past its sell-by date!

I have looked at the interesting DOM popup kit from Stuart Rackham which uses AJAX and Rails to produce a popup form which can be updated.

The tricky thing is that I need just one popup element for all the Popup objects (because there are so many).  However, this means that all the Popup objects fire when I complete the form - the form belongs to them all.

My knowledge of Javascript is negligible and I'm happy with that!  Does anyone know roughly the direction to go in with Rails / AJAX - and, indeed, if this is possible at all?

Thanks

Mike

Re: Popup forms - can they be done in Rails / AJAX ?

This is definitely possible to do with JavaScript and shouldn't be too hard to implement. Without JavaScript, your only option is regular form in a frame or next page.

Re: Popup forms - can they be done in Rails / AJAX ?

I've tried to use the DOM popup kit with rails but for some reason it doesn't work with one of my applications and does with another. Has anyone worked extensively with it that might be able to answer some questions? I'll drop some code for you too.
Also I have another issue where I had some perfectly fine link_to_remote's working with a div to render a partial in the div but now they don't work at all. Is rails just selectively deciding when it wants to deal with AJAX and when it doesn't? I'm really confused about all of this.

Oh and popup.js is in public/javascripts and popup.css is in public/stylesheets.

Here's the code pertaining to the DOM kit:

my layout bus.html.erb header (that's the only part that's changed from the scaffold-generated layout)

<head>
    <title><%= h(yield(:title) || "Untitled") %></title>
    <%= stylesheet_link_tag 'physical', 'formtastic', 'formtastic_changes', 'popup', :cache => "base" %>
    <%= javascript_include_tag :all, :cache => "scripts" %>
    <%= yield(:head) %>
</head>

Now here's the page in question: _index.html.erb for the hardware controller:

<h2>Hardware</h2>

<table>
  <tr>
    <th>Cctr</th>
    <th>Person</th>
    <th>Cpu</th>
    <th>Ram</th>
    <th>Building</th>
    <th>Room</th>
  </tr>
<% @hardwares.each do |hardware| %>
  <tr>
    <td><%=h hardware.cctr %></td>
    <td><%=h hardware.person_id %></td>
    <td><%=h hardware.cpu %></td>
    <td><%=h hardware.ram %></td>
    <td><%=h hardware.building %></td>
    <td><%=h hardware.room %></td>
    <td><span id="hardware_link_<%= hardware.id %>" class="popup_link">Show</span><%= render :partial => 'hardwares/hardware_popup', :locals => {:hardware => hardware} %></td>
    <td><%= link_to_remote "Edit", :update => "hardware"+hardware.id.to_s, :url => {:action => "edit", :type => "Hardware", :id => hardware.id} %></td>
    <td><%= link_to 'Destroy', hardware, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
  <tr><td><div id='<%= "hardware"+hardware.id.to_s %>'></div></td></tr>
<% end %>
<tr>
  <td><%= link_to_remote "New Hardware", :update => "new_object_field", :url => {:action => "new", :type => "Hardware"} %></td>
</tr>
<tr>
  <td><div id="new_object_field"></div></td>
</tr>
</table>

And the final _hardware_popup partial (I've tried this with extensions .rhtml and .html.erb - I think Rails 2.3.8 likes .erb)

<div id="hardware_popup_<%= hardware.id %>" class="popup" style="display:none">

  <b>Cctr:</b>
  <%=h hardware.cctr %>



  <b>Person:</b>
  <%=h hardware.person_id %>



  <b>Cpu:</b>
  <%=h hardware.cpu %>



  <b>Ram:</b>
  <%=h hardware.ram %>



  <b>Building:</b>
  <%=h hardware.building %>



  <b>Room:</b>
  <%=h hardware.room %>

</div>
<%= javascript_tag "new Popup('hardware_popup_#{hardware.id}','hardware_link_#{hardware.id}',{modal:true})" %>

Also, here's the relevant generated html for the page:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Untitled</title>
    <link href="/stylesheets/physical.css?1278445441" media="screen" rel="stylesheet" type="text/css" />
<link href="/stylesheets/formtastic.css?1277506641" media="screen" rel="stylesheet" type="text/css" />
<link href="/stylesheets/formtastic_changes.css?1278462220" media="screen" rel="stylesheet" type="text/css" />
<link href="/stylesheets/popup.css?1278544136" media="screen" rel="stylesheet" type="text/css" />
    <script src="/javascripts/prototype.js?1277403114" type="text/javascript"></script>
<script src="/javascripts/effects.js?1277403114" type="text/javascript"></script>

<script src="/javascripts/dragdrop.js?1277403114" type="text/javascript"></script>
<script src="/javascripts/controls.js?1277403114" type="text/javascript"></script>
<script src="/javascripts/application.js?1277403114" type="text/javascript"></script>
<script src="/javascripts/jquery.js?1278457367" type="text/javascript"></script>
<script src="/javascripts/popup.js?1278544104" type="text/javascript"></script>
    
  </head>
  <body>
    <div id="container">
      
      
      <div id="main">
.
.
.
<h2>Hardware</h2>

<table>
  <tr>
    <th>Cctr</th>

    <th>Person</th>
    <th>Cpu</th>
    <th>Ram</th>
    <th>Building</th>
    <th>Room</th>
  </tr>

  <tr>
    <td>123</td>
    <td>1</td>
    <td>1</td>
    <td>1024</td>
    <td>Over There</td>

    <td>123</td>
    <td><span id="hardware_link_2" class="popup_link">Show</span><div id="hardware_popup_2" class="popup" style="display:none">

  <b>Cctr:</b>
  123



  <b>Person:</b>
  1



  <b>Cpu:</b>

  1



  <b>Ram:</b>
  1024



  <b>Building:</b>
  Over There



  <b>Room:</b>
  123

</div>
<script type="text/javascript">
//<![CDATA[
new Popup('hardware_popup_2','hardware_link_2',{modal:true})
//]]>
</script></td>

    <td><a href="#" onclick="new Ajax.Updater('hardware2', '/bus/edit/2?type=Hardware', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('BIaNjzwLkiIorFPISmwqVkZt5CcDx4/BwpcI49ujHO4=')}); return false;">Edit</a></td>
    <td><a href="/hardwares/2" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'BIaNjzwLkiIorFPISmwqVkZt5CcDx4/BwpcI49ujHO4='); f.appendChild(s);f.submit(); };return false;">Destroy</a></td>
  </tr>
  <tr><td><div id='hardware2'></div></td></tr>

  <tr>
    <td>456</td>
    <td>1</td>

    <td>4</td>
    <td>2048</td>
    <td>J</td>
    <td>24g</td>
    <td><span id="hardware_link_3" class="popup_link">Show</span><div id="hardware_popup_3" class="popup" style="display:none">

  <b>Cctr:</b>

  456



  <b>Person:</b>
  1



  <b>Cpu:</b>
  4



  <b>Ram:</b>
  2048



  <b>Building:</b>
  J



  <b>Room:</b>

  24g

</div>
<script type="text/javascript">
//<![CDATA[
new Popup('hardware_popup_3','hardware_link_3',{modal:true})
//]]>
</script></td>
    <td><a href="#" onclick="new Ajax.Updater('hardware3', '/bus/edit/3?type=Hardware', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('BIaNjzwLkiIorFPISmwqVkZt5CcDx4/BwpcI49ujHO4=')}); return false;">Edit</a></td>
    <td><a href="/hardwares/3" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'BIaNjzwLkiIorFPISmwqVkZt5CcDx4/BwpcI49ujHO4='); f.appendChild(s);f.submit(); };return false;">Destroy</a></td>
  </tr>
  <tr><td><div id='hardware3'></div></td></tr>

<tr>

  <td><a href="#" onclick="new Ajax.Updater('new_object_field', '/bus/new?type=Hardware', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('BIaNjzwLkiIorFPISmwqVkZt5CcDx4/BwpcI49ujHO4=')}); return false;">New Hardware</a></td>
</tr>
<tr>
  <td><div id="new_object_field"></div></td>
</tr>
</table>
.
.
.
</div>

    </div>
  </body>
</html>

I can't figure out why this doesn't work when the mongrel server reports back with affirmatives for rendering partials and gathering data.
Ideas anyone?

Thanks for any assistance,

-Pharserror

Last edited by Pharserror (2010-07-07 20:51:14)