jquery serialize and $.post - php

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;

If you are using a <button> element to activate the serialize and ajax, and if that <button> element is within the form element, the button automatically acts as a form submission, no matter what other .click assignment you give it with jQuery.
type='submit'
<button></button> and <button type='submit'></button> are the same thing. They will submit a form if placed within the <form> element.
type='button'
<button type='button'></button> is different. It is just a normal button and will not submit the form (unless you purposely make it submit the form via JavaScript).
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.
Possible solutions
1 - Make the <button> type button. As explained above, this will prevent the button from submitting the form.
Before:
<form id='myForm'>
<!--Some inputs, selects, textareas, etc here-->
<button id='mySubmitButton'>Submit</button>
</form>
After:
<form id='myForm'>
<!--Some inputs, selects, textareas, etc here-->
<button type='button' id='mySubmitButton'>Submit</button>
</form>
2 - Move the <button> element outside the <form> element. This will prevent the button from submitting the form.
Before:
<form id='myForm'>
<!--Some inputs, selects, textareas, etc here-->
<button id='mySubmitButton'>Submit</button>
</form>
After:
<form id='myForm'>
<!--Some inputs, selects, textareas, etc here-->
</form>
<button id='mySubmitButton'>Submit</button>
3 - Add in the preventDefault() into the button click handler to prevent the form from being submitted (it's default action):
$("#addShowFormSubmit").click(function(event){
event.preventDefault();
var perfTimes = $("#addShowForm").serialize();
$.post("includes/add_show.php", {name: $("#showTitle").val(), results: perfTimes }, function(data) {
$("#addShowSuccess").empty().slideDown("slow").append(data);
});
});
Obviously without seeing all your code, I have no idea if this is the case for your issue, but the only reason I have ever seen behavior you are describing is because the submit button was a <button> without a type specified.

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

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) {...});
});

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.

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));
});

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.

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;
});

Related

Recaptcha invisible never sends form name in post [duplicate]

Ok, this is less of a question than it is just for my information (because I can think of about 4 different work arounds that will make it work. But I have a form (nothing too special) but the submit button has a specific value associated with it.
<input type='submit' name='submitDocUpdate' value='Save'/>
And when the form gets submitted I check for that name.
if(isset($_POST['submitDocUpdate'])){ //do stuff
However, there is one time when I'm trying to submit the form via Javascript, rather than the submit button.
document.getElementById("myForm").submit();
Which is working fine, except 1 problem. When I look at the $_POST values that are submitted via the javascript method, it is not including the submitDocUpdate. I get all the other values of the form, but not the submit button value.
Like I said, I can think of a few ways to work around it (using a hidden variable, check isset on another form variable, etc) but I'm just wondering if this is the correct behavior of submit() because it seems less-intuitive to me. Thanks in advance.
Yes, that is the correct behavior of HTMLFormElement.submit()
The reason your submit button value isn't sent is because HTML forms are designed so that they send the value of the submit button that was clicked (or otherwise activated). This allows for multiple submit buttons per form, such as a scenario where you'd want both "Preview" and a "Save" action.
Since you are programmatically submitting the form, there is no explicit user action on an individual submit button so nothing is sent.
Using a version of jQuery 1.0 or greater:
$('input[type="submit"]').click();
I actually was working through the same problem when I stumbled upon this post. click() without any arguments fires a click event on whatever elements you select: http://api.jquery.com/click/
Why not use the following instead?
<input type="hidden" name="submitDocUpdate" value="Save" />
Understanding the behavior is good, but here's an answer with some code that solved my problem in jquery and php, that others could adapt. In reality this is stripped out of a more complex system that shows a bootstrap modal confirm when clicking the delete button.
TL;DR Have an input dressed up like a button. Upon click change it to a hidden input.
html
<input
id="delete"
name="delete"
type="button"
class="btn btn-danger"
data-confirm="Are you sure you want to delete?"
value="Delete"></input>
jquery
$('#delete').click(function(ev) {
button.attr('type', 'hidden');
$('#form1').submit();
return false;
});
php
if(isset($_POST["delete"])){
$result = $foo->Delete();
}
The submit button value is submitted when the user clicks the button. Calling form.submit() is not clicking the button. You may have multiple submit buttons, and the form.submit() function has no way of knowing which one you want to send to the server.
Here is another solution, with swal confirmation. I use data-* attribute to control form should be send after button click:
<button type="submit" id="someActionBtn" name="formAction" data-confirmed="false" value="formActionValue">Some label</button>
$("#someActionBtn").on('click', function(e){
if($("#someActionBtn").data("confirmed") == false){
e.preventDefault();
swal({
title: "Some title",
html: "Wanna do this?",
type: "info",
showCancelButton: true
}).then(function (isConfirm) {
if (isConfirm.value) {
$("#someActionBtn").data("confirmed", true);
$("#someActionBtn").click();
}
});
}
});
i know this question is old but i think i have something to add... i went through the same problem and i think i found a simple, light and fast solution that i want to share with you
<form onsubmit='realSubmit(this);return false;'>
<input name='newName'/>
<button value='newFile'/>
<button value='newDir'/>
</form>
<script>
function getResponse(msg){
alert(msg);
}
function realSubmit(myForm){
var data = new FormData(myForm);
data.append('fsCmd', document.activeElement.value);
var xhr = new XMLHttpRequest();
xhr.onload=function(){getResponse(this.responseText);};
xhr.open('POST', 'create.php');
// maybe send() detects urlencoded strings and setRequestHeader() could be omitted
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send(new URLSearchParams(data));
// will send some post like "newName=myFile&fsCmd=newFile"
}
</script>
summarizing...
the functions in onsubmit form event are triggered before the actual form submission, so if your function submits the form early, then next you must return false to avoid the form be submitted again when back
in a form, you can have many <input> or <button> of type="submit" with different name/value pairs (even same name)... which is used to submit the form (i.e. clicked) is which will be included in submission
as forms submitted throught AJAX are actually sent after a function and not after clicking a submit button directly, they are not included in the form because i think if you have many buttons the form doesn't know which to include, and including a not pressed button doesn't make sense... so for ajax you have to include clicked submit button another way
with post method, send() can take a body as urlencoded string, key/value array, FormData or other "BodyInit" instance object, you can copy the actual form data with new FormData(myForm)
FormData objects are manipulable, i used this to include the "submit" button used to send the form (i.e. the last focused element)
send() encodes FormData objects as "multipart/form-data" (chunked), there was nothing i could do to convert to urlencode format... the only way i found without write a function to iterate formdata and fill a string, is to convert again to URLSearchParams with new URLSearchParams(myFormData), they are also "BodyInit" objects but return encoded as "application/x-www-form-urlencoded"
references:
https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
https://developer.mozilla.org/en-US/docs/Web/API/FormData
https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/requestSubmit#usage_notes (proves that form.submit() does not emulate a submit button click)
Although the acepted answer is technicaly right. There is a way to carry the value you'd like to assign. In fact when the from is submited to the server the value of the submit button is associated to the name you gave the submit button. That's how Marcin trick is working and there is multiple way you can achive that depending what you use. Ex. in jQuery you could pass
data: {
submitDocUpdate = "MyValue"
}
in MVC I would use:
#using (Html.BeginForm("ExternalLogin", "Account", new { submitDocUpdate = "MyValue" }))
This is actually how I complied with steam requirement of using thier own image as login link using oAuth:
#using (Html.BeginForm("ExternalLogin", "Account", new { provider = "Steam" }, FormMethod.Post, new { id = "steamLogin" }))
{
<a id="loginLink" class="steam-login-button" href="javascript:document.getElementById('steamLogin').submit()"><img alt="Sign in through Steam" src="https://steamcommunity-a.akamaihd.net/public/images/signinthroughsteam/sits_01.png"/></a>
}
Here is an idea that works fine in all browsers without any external library.
HTML Code
<form id="form1" method="post" >
...........Form elements...............
<input type='button' value='Save' onclick="manualSubmission('form1', 'name_of_button', 'value_of_button')" />
</form>
Java Script
Put this code just before closing of body tag
<script type="text/javascript">
function manualSubmission(f1, n1, v1){
var form_f = document.getElementById(f1);
var fld_n = document.createElement("input");
fld_n.setAttribute("type", "hidden");
fld_n.setAttribute("name", n1);
fld_n.setAttribute("value", v1);
form_f.appendChild(fld_n);
form_f.submit();
}
</script>
PHP Code
<?php if(isset($_POST['name_of_button'])){
// Do what you want to do.
}
?>
Note: Please do not name the button "submit" as it may cause browser incompatibility.

Collect form data for ajax submission

I have a database which has over 50 items in it which need to be checked and possibly edited. I have a web page which pulls the data from the database using php and displays it as values in a webform. Then I have a series of submit buttons at the bottom of the page, depending on what the user wants to do. Each button uses an onclick method to call a javascript function.
In the case where some changes need to be made, the user will make edits directly in the webform. For example, in a textarea, the value of the textarea will display the current content of the database item. The user can then edit the content. Clicking a "Save Changes" button calls an ajax function to send the data back to the server using a POST request.
The problem I am having, probably simple to someone who knows how, is how to collect all the updated data from the different form components to send to the server in the variable "FormData" below (presumably an array). Is there a way to do this all at once, or do I have to step through every one of the form elements and add them to the array one by one? "msg" refers to a <div id="msg"></div> where a message from the server page will be displayed.
My ajax function so far is:
function callsave() {
var xmlHttp, FormData;
xmlHttp = new XMLHttpRequest;
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
document.getElementById("msg").innerHTML = xmlHttp.responseText;
}
}
xmlHttp.open("POST", "savechanges.php", true);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.send(FormData);
}
The submit button at the end of the form is:
<input type="button" value="Save Changes" id="save" onClick="callsave();">
Many thanks for pointing me in the right direction. BTW, this is my first ajax coding.
If you're using jQuery, it can be easy by FormData=$('#formId').serialize(),
serialize() will return all form data in query string style, like "name=AAA&action=BBB"
I'm not sure what your html is like but you can assign a unique id to each form button (this can be done in php by assigning the primary key of your the row in the db) and submit button so that you can get the form you need to submit from the id of the submit button.
For example, if your form html is like this :
<form id="data-<?php //put the primary key of the row here ?>">
<!-- rest of your form attributes here -->
<input type="Submit" id="submit" class="submit" onClick="callSave(<?php //same primary key as your form?>)" />
</form>
As for ajax, I would suggest that you use jQuery's $.ajax function as its much easier to code than in native js.
you would do something like in your callsave function
function callSave(formId)
{
$.ajax({
type : 'POST',
url : //your post url,
data : $("#data" + formId).serialize(),
success : function(data){
$("#msg").text(data);
}
});
}
Setting up jQuery is a breeze. Follow this link
"...how to collect all the updated data from the different form components..."
Without knowing what's inside your full form and your handler (savechanges.php),
you could pull each POST value from your form by using this snippet in savechanges.php:
foreach ($_POST as $key=>$value) {
$post_values=$key.": " . $value . "\n";
}

How do I post to a new php page with jquery

I am trying to post the element information that jQuery pulls, when a user clicks on table cell, to a new page that will use that information (an id in this case) in a sql query. i.e., the user clicks a cell and the job he/she clicks has an id of 25, that is to be passed to my php page that queries the database for the job with that id and then populates the page with said information. The user can then alter the information from the query and submit it to update the database table. I have the id from the click function and a success alert tells me that the info was posted. The problem is that when the page is opened it states that the posted name index is undefined.
Here is my script to get the information:
<script>
$(document).ready(function()
{
$("table.jobs tbody td#job").click(function()
{
var $this = $(this);
var col = $this.text();
var LeftCellText = $this.prev().text();
if (col == '')
alert("Please pick another column");
else
$.ajax(
{
type:"POST",
url:"../php/jobUpdate.php",
data:"name=" + LeftCellText,
success: function()
{
window.location = "../php/jobUpdate.php";
}
});
});
});
</script>
and here is the simple php page it is sending to:
$name = $_POST['name'];
echo $name;
I am new to jQuery, and I cannot figure out why this is not working?
When you use ajax, the second page ../php/jobUpdate.php processes the data sent by the first page, and returns a value (or even a huge string of html, if you want).
The first page receives the new data in the ajax routine's success function and can then update the current page. The updating part happens in the success: function, so you're on the right track.
But in your success function, you are redirecting the user to the 2nd page -- after already being there and processing the data. Redirecting them is probably not what you want to do.
Try replacing this:
success: function()
{
window.location = "../php/jobUpdate.php";
}
with this:
success: function(data)
{
alert(data);
}
If you want to see how to update the first page with the data received via ajax, try adding an empty DIV to your html, like this:
<div id="somestuff"></div>
Then, in the success: function of the ajax routine, do this:
$('#somestuff').html(data);
(Note that the term "data" can be any name at all, it only needs to match the name used in the function param. For example:
success: function(whatzup) {
alert(whatzup);
}
From your comment to my previous post, it seems that you don't need ajax at all. You just need a form in your HTML:
<form id="MyForm" action="../php/jobUpdate.php" method="POST">
<input type="hidden" id="jobID" name="yourJobID">
</form>
Note that forms are invisible until you put something visible inside them.
You can have select controls (dropdowns) in there, or all form elements can be invisible by using hidden input fields (like the HTML just above), which you can populate using jQuery. Code to do that would look something like this:
<script>
$(document).ready(function() {
$("table.jobs tbody td#job").click(function() {
var $this = $(this);
var col = $this.text();
var LeftCellText = $this.prev().text();
//Set value of hidden field in form. This is how
//data will be passed to jobUpdate.php, via its `name` param
$('#jobID').val(LeftCellText);
if (col == '')
alert("Please pick another column");
else
$('#myForm').submit();
});
});
</script>
If you add more values to your form to send over to jobUpdate.php, just ensure that each element has a name, such as <input type="text" name="selectedJobType"> (this element, type="text", would be visible on screen).
In the jobUpdate.php file, you would get these values thus:
$SJT = $_POST['selectedJobType'];
$id = $_POST["yourJobID"];
//Use these vars in MySQL search, then display some HTML based on results
Note that the key referenced in the $_POST[] array (selectedJobType / yourJobID) is always identical to the name specified in the HTML tag. These names are case sensitive (and spelling counts, too).
Hope this isn't TMI, just wish to cover all the bases.
On your success function causing the window to reload will delete any of the variables passed in via .ajax.
What you can try is returning the data and use it in the existing page.
success: function(msg) {
$('#someDiv').append(msg);
}
The reason the index is not defined is because you are using a string in the data-argument, however, that is actually an array-like object. :)
data: { name: col }
that should be the line you need to change. Otherwise I have not seen any problems. Also if I can give you a little idea, I wouldn't use POST actually. In fact, I'd use GET. I can not confirm if that is saver or not, but using $_SERVER["HTTP_REFFERER"] you can check from where that request is coming to determine if you want to let it pass or not.
The way I would suggest is, that you sent the ID in a GET-request and have the PHP code return the data using json_decode(). Now in jQuery, you can use $.getJSON(url, function(data){}) - which is, for one, shorter and a bit faster.
Since you probably will crop the URL yourself here, make sure that you use a function like intVal() in JS to make sure you are sending an intenger instead of a malicious string :)

Submit JQuery array alongside PHP form data to PHP script

I'm dabbling in JQuery, and have run up against an issue I'm not quite able yet to figure out. Here is the context:
I have a HTML form, utilising MySQL & PHP, used to edit a CMS post. This post would have a list of attachments (eg. images for a gallery, or downloadable files). Using JQuery, the user can click on these list item elements and edit the details of each attachment in a revealed div (eg. delete image, add capton, etc).
Currently when the user opts to delete an attachment, I simply fade its opacity and provide a new option to the user to 'undo' the delete. Upon submission of the complete parent form (the CMS post), I want to gather all the attachments still marked for deletion, and submit their GUID's to the PHP script that is doing all the rest of the post updating for me.
Option A:
Is it possible to submit a JQuery array to a PHP script alongside the data being sent naturally to the action script by the form inputs?
Option B:
Is it possible to fill / empty a (hidden) form input array dynamically with JQuery, which could then be submitted naturally to the action script with everything else?
I am currently at the stage where I am filling a Javascript array with the necessary GUIDs, but now don't know what to do with it.
//populate deleted attachments array
$(document).ready(function() {
$('#post-editor').submit(function() {
var arrDeleted = [];
$('.deleted-att').each(function(){
arrDeleted.push({guid: $(this).attr("data-guid")});
});
//do something with array
});
});
JSON.stringify the arrDeleted and put them in a hidden field in the form, that will be submitted.
$('#post-editor').submit(function() {
var arrDeleted = [];
$('.deleted-att').each(function(){
arrDeleted.push({guid: $(this).attr("data-guid")});
});
$('#post-hidden').val(JSON.stringify(arrDeleted));
});
Somewhere in your html:
<form id="post-editor">
<input type="hidden" id="post-hidden" name="post-hidden" />
<!-- ... other fields ... -->
</form>
Then json_decode($_POST['post-hidden']) on the server to get the array.
create a hidden field in your form..put the arrDeleted value in your input through jquery
and post the form..use json_decode() to get the posted value...
<input type="hidden" id="hidden"/>
JQUERY
$(document).ready(function() {
$('#post-editor').submit(function() {
var arrDeleted = [];
$('.deleted-att').each(function(){
arrDeleted.push({guid: $(this).attr("data-guid")});
});
$('#hidden').val(JSON.stringify(arrDeleted));
});
});
The easiest to do what you want would be to add a hidden input field to your HTML form
Then in jQuery do something like this
$('form').submit(function() {
$('#hidden_id_field').val( arrDeleted.join(',') );
});
arrDeleted in this case being your array you've already setup. It would sent a comma separated list then in your PHP you split up the values and act as you want.
Usually I just do AJAX and send JSON to my app. But the above approach will work if you really want to go about it like that. And it has the advantage of not actually deleting anything on the server until you submit the form.
You may be looking to do this with a traditional form submit and refresh, but if you're willing to submit the request asynchronously, you can use jQuery to submit the form and serialize the array of deleted items:
var form = $('#post-editor');
form.submit(function() {
var arrDeleted = [];
$('.deleted-att').each(function(){
arrDeleted.push({ // The format $.serializeArray produces.
name: "deleted",
value: $(this).attr("data-guid")
});
});
var formData = form.serializeArray();
// Add values to existing form data
formData = formData.concat(arrDeleted);
$.ajax({
url: form.attr('action'),
data: formData
// Other ajax options
});
});
On the PHP side, referring to $_REQUEST['deleted'] will return an array of GUIDs.

How to POST without using Submit?

I want to post the Form but don't want to use the Submit method. If I use JQuery, how to handle the Form input controls?
You can use the jQuery AJAX .post function functions. An example (untested, but should be working):
<script>
function postit(obj) {
var data = $(obj).serialize();
$.post($(obj).attr("action"), data, function() {
//Put callback functionality here, to be run when the form is submitted.
});
}
</script>
<form action="posthandler.php" onsubmit="postit(this); return false;">
<input type="text" name="field">
<input type="submit">
</form>
Also, read about serialize
(Of course you need to include the jQuery library in your code before using this code).
Just create a function that is triggered by whatever event you want, for example: (found this code in another question)
function example() {
// get all the inputs into an array.
var $inputs = $('#myForm :input');
// not sure if you wanted this, but I thought I'd add it.
// get an associative array of just the values.
var values = {};
$inputs.each(function() {
values[this.name] = $(this).val();
});
}
After that you can do whatever you want with the input values. You might want to consider using more advanced processing though, there are plenty of plugins that can provide this kind of functionality.
I am not sure if I understood the question correctly.
If you don't want to use submit(), you can do the same thing via jQuery.post() using Ajax. The main difference is you have to construct the key value data from the input fields yourself rather than the browser doing it automatically and you won't get a page refresh.
Either Post function or Load function will work.
#PRK are you trying to post the Form when the page loads or when a user hit a button?
load(url, parameters, callback)
eg:
$("#loadItHere").load("some.php", {somedata: 1});

Categories