Permalink
Browse files

Merge branch 'unobtrusive-jquery' into unobtrusive-jquery-deep

Conflicts:
	README.rdoc
	app/helpers/application_helper.rb
	app/views/projects/_form.html.erb
	app/views/projects/_task.html.erb
	public/javascripts/application.js
  • Loading branch information...
2 parents 605eee5 + 3d36b80 commit 75bbce338b1888e580759387f186816064e7d9bc @ryanb ryanb committed Oct 13, 2009
View
@@ -1,4 +1,4 @@
-Copyright (c) 2008 Ryan Bates
+Copyright (c) 2009 Ryan Bates
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
@@ -1,12 +1,10 @@
= Complex Form Example: Deep Nesting
-This solution uses the +accepts_nested_attributes_for+ which was introduced in Rails 2.3. It supports any level of depth in nesting models. The primary challenge in deep nesting is getting the escaping working with JavaScript when adding new records.
+This solution uses the +accepts_nested_attributes_for+ which was introduced in Rails 2.3. It supports any level of depth in nesting models. This version uses unobtrusive JavaScript with jQuery and HTML 5.
Once you clone this repository, just run the migrations and start up the server to try it out.
rake db:migrate
script/server
-See the branches for alternative solutions. Here's how to clone a remote branch.
-
- git checkout -b deep origin/deep
+Special thanks to Tim Riley and Eloy Duran.
@@ -1,20 +1,22 @@
# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
def remove_child_link(name, f)
- f.hidden_field(:_delete) + link_to_function(name, "remove_fields(this)")
+ f.hidden_field(:_delete) + link_to(name, "javascript:void(0)", :class => "remove_child")
end
- def add_child_link(name, f, method)
- fields = new_child_fields(f, method)
- link_to_function(name, h("insert_fields(this, \"#{method}\", \"#{escape_javascript(fields)}\")"))
+ def add_child_link(name, association)
+ link_to(name, "javascript:void(0)", :class => "add_child", :"data-association" => association)
end
- def new_child_fields(form_builder, method, options = {})
- options[:object] ||= form_builder.object.class.reflect_on_association(method).klass.new
- options[:partial] ||= method.to_s.singularize
+ def new_child_fields_template(form_builder, association, options = {})
+ options[:object] ||= form_builder.object.class.reflect_on_association(association).klass.new
+ options[:partial] ||= association.to_s.singularize
options[:form_builder_local] ||= :f
- form_builder.fields_for(method, options[:object], :child_index => "new_#{method}") do |f|
- render(:partial => options[:partial], :locals => { options[:form_builder_local] => f })
+
+ content_tag(:div, :id => "#{association}_fields_template", :style => "display: none") do
+ form_builder.fields_for(association, options[:object], :child_index => "new_#{association}") do |f|
+ render(:partial => options[:partial], :locals => {options[:form_builder_local] => f})
+ end
end
end
end
@@ -1,10 +1,9 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!DOCTYPE html>
<html>
<head>
<title><%= h(yield(:title) || "Untitled") %></title>
<%= stylesheet_link_tag 'application' %>
- <%= javascript_include_tag :defaults %>
+ <%= javascript_include_tag 'jquery-1.3.2.min', 'application' %>
<%= yield(:head) %>
</head>
<body>
@@ -9,6 +9,7 @@
<% f.fields_for :tasks do |task_form| %>
<%= render :partial => 'task', :locals => { :f => task_form } %>
<% end %>
- <p><%= add_child_link "New Task", f, :tasks %></p>
+ <p><%= add_child_link "New Task", :tasks %></p>
+ <%= new_child_fields_template(f, :tasks)%>
<p><%= f.submit "Submit" %></p>
<% end %>
@@ -2,10 +2,16 @@
<%= f.label :name, "Task" %>
<%= f.text_field :name %>
<%= remove_child_link "remove", f %>
+<<<<<<< HEAD
<div class="children_fields">
<% f.fields_for :assignments do |assignment_form| %>
<%= render :partial => 'assignment', :locals => { :f => assignment_form } %>
<% end %>
<p><%= add_child_link "New Assignment", f, :assignments %></p>
</div>
+=======
+ <%# Alternatively you can use a check box: %>
+ <%# f.check_box :_delete %>
+ <%# f.label :_delete, "(remove)" %>
+>>>>>>> unobtrusive-jquery
</div>
@@ -1,18 +1,20 @@
-// Place your application-specific JavaScript functions and classes here
-// This file is automatically included by javascript_include_tag :defaults
-function insert_fields(link, method, content) {
- var new_id = new Date().getTime();
- var regexp = new RegExp("new_" + method, "g")
- $(link).up().insert({
- before: content.replace(regexp, new_id)
+$(function() {
+ $('form a.add_child').click(function() {
+ var assoc = $(this).attr('data-association');
+ var content = $('#' + assoc + '_fields_template').html();
+ var regexp = new RegExp('new_' + assoc, 'g');
+ var new_id = new Date().getTime();
+
+ $(this).parent().before(content.replace(regexp, new_id));
+ return false;
});
-}
-
-function remove_fields(link) {
- var hidden_field = $(link).previous("input[type=hidden]");
- if (hidden_field) {
- hidden_field.value = '1';
- }
- $(link).up(".fields").hide();
-}
-
+
+ $('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('.fields').hide();
+ return false;
+ });
+});
Oops, something went wrong.

0 comments on commit 75bbce3

Please sign in to comment.