views:

148

answers:

3

Hi guys,

I am trying to create a JSON object from a bunch of grouped HTML elements, this is my markup,

HTML:

<div id="locations_wrapper">
    <div id="location_0" class="locations">
        <div class="container">
          <label for="locations_province">Province: </label>
          <div>
            <select id="locations_province" name="locations_province" onchange="get_cities(this);">
              <option value="">Select one</option>
              <option>Eastern Cape</option>
              <option>Freestate</option>
              <option>Gauteng</option>
              <option>KZN</option>
              <option>Limpopo</option>
              <option>Mpumalanga</option>
              <option>North West</option>
              <option>Northern Cape</option>
              <option>Western Cape</option>
            </select>
          </div>
        </div>
        <!-- City -->
        <div class="container">
          <label for="locations_city">City: </label>
          <div>
            <select id="locations_city" name="locations_city">
              <option value="">Select one</option>
            </select>
          </div>
        </div>
        <!-- Towns -->
        <div class="container">
          <label for="locations_towns">Towns: </label>
          <div>
            <input type="text" name="locations_towns" id="locations_towns" />
          </div>
        </div>
    </div>
</div>

At the moment I am cloning these 3 fields and appending them to the parent div locations_wrapper, I also increment the id attribute of each field, the problem now is that I need to get all of the cloned elements and somehow, using jQuery/ajax, capture all of the data of each location into a database.

How could I go about getting that information?

here is some jQuery I wrote that basically does the same thing, but with one fied instead of 3:

    var sections = $('#systems_wrapper').find('.dropDowns');
    var newArray = new Array();

        sections.each(function(){
            var id = $(this).attr('id');
            var val = $(this).val();
            var o = { 'id': id, 'value': val };

            newArray.push(o);
        });

        $.ajax({
                type: 'POST',
                url: 'qwer.php',
                dataType: 'json',
                data: { json: JSON.stringify(newArray) }
        });

Maybe I could try creating a JSON object with 3 fields province, city and town? I am a little unsure.

Thanx in advance!

+2  A: 

The easiest way to serialize a form as JSON is to use jQuery's serializeArray():

JSON.stringify($("#myForm").serializeArray());

You will need to wrap a form around your HTML for this to work though. It won't change the behavior. http://api.jquery.com/serializeArray/

SimpleCoder
Thanx, will give it a go!
+1  A: 

It's not very clear, from your question, what you're trying to accomplish. But I'm guessing, from your markup, that you're building something that will allow the user to add multiple "locations" within the "locations_wrapper" object. This sort of thing usually starts with markup like you've shown, providing a single blank "location" form for the user to fill in (3-fields, in this case); and a button that they can click to add additional "location" blocks as needed.

Assuming that this is what you're doing, my first suggestion would be that, instead of cloning the three form fields individually, you should be cloning only their parent container, "location_0". Something like this should do the trick:

$('#location_0').clone().appendTo('#locations_wrapper');

That will copy the entire block -- and you don't really need to worry about changing the ids of things, jQuery and/or the browser will take care of ensuring that everything has a unique id behind-the-scenes.

Now, assuming that your markup is located within a form, the easiest way to get the information back up to the server is just to submit the form. The form post will contain multiple fields with the same name -- which is completely valid, and most server-side languages have a simple way of dealing with it.

In php, multi-value request parameters come in as an array. So in php, you could do something like this:

<?php
$field_names = ['locations_province', 'locations_city', 'locations_town'];

$locations = array();
foreach( $field_names as $fieldname ) {
    $temp = (array)$_REQUEST[$fieldname];
    for( $i=0; $i<count($temp); ++$i ) {
        if( !isset($locations[$i]) ) $locations[$i] = array();
        $locations[$i][$fieldname] = $temp[$i];
    }
}

If you'd rather aggregate it all in javascript, you can access your field groups like this:

var allLocations = [];
$(".locations").each( function(i, location) {
    // for each location block
    location = $(location);
    var loc = {
        'locations_province' : $("select[name='locations_province']", location).val(),
        'locations_city' : $("select[name='locations_city']", location).val(),
        'locations_towns' : $("input[name='locations_towns']", location).val()
    };
    allLocations.push( loc );
});

// allLocations will contain a list of objects with properties representing 
// your locations.  at this point, you can do whatever you want with 'em 
// send them up via Ajax, or whatever.

good luck!

Lee
Thank you very much for taking the time to explain it as you did, it was a great help! One thing that seems to be happening though is that the `select[name='locations_towns']` is not sending a value through, even though I fixed the code, as it should be a input and not a select, I am still getting a blank variable when it gets returned to me on the callback function.
oops - you're right, it *should* be `input` instead of `select`. Good catch. I made another error too (which is probably causing the problems you're seeing). The values should be extracted like this: `$("select[name='locations_towns']", location).val()`. The correct name of the function is [`val()` not `value()`](http://api.jquery.com/val/). Let us know whether this fixes it or not.
Lee
I made those fixes in the code example. Also, fixed a misspelling of 'locations_towns'.
Lee
I actually cought that one too, I changed `value()` to `val()`, but it only worked when I changed `locations_towns` to something else, I have no idea why it did that, but the code is working like a charm now, thanx alot! You've just opened a whole new chapter in my jQuery book, I can't get enough of CSS selectors, so thanx again for all the help! :)
+1  A: 

My thought, if you've got control over what the server can accept, would be to pass a bag instead of an array e.g.

{"province" : "", "city" : "", "town" : ""}

I'd then create a payload object:

var province, city, town, payload;

province = $("#locations_province").val();
city= $("#locations_city").val();
town= $("#locations_town").val();
payload = {"province" : province, "city" : city, "town" : town};

...and give the payload to $.ajax:

$.ajax({
  type: 'POST',
  url: 'qwer.php',
  dataType: 'json',
  data: payload
  });

jQuery will URI encode the payload for you.

You can streamline the payload creation even further if you use Mustache.

Christopher Hunt
Thank you, will give it a go.