views:

9942

answers:

7

I'm trying to send a lot of data from a form using the $.post method in jQuery. I've used the serialize() function first to make all the form data into one long string which I will then explode serverside. The weird thing is when I try and send it using $.post it appends the result of the serialize() to the URL as if I was sending it using GET. Anyone have any ideas why this is happening?

Here's the jquery:

$("#addShowFormSubmit").click(function(){
  var perfTimes = $("#addShowForm").serialize();
  $.post("includes/add_show.php", {name: $("#showTitle").val(), results: perfTimes }, function(data) {
    $("#addShowSuccess").empty().slideDown("slow").append(data);
  });
});

here's the php:

$show = $_POST['name'];
$results = $_POST['results'];
$perfs = explode("&", $results);
foreach($perfs as $perf) {
    $perf_key_values = explode("=", $perf);
    $key = urldecode($perf_key_values[0]);
    $values = urldecode($perf_key_values[1]);
}
echo $key, $values;
A: 

try using serializeArray() instead of serialize(). serialize() will produce an url-encoded query string, whereas serializeArray() produces a JSON data structure.

Franz
+2  A: 

What leads you to believe that the data is appended to the URL?

Anyway, wouldn't it make more sense to pass the form values in the form data itself? It will allow you to skip the "explode" step:

$("#addShowFormSubmit")
  .click(function() { 
      var perfTimes = $("#addShowForm").serialize(); 
      $.post("includes/add_show.php", 
         $.param({name: $("#showTitle").val()}) + & + perfTimes, 
         function(data) {...}); 
  });
Philippe Leybaert
A: 

So this is probably a bit obtuse, but I made a function to help me do this very thing since I got tired of making a bunch of fixes every time. serializeArray is kind of annoying because it provides a collection of objects, when all I wanted to have PhP reconstruct was an associative array. The function below will go through the serialized array and will build a new object with the appropriate properties only when a value exists.

Firstly, the function (it takes the ID of the form in question):

function wrapFormValues(form) { 
    form = "#" + form.attr("id") + " :input";
    form = $(form).serializeArray();
    var dataArray = new Object();

    for( index in form)
    {  
     if(form[index].value)  {
      dataArray[form[index].name] = form[index].value;  
     }
    }  

    return dataArray; 
}

When constructing my posts I also usually use an object since I usually tag on two or three other values before the form data and I think it looks cleaner than to define it inline, so the final step looks like this:

var payload = new Object(); 
//stringify requires json2.js from http://www.json.org/js.html
payload.data = JSON.stringify(data);

$.post("page.php", payload,  
    function(reply) {
     //deal with reply.
    });

Server-side all you have to do is $payload = json_decode($_POST['data'], true) and you have yourself an associative array where the keys are the names of your form fields.

Full disclaimer though, multiple-selects probably won't work here, you would probably only get whichever value was last on the list. This is also created very specifically to suit one of my projects, so you may want to tweak it to suit you. For instance, I use json for all of my replies from the server.

Vassi
A: 

Try this syntax. I use this to serialize a form and POST via ajax call to WCF service. Also, you can send this back a single JSON object instead of building the object the way you are. Try this:

var serializedForm = serializedForm = $("#addShowForm").serializeArray();

$.post("includes/add_show.php", 
    {
        "myObjectName": ("#showTitle").val(), results: perfTimes 
    }, function(data) 
        {
            $("#addShowSuccess").empty()
            .slideDown("slow")
            .append(JSON.stringify(serializedForm)); 
        });
Zacho
Thanks. I need to look at that cos I've haven't delved into JSON before...
musoNic80
A: 

On the php side, you may want to look into parse_str. It will parse that url string into variables, or into an array if you utilize the 2nd optional parameter.

CRasco
+3  A: 

I have seen this exact behavior caused by only one thing:

If you are using a button element to activate the serialize and ajax, and if that element is within the form, the button automatically acts as a form submission, no matter what other .click assignment you give it with jQuery.

And in the case where a form element has no action attribute specified, this submission simply sends the data back onto the same page. So you will end up seeing a page refresh, along with the serialized data appearing in the URL as if you used GET in your ajax.

The simple solution is just make sure the button element was not within the bounds of the form element:

Change this:

<form id='myForm'>
    <!--Some inputs, selects, textareas, etc here-->
    <button id='mySubmitButton'>Submit</button>
</form>

to:

<form id='myForm'>
    <!--Some inputs, selects, textareas, etc here-->
</form>
<button id='mySubmitButton'>Submit</button>

Obviously without seeing all your code, I have no idea if this is the case for your issue, but there is only one reason I have ever seen behavior you are describing and this is it.

Jakobud
Actually, the real trick is to, in your click handler, call the event's `preventDefault()` method. That will prevent the browser's native action from being performed.
Sixten Otto
Keep the button inside the form, but use the form's submit handler and return false`$('#myForm').submit(function() {var data = this.serialize(); $.post(this.attr('action'), data, function() {alert('done!')}); return false});`
lenkite
A: 

One more possible reason for this issue: If you have a form without any sort of submission action assigned to it, whenever you press the "ENTER" key while filling out the form, the form will be submitted to the current URL, so you will see the serialized data appear in the URL as if you were using a GET ajax transaction. A simple solution to this problem, just prevent ENTER from submitting the form when its pressed:

//Prevent Form Submission when Pressing Enter
$("form").bind("keypress", function(e) {
if (e.keyCode == 13)
    return false;
});
Jakobud