views:

111

answers:

1

I'm trying to build a Rails app in which you can edit the same model from several different locations on the page. I want changes to be saved automatically every X seconds, with an option of manually triggering a save.

I have come up with a solution, but it seems very complicated, and I assume other Rails users have already faced similar questions.

The solution I came up with, is to have a hidden form on my page that is the one actually submitted, and then have multiple "dummy" forms scattered around the page that update the hidden form.

Once submitted, the hidden form updates the model, and the model contains logic to determine which RJS files should be returned in response. These are bundled up and sent as an update response.

some limitations:

  • Can't wrap the whole page in one form tag (there are multiple models/controllers on the page)
  • The same field might be editable from multiple locations

Anyone have a more efficient way?

+2  A: 
  • create as much form as you need in your page even of the same instance of the same model
  • triggering the update would be either a javascript setInterval call, or onblur on your form fields.
  • your controller should be a REST one, and it will return success or error messages in json variables and a HTTP status (200, 422)
  • Forget rjs, think client side. Each form in your page will be submitting the form to the update method of your controller. The javascript submitting the form will have a error or success callback which will then show the success or error messages. The idea is that the javascript sending the form "knows" which form it is currently submitting, and it should be able to show error or success by itself dependending of the form it is submitting, it's not the controller job.
  • Saving the whole page is just serializing all the fields from all the forms and sending it to the update method. (see serialize)
hellvinz
1. How would I avoid id clashes between input fields? Remember I want to allow editing the same field in several different locations
shmichael
2. How would I take care of updating all the representations of an updated form field without using RJS? I don't want to refresh the whole page for a single field update.
shmichael
for 1. you can pass an :id parameter to your input helper. <%= f.text_field :name, :id => 'bla' %> It's then up to you to take care of your id to avoid collisions. Maybe you can prefix them by the form name
hellvinz
for 2. I've set up a really basic example here http://gist.github.com/570183 : you have two forms, a javascript function submitAllForms() which is intended to be called periodically (not done) it will put a green border around the good input and a red or yellow (depending of the form) in the bad input. No rjs, just json and javascript.
hellvinz
First off, +1 to the answer for providing the source code. Second, you are taking care of a simple scenario, where submitting the forms successfully does not alter the page. However, as mentioned above, once a form has been changed, other forms need to be updated, as well as page elements (for example, I have 3 forms in which a user can change his username). If one of these forms is updated, the change should propogate throughout the page. I can't see how the proposed solution could scale to support this beahviour without becoming impossible to maintain.
shmichael