views:

86

answers:

4

Here is my problem, I have a whole bunch of elements that look like this...

<input type="email" id="email" data-item="email" data-key="contact_details"/>
<input type="tel" id="mobileNo" data-item="mobileNo" data-key="contact_details"/>

<input type="text" id="sleeve_length" data-item="sleeve_length" data-key="measurements"/>
<input type="text" id="inseam" data-item="inseam" data-key="measurements"/>

Each element has a 'data-key' and 'data-item' which corresponds to the json form i'm trying to turn them into, which will look something like this...

{
    "measurements" : {"sleeve_length" : value, "inseam" : value},

When each data-item is unique... and like this when it isn't...

    "contact_details" : [
                             {"email" : value, "mobileNo" : value},
                             {"email" : value, "mobileNo" : value}
                        ]
}

Now because my web app involves many forms, I need a way to dynamically transform the markup above into these json strings... but I can't seem to wrap my head around it!

Does anyone have any idea how I can approach this?

A: 

Something like:

var myJson = {};
// jQuery
$('input').each(function () {
    myJson[$(this).attr('data-key')][$(this).attr('data-value')] = $(this).val();
});
// Native JS
var els = document.getElementsByTagName('input');
for (var i = 0, l = els.length; i < l; i += 1) {
    myJson[els[i]['data-key']][els[i]['data-value']] = els[i].value;
}

Should do the trick. It loops through all of the input elements on the page and puts the data found in each element into an object with the key data-key and sets that equal to an object with the key data-value and the value the value of the input element.

Helpful?

Edit: Is that better? I don't know what I was thinking.

indieinvader
both of these examples come up with errors... the jquery one comes up with "Uncaught SyntaxError: Unexpected token (" , on the 3rd line of the function... the native js one comes up with "Uncaught SyntaxError: Unexpected token [" , on the 3rd line of the for loop.
cybermotron
A: 

You could let some JS MVC / MVVC library do this for you. For example, Knockout. I haven't used it myself yet, but from a glance it seems neat. You define mapping between your JSON object and HTML form fields, and the library would monitor form fields and update the JSON object (a "view model").

Pēteris Caune
+2  A: 

Something like so:

var json = {};
$('#path .to input').each(function(e) {
    var key = $(this).attr('data-key');
    var param = $(this).attr('data-item');
    var obj = {};
    obj[param] = $(this).val();

    // If we already have a record...
    if(key in json) {
        // If it's not an array, make it an array
        if(typeof(json[key].push) != 'function')
            json[key] = [ json[key] ];
        // Toss it on the pile
        json[key].push(obj);
    } else {
        // There's only 1 thus far, keep it k/v
        json[key] = obj;
    }
});

etc. Fairly basic, the key points just being testing whether or not the key you're working with exists or not, and if so, converting it to an array.

Edit: this is untested, but it should work.

Edit 2: revised code so your hash key vars don't come across as strings.

mway
Wow... that certainly takes me closer... the only thing is that it outputs like so {"_id":"contact_1288116316143","firstname":"John","lastname":"Smith","contact_details":[{"param":""},{"param":"sadfsadf"},{"param":"fasdfsad"},{"param":"sadfsad"},{"param":"asdfasdfsadfsa"}],"job_description":[{"param":""},{"param":""}],"fee":[{"param":""},{"param":""}],"measurements":[{"param":""},{"param":""},{"param":""},{"param":""},{"param":""},{"param":""},{"param":""},{"param":""},{"param":""},{"param":""}]}
cybermotron
Updated the code - sorry about that, short sight on my part. :) Give it a shot and let me know if that works as expected.
mway
now it throws up an error "Uncaught SyntaxError: Unexpected token (". on this line ... json[key] = { $(this).attr('data-item'): $(this).val() }; ... although all of the '(' seem to be in the right place.
cybermotron
My bad - forgot to fix a preliminary edit. Take a look now.
mway
That works nearly perfect. Only problem is that each key/value, becomes its own object, instead of being siblings inside an object. I just found this amazing plug-in "http://code.google.com/p/form2js/" that does exactly what I want, and gives me some extra wiggle room if I need to change my data mapping. Thanks heaps though. Your answer is awesome.
cybermotron