Find don't you just define a toJSON method for forms and form
elements.

Prototype's implementation was designed with that in mind.

See http://prototypejs.org/learn/json for details. (About midways)

Best,

Tobie



On Jun 12, 3:52 pm, TAOS <[EMAIL PROTECTED]> wrote:
> Now i fix my method.
>
> It work like a prototype serialize method without options and with ths
> option hierarchy = true work like my way, broke in each point.
>
> examples with this form:
>
> Look herehttp://pastebin.com/f41ba8348to view the code with better
> look.
>
> <form id="form_person">
> <input name="person.name" value="Thiago"/>
> <input name="person.age" value="23"/>
> <input name="person.address.street" value="Marketplace Street" />
> <select name="person.country.id">
>   <option value="BR">BR</option>
>   <option value="EUA">EUA</option>
> </select>
> <input type="checkbox" name="person.intersting" value="Prototype"
> checked="checked"/>
> <input type="checkbox" name="person.intersting" value="Ruby"
> checked="checked"/>
> <input type="checkbox" name="person.intersting" value="Java" />
> </form>
>
> formToJSON('form_person');
>
> "person.name=Thiago&person.age=23&person.address.street=Marketplace
> %20Street&person.country.id=BR&person.intersting=Prototype&person.interstin 
> g=Ruby"
>
> formToJSON('form_person', {});
>
> {
>   person.name:"Thiago",
>   person.age:"23",
>   person.address.street:"Marketplace Street",
>   person.country.id:"BR",
>   person.intersting:["Prototype", "Ruby"]
>
> }
>
> formToJSON('form_person', { hierarchy: true, prefix : 'person.',
> exclude: ['intersting'] } );
>
> {
>   name:"Thiago",
>   age:"23",
>   address:{street:"Marketplac..."},
>   country:{id:"BR"}
>
> }
>
> And finally the method. No repeat code, and no eval
>
> function formToJSON(form, options) {
>         elements = $(form).getElements();
>         if (typeof options != 'object') options = { hash: !!options };
>         else if (Object.isUndefined(options.hash)) options.hash = true;
>         var key, value, submitted = false, submit = options.submit;
>
>         var data = elements.inject({ }, function(result, element) {
>                 if (!element.disabled && element.name) {
>                 key = element.name;
>                 value = $(element).getValue();
>                 if (value != null && (element.type != 'submit' || (!submitted 
> &&
>                         submit !== false && (!submit || key == submit) && 
> (submitted
> = true)))) {
>
>                         function set_key(key, obj, value) {
>                                         if (key in obj) {
>                         if ( !Object.isArray( obj[key] ) ) obj[key] =
> [ obj[key] ];
>                         obj[key].push(value);
>                                 } else  obj[key] = value;
>                                         return obj;
>                         }
>
>                         function is_exclude_key(key) {
>                                 if( Object.isArray(options.exclude) &&
> options.exclude.indexOf(key) != -1 ) return true;
>                                 return false;
>                         }
>
>                         if( !Object.isUndefined(options.hierarchy) &&
> options.hierarchy ) {
>                                 key = ( !Object.isUndefined(options.prefix) ) 
> ?
> key.replace(options.prefix,"") : key;
>                                 if( is_exclude_key(key) ) return result;
>                                 if( key.indexOf(".") != -1 ) {
>                                         var newkey = key.substring( 0,
> key.indexOf(".") );
>                                         key = key.replace( newkey + ".", "" );
>
>                                         function 
> set_and_advance_key(processkey, obj, value) {
>                                                 if( processkey.indexOf(".") 
> != -1 ) {
>                                                         var newkey = 
> processkey.substring( 0,
> processkey.indexOf(".") );
>                                                         processkey = 
> processkey.replace( newkey + ".", "" );
>                                                         obj[newkey] = 
> set_and_advance_key( processkey, {},
> value )
>                                                         }  else obj = 
> set_key(processkey, obj, value);
>                                                 return obj;
>                                         }
>                                         result[newkey] = 
> set_and_advance_key(key, {}, value);
>                                 } else result = set_key(key, result, value);
>                         } else if( !is_exclude_key(key) ) result = 
> set_key(key,
> result, value);
>                         }
>                 }
>                 return result;
>         });
>         return options.hash ? data : Object.toQueryString(data);
>
> };
>
> and now, with yout tips i think that the method is better.
> How can i get more better yet?
>
> On 12 jun, 10:12, "Frederick Polgardy" <[EMAIL PROTECTED]> wrote:
>
> > You passed the serialized string into the function, which won't work.
> > (It'll iterate through the characters, as you can see.)
>
> > There isn't a Prototype function that collects a form's values into an
> > object, but it's pretty simple to write one:
>
> > function to_object(form) {
> >   return $(form).getElements().inject({}, function(object, element) {
> >     o[e.name] = $F(e);
> >     return o;
> >   });
>
> > }
>
> > This doesn't handle multiple valued elements like checkboxes and
> > multiselects, but it gives the basic idea.  You'd then pass the result of
> > that to to_exploded_object() to handle the rest:
>
> > var object = to_exploded_object(to_object('form_test'));
>
> > I might refactor this a bit into a single function.  I think it has a pretty
> > important use-case: where you want to submit a JSON request directly from a
> > form in HTML/JS without going through a server-side framework that handles
> > this unpacking for you.
>
> > -Fred
>
> > On Thu, Jun 12, 2008 at 7:43 AM, TAOS <[EMAIL PROTECTED]> wrote:
>
> > > How to use this?
>
> > > json = to_exploded_object( $('form_test').serialize() );
>
> > > or
>
> > > json = to_exploded_object( Object.toJSON( $
> > > ('form_test').serialize() ) );
>
> > > Look the result in both examples, this don't work like i expected, but
> > > i get the ideia to don't use eval. thx both.
>
> > > {  0:""",   1:"c",   2:"o",   3:"n",   4:"c",   5:"e",   6:"s",
> > > 7:"s",   8:"i",   9:"o",   10:"n",   11:"a",   12:"r",   13:"i",
> > > 14:"a",   15:".",   16:"c",   17:"a",   18:"r",   19:"r",
> > >  20:"o",   21:".",   22:"m",   23:"a",   24:"r",   25:"c",
> > > 26:"a",   27:".",   28:"c",   29:"o",   30:"d",   31:"i",   32:"g",
> > > 33:"o",   34:"=",   35:"2",   36:"0",   37:"&",
> > >  38:"c",   39:"o",   40:"n",   41:"c",   42:"e",   43:"s",
> > > 44:"s",   45:"i",  ....
>
> > > On 11 jun, 22:48, "Frederick Polgardy" <[EMAIL PROTECTED]> wrote:
> > > > Right, all the uses of eval were unnecessary.
>
> > > > I came up with a quick utility along these lines, that allows you to 
> > > > pass
> > > in
> > > > an object like:
>
> > > > {"a.b.c": 1, "a.b.d":2, "a.b.e[0].f": 3, "a.b.e[1].g": 4}
>
> > > > Which you might get from a Prototype form utility function, and get back
> > > an
> > > > exploded object like:
>
> > > > {"a": {"b": {"c":1, "d":2, "e": [{"f": 3}, {"g": 4}]}}}
>
> > > > Which is suitable for passing to Object.toJSON().  It basically just
> > > handles
> > > > intermediate objects that can be ordinary values or arrays, but that
> > > handles
> > > > all the cases I can think of.  Let me know what you think.
>
> > > >   function to_exploded_object(object) {
> > > >     var root = {};
>
> > > >     $H(object).each(function(property) {
> > > >       var current = root,
> > > >           path = property.key.split("."),
> > > >           last = path.pop();
>
> > > >       function set_and_advance_key(key, value) {
> > > >         var match = key.match(/^(\w+)(?:\[(\d+)\])?/),
> > > >             name = match[1],
> > > >             index = match[2];
>
> > > >         if (index) {
> > > >           index = parseInt(index);
> > > >           current[name] = current[name] || [];
> > > >           current[name][index] = current[name][index] || value;
> > > >           current = current[name][index];
> > > >         } else {
> > > >           current[name] = current[name] || value;
> > > >           current = current[name];
> > > >         }
> > > >       }
>
> > > >       path.each(function(key) { set_and_advance_key(key, {}); });
> > > >       set_and_advance_key(last, property.value);
> > > >     });
>
> > > >     return root;
> > > >   }
>
> > > > -Fred
>
> > > > On Wed, Jun 11, 2008 at 4:43 PM, kangax <[EMAIL PROTECTED]> wrote:
>
> > > > > Fair enough, but still makes little sense to use eval:
>
> > > > > function toObject(str) {
> > > > >  var result = { };
> > > > >  str.split('.').inject(result, function(parent, child) {
> > > > >    return parent[child] = parent[child] || { };
> > > > >  });
> > > > >  return result;
> > > > > };
>
> > > > > toObject('foo.bar.baz'); // { foo: { bar: baz: { }}}
>
> > > > --
> > > > Science answers questions; philosophy questions answers.
>
> > --
> > Science answers questions; philosophy questions answers.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Spinoffs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to