Alex Rivera | Logout

Unobtrusive dynamic form fields in Rails with jQuery

Asked 2009-11-09T21:54:23.940
41

I'm attempting to get over the hurdle of dynamic form fields in Rails -- this appears to be something the framework doesn't handle very gracefully. I'm also using jQuery in my project. I have jRails installed, but I'd much rather write the AJAX code unobtrusively where possible.

My forms are fairly complex, two or three levels of nesting are not unusual. The problem I'm having is generating the correct form ids, since they are so dependant on the form builder context. I need to be able to dynamically add new fields or delete existing records in a has_many relationship, and I am completely at a loss.

Every example I've seen so far has been ugly in one way or another. Ryan Bates' tutorial requires RJS, which results in some pretty ugly obtrusive javascript in the markup, and seems to have been written before nested attributes. I've seen a fork of that example with unobtrusive jQuery, but I just don't understand what it's doing, and haven't been able to get it working in my project.

Can somebody provide a simple example of how this is done? Is this even possible while respecting the RESTful convention of the controllers?


Andy has posted an excellent example of deleting an existing record, can anybody provide an example of creating new fields with the correct attributes? I haven't been able to figure out how to do this with nested forms.

Edit
Report

2 Answers

2

By the way. rails has changed a bit so you can not longer use _delete, now use _destroy.

def remove_child_link(name, f)
  f.hidden_field(:_destroy) + link_to(name, "javascript:void(0)", :class => "remove_child")
end

Also I found it easier to just remove html that is for new records... so i do this

$(function() {
  $('form a.add_child').click(function() {
    var association = $(this).attr('data-association');
    var template = $('#' + association + '_fields_template').html();
    var regexp = new RegExp('new_' + association, 'g');
    var new_id = new Date().getTime();

    $(this).parent().before(template.replace(regexp, new_id));
    return false;
  });

  $('form a.remove_child').live('click', function() {
    var hidden_field = $(this).prev('input[type=hidden]')[0];
    if(hidden_field) {
      hidden_field.value = '1';
    }
    $(this).parents('.new_fields').remove();
    $(this).parents('.fields').hide();
    return false;
  });
});
answered 2010-08-16T01:33:12.863
1

I've successfully (and rather painlessly) used https://github.com/nathanvda/cocoon to dynamically generate my forms. Handles associations elegantly and the documentation is very straightforward. You can use it together with simple_form, too, which was particularly useful for me.

answered 2013-01-21T15:55:52.067

Your Answer