public
Fork of sstephenson/prototype
Description: Prototype JavaScript framework, patched to serialize forms fields in the correct order for Rails
Homepage: http://prototypejs.org/
Clone URL: git://github.com/notahat/prototype.git
Patched to serialize Rails style forms with nested params in the correct order.
notahat (author)
Sat Jul 12 00:45:53 -0700 2008
commit  8949aa23cb547039a34f380863e13c11bc919878
tree    129e310db4fc29e0a975bcfae5320a2c160f0833
parent  a134431d807463274176f6db457a2001e9b7e3a4
...
59
60
61
62
63
64
 
65
66
67
...
78
79
80
81
 
 
82
83
84
85
 
 
 
 
86
87
88
89
90
91
 
 
92
93
94
...
59
60
61
 
 
 
62
63
64
65
...
76
77
78
 
79
80
81
82
83
 
84
85
86
87
88
89
90
91
92
 
93
94
95
96
97
0
@@ -59,9 +59,7 @@ Ajax.Base = Class.create({
0
 
0
     this.options.method = this.options.method.toLowerCase();
0
 
0
-    if (Object.isString(this.options.parameters))
0
-      this.options.parameters = this.options.parameters.toQueryParams();
0
-    else if (Object.isHash(this.options.parameters))
0
+    if (Object.isHash(this.options.parameters))
0
       this.options.parameters = this.options.parameters.toObject();
0
   }
0
 });
0
@@ -78,17 +76,22 @@ Ajax.Request = Class.create(Ajax.Base, {
0
   request: function(url) {
0
     this.url = url;
0
     this.method = this.options.method;
0
-    var params = Object.clone(this.options.parameters);
0
+    var params = this.options.parameters;
0
+    if (!Object.isString(params)) params = Object.clone(params);
0
 
0
     if (!['get', 'post'].include(this.method)) {
0
       // simulate other verbs over post
0
-      params['_method'] = this.method;
0
+      if(Object.isString(params))
0
+        params += '_method=' + this.method;
0
+      else
0
+        params['_method'] = this.method;
0
       this.method = 'post';
0
     }
0
 
0
     this.parameters = params;
0
 
0
-    if (params = Object.toQueryString(params)) {
0
+    if (!Object.isString(params)) params = Object.toQueryString(params);
0
+    if (params) {
0
       // when GET, append parameters to URL
0
       if (this.method == 'get')
0
         this.url += (this.url.include('?') ? '&' : '?') + params;
...
11
12
13
14
 
 
15
16
17
...
38
39
40
41
42
 
 
 
 
 
 
 
 
 
 
 
43
44
45
46
47
48
49
50
51
 
 
 
 
 
 
 
 
 
 
 
52
53
54
55
56
 
57
58
59
...
11
12
13
 
14
15
16
17
18
...
39
40
41
 
 
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 
 
 
 
 
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
72
73
74
75
0
@@ -11,7 +11,8 @@ var Form = {
0
     var key, value, type, isImageType, isSubmitButton, submitSerialized;
0
     var submit = options.submit;
0
     
0
-    var data = elements.inject({ }, function(result, element) {
0
+    var start_with = options.hash ? { } : ''
0
+    var data = elements.inject(start_with, function(result, element) {
0
       element = $(element);
0
       key     = element.name;
0
       value   = element.getValue();
0
@@ -38,22 +39,37 @@ var Form = {
0
           var prefix = key ? key + '.' : '',
0
            x = options.x || 0, y = options.y || 0;
0
            
0
-          result[prefix + 'x'] = x;
0
-          result[prefix + 'y'] = y;
0
+          if (Object.isString(result)) {
0
+            if (result != '') result += '&';
0
+            var pairs = { }
0
+            pairs[prefix + 'x'] = x;
0
+            pairs[prefix + 'y'] = y;
0
+            result += Object.toQueryString(pairs);
0
+          }
0
+          else {
0
+            result[prefix + 'x'] = x;
0
+            result[prefix + 'y'] = y;
0
+          }
0
           return result;
0
         }
0
       } else if (!key) return result;
0
       
0
-      if (key in result) {
0
-        // a key is already present; construct an array of values
0
-        if (!Object.isArray(result[key])) result[key] = [result[key]];
0
-        result[key].push(value);
0
-      } else result[key] = value;
0
+      if (Object.isString(result)) {
0
+        if (result != '') result += '&';
0
+        result += element.serialize();
0
+      }
0
+      else {
0
+        if (key in result) {
0
+          // a key is already present; construct an array of values
0
+          if (!Object.isArray(result[key])) result[key] = [result[key]];
0
+          result[key].push(value);
0
+        } else result[key] = value;
0
+      }
0
       
0
       return result;
0
     });
0
     
0
-    return options.hash ? data : Object.toQueryString(data);
0
+    return data;
0
   }
0
 };
0
 
...
99
100
101
 
 
 
 
 
 
 
 
102
103
104
...
99
100
101
102
103
104
105
106
107
108
109
110
111
112
0
@@ -99,6 +99,14 @@
0
   <input type="file" name="file_name" value="foo" />
0
 </form>
0
 
0
+<form id="form_with_rails_style_nested_params">
0
+  <input type="text" name="group[name]" value="a" />
0
+  <input type="text" name="group[person][][first_name]" value="b" />
0
+  <input type="text" name="group[person][][last_name]"  value="c" />
0
+  <input type="text" name="group[person][][first_name]" value="d" />
0
+  <input type="text" name="group[person][][last_name]"  value="e" />
0
+</form>
0
+
0
 <!-- tabindexed forms -->
0
 <div id="tabindex">
0
   <form id="ffe">
...
286
287
288
 
 
 
 
 
289
290
291
...
286
287
288
289
290
291
292
293
294
295
296
0
@@ -286,6 +286,11 @@ new Test.Unit.Runner({
0
     // test control groups
0
     var expected = {group_radio:'2r', group_checkbox:'2c'};
0
     this.assertHashEqual(expected, Form.serialize('form_with_control_groups', {submit:'button_commit'}));
0
+    
0
+    // forms with Rails style nested params should serialize in the right order
0
+    var form = $('form_with_rails_style_nested_params');
0
+    var expected = 'group[name]=a&group[person][][first_name]=b&group[person][][last_name]=c&group[person][][first_name]=d&group[person][][last_name]=e'
0
+    this.assertEqual(expected, unescape(form.serialize()))
0
   },
0
   
0
   testFormMethodsOnExtendedElements: function() {

Comments