[patch] formContents returning a dict

View: New views
2 Messages — Rating Filter:   Alert me  

[patch] formContents returning a dict

by Eoghan Murray :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Here is a patch that converts the output of DOM.formContents to a dictionary.

This has been raised as a difficulty before [1] and has bitten me a
few times when trying to edit the return value of formContents before
converting it to a query string.

In this patch, the previous format of:
[['name1', 'name2', 'name2'], ['value1', 'value2', 'value3']]
becomes:
{'name1': ['value1'], 'name2': ['value2', 'value3'] }
i.e. values are always stored in lists even if there is only one value.

This is backwards incompatible, but I've also updated Base.queryString
so that it still works with the new format.

If it is accepted I can update docs & version history.

Eoghan

[1] http://groups.google.com/group/mochikit/browse_thread/thread/5d970041f1696b10/a5fa33325d639cf4

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to mochikit@...
To unsubscribe from this group, send email to mochikit+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---


Index: MochiKit/DOM.js
===================================================================
--- MochiKit/DOM.js (revision 1525)
+++ MochiKit/DOM.js (working copy)
@@ -44,8 +44,7 @@
 
     /** @id MochiKit.DOM.formContents  */
     formContents: function (elem/* = document.body */) {
-        var names = [];
-        var values = [];
+        var dict = {};
         var m = MochiKit.Base;
         var self = MochiKit.DOM;
         if (typeof(elem) == "undefined" || elem === null) {
@@ -57,12 +56,20 @@
             var name = elem.name;
             if (m.isNotEmpty(name)) {
                 var tagName = elem.tagName.toUpperCase();
+                if (tagName === "FORM" || tagName === "P" || tagName === "SPAN"
+                    || tagName === "DIV"
+                ) {
+                    return elem.childNodes;
+                }
                 if (tagName === "INPUT"
                     && (elem.type == "radio" || elem.type == "checkbox")
                     && !elem.checked
                 ) {
                     return null;
                 }
+                if (dict[name] === undefined) {
+                    dict[name] = [];
+                }
                 if (tagName === "SELECT") {
                     if (elem.type == "select-one") {
                         if (elem.selectedIndex >= 0) {
@@ -75,19 +82,16 @@
                                     v = opt.text;
                                 }
                             }
-                            names.push(name);
-                            values.push(v);
+                            dict[name].push(v);
                             return null;
                         }
                         // no form elements?
-                        names.push(name);
-                        values.push("");
+                        dict[name].push("");
                         return null;
                     } else {
                         var opts = elem.options;
                         if (!opts.length) {
-                            names.push(name);
-                            values.push("");
+                            dict[name].push("");
                             return null;
                         }
                         for (var i = 0; i < opts.length; i++) {
@@ -103,24 +107,17 @@
                                     v = opt.text;
                                 }
                             }
-                            names.push(name);
-                            values.push(v);
+                            dict[name].push(v);
                         }
                         return null;
                     }
                 }
-                if (tagName === "FORM" || tagName === "P" || tagName === "SPAN"
-                    || tagName === "DIV"
-                ) {
-                    return elem.childNodes;
-                }
-                names.push(name);
-                values.push(elem.value || '');
+                dict[name].push(elem.value || '');
                 return null;
             }
             return elem.childNodes;
         });
-        return [names, values];
+        return dict;
     },
 
     /** @id MochiKit.DOM.withDocument */
Index: MochiKit/Base.js
===================================================================
--- MochiKit/Base.js (revision 1525)
+++ MochiKit/Base.js (working copy)
@@ -1170,14 +1170,8 @@
                 typeof(names.nodeType) != "undefined" && names.nodeType > 0
             ))
         ) {
-            var kv = MochiKit.DOM.formContents(names);
-            names = kv[0];
-            values = kv[1];
+            return arguments.callee(MochiKit.DOM.formContents(names));
         } else if (arguments.length == 1) {
-            // Allow the return value of formContents to be passed directly
-            if (typeof(names.length) == "number" && names.length == 2) {
-                return arguments.callee(names[0], names[1]);
-            }
             var o = names;
             names = [];
             values = [];
Index: tests/test_MochiKit-DOM.html
===================================================================
--- tests/test_MochiKit-DOM.html (revision 1525)
+++ tests/test_MochiKit-DOM.html (working copy)
@@ -297,17 +297,17 @@
         );
     });
     var kv = formContents(frm);
-    is( kv[0].join(","), "foo,foo,baz", "mock formContents names" );
-    is( kv[1].join(","), "bar,bar,bar", "mock formContents values" );
+    is( keys(kv).join(","), "foo,baz", "mock formContents names" );
+    is( values(kv).join(","), "bar,bar,bar", "mock formContents values" );
     is( queryString(frm), "foo=bar&foo=bar&baz=bar", "mock queryString hook" );
 
     var kv = formContents("form_test");
-    is( kv[0].join(","), "select,selmultiple,selmultiple,hidden,radio_on", "formContents names" );
-    is( kv[1].join(","), "foo,bar,baz,test,2", "formContents values" );
+    is( keys(kv).join(","), "select,selmultiple,hidden,radio_on", "formContents names" );
+    is( values(kv).join(","), "foo,bar,baz,test,2", "formContents values" );
     is( queryString("form_test"), "select=foo&selmultiple=bar&selmultiple=baz&hidden=test&radio_on=2", "queryString hook" );
     kv = formContents("form_test2");
-    is( kv[0].join(","), "selempty,selempty2", "formContents names empty option values" );
-    is( kv[1].join(","), ",foo", "formContents empty option values" );
+    is( keys(kv).join(","), "selempty,selempty2", "formContents names empty option values" );
+    is( values(kv).join(","), ",foo", "formContents empty option values" );
     is( queryString("form_test2"), "selempty=&selempty2=foo", "queryString empty option values" );
     
     var d = DIV(null, SPAN(), " \n\t", SPAN(), "foo", SPAN(), " ");

Re: [patch] formContents returning a dict

by Per Cederberg-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I'd prefer a non-incompatible fix for this. One obvious improvement
would be to add a dict() function:

http://github.com/cederberg/mochikit-patches/blob/1e0dd2fcc3c80e1fe78f87d9ca7d9ba16b9eee09/MochiKit/Base.js#L71

But for forms, some values might be repeated so that wouldn't solve it
all. Actually, I don't know if the current formContents() handles that
correctly... For the proposed widget library I rewrote it as this:

http://github.com/cederberg/mochikit-patches/blob/1e0dd2fcc3c80e1fe78f87d9ca7d9ba16b9eee09/MochiKit/Widget.js#L963

None of the above is in the MochiKit repository yet due to lack of
time on my part. Been working full-time with other stuff for a while,
but I'm planning to come back to MochiKit eventually. And tend to the
issues reported in Trac and here on the list.

Anyway. I think the best solution might be to create a new
formContents (different name) to allow for an alternative API. We'd
then deprecate the old implementation and remove entirely eventually.
Improving the download packager, we might even provide a "strict"
version or so.

Cheers,

/Per

On Fri, Apr 17, 2009 at 9:13 PM, Eoghan Murray <eoghanomurray@...> wrote:

> Here is a patch that converts the output of DOM.formContents to a dictionary.
>
> This has been raised as a difficulty before [1] and has bitten me a
> few times when trying to edit the return value of formContents before
> converting it to a query string.
>
> In this patch, the previous format of:
> [['name1', 'name2', 'name2'], ['value1', 'value2', 'value3']]
> becomes:
> {'name1': ['value1'], 'name2': ['value2', 'value3'] }
> i.e. values are always stored in lists even if there is only one value.
>
> This is backwards incompatible, but I've also updated Base.queryString
> so that it still works with the new format.
>
> If it is accepted I can update docs & version history.
>
> Eoghan
>
> [1] http://groups.google.com/group/mochikit/browse_thread/thread/5d970041f1696b10/a5fa33325d639cf4
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to mochikit@...
To unsubscribe from this group, send email to mochikit+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---