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 here http://pastebin.com/f41ba8348 to 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.intersting=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