jQuery - send multidimensional form data to PHP script - php

I have a jQuery script that adds hidden inputs into a form whenever a certain .class input undergoes a change. Depending on user input, it generates values for other uneditable columns which also get pushed into a form as hidden inputs.
The form output looks like this:
<input type="hidden" name="[1008016BSTL][1][part]" value="1008016BSTL" />
<input type="hidden" name="[1008016BSTL][1][price]" value="123" />
<input type="hidden" name="[1008016BSTL][1][priceExVat]" value="102.50" />
<input type="hidden" name="[1008016BSTL][1][fee]" value="10.53" />
<input type="hidden" name="[1008016BSTL][1][profit]" value="68.41" />
This is just one set of data I'm trying to capture, but it's the same for the others, save the original key and sub-key.
My form wrapper looks like this:
<form method="post" id="submit-form" enctype="multipart/form-data">
<input type="submit" value="Save" />
</form>
With my AJAX looking like:
$('form#submit-form').submit(function(e)
{
e.preventDefault();
let data = $('form#submit-form').serializeArray();
$.ajax({
url: '/save-pricing.php',
data: {data: JSON.stringify(data)},
type: 'post',
success: function(res)
{
console.log(res)
},
error: function(res)
{
alert('Error! I won\'t tell you what it is. But, I\'ll give you a clue: 21');
console.log(res)
}
})
})
I've also tried (for setting data):
let data = $('form#submit-form').serialize();
data = JSON.stringify(data);
$.ajax({
...
data: {data: data}
...
})
As well as omitting the .stringify() function.
This comes through to PHP like this:
<?php
echo '<pre>'. print_r($_POST, 1) .'</pre>';
/**
* Below is for .serialize() -> output is an empty array
*
* parse_str($_POST['data'], $postData)
* echo '<pre>'. print_r($postData, 1) .'</pre>';
*/
simplified output (just removing the other sets) with .serializeArray():
Array
(
[data] => [
{"name":"[1008016BSTL][1][part]","value":"1008016BSTL"},
{"name":"[1008016BSTL][1][price]","value":"123"},
{"name":"[1008016BSTL][1][priceExVat]","value":"102.50"},
{"name":"[1008016BSTL][1][fee]","value":"10.53"},
{"name":"[1008016BSTL][1][profit]","value":"68.41"}
]
)
This is OK I guess, I could probably group by name and merge into an array, but there feels like it should already do this with .serialize() on jQuery-side and then parse_str() on the PHP side.
However, as I've mentioned, parse_str() and .serialize() yield an empty array, which I can't use.
so my question is: How do I successfully send multi-dimensional form data to PHP via jQuery?
Edit
Added:
dataType: 'json'
with .serialize() and then JSON.stringify(data), removed parse_str() and it outputs:
Array
(
[\"] => Array
(
[1008016BSTL] => Array
(
[1] => Array
(
[part] => 1008016BSTL
)
)
)
)

Input fields names with brackets are not treated nicely by serializeArray. This below code will create a proper multidimentional array you can send back to the server.
$('form#submit-form').submit(function(event)
{
event.preventDefault();
//Prevent the form from submitting
var fields = {};
//This is where you're gonna store your form fields
$.each($('form#submit-form').serializeArray(), function(i, field) {
//Get values, even from multiple-selects
if (Array.isArray(fields[field.name])) {
fields[field.name].push(field.value);
} else if (typeof fields[field.name] !== 'undefined') {
var val = fields[field.name];
fields[field.name] = new Array();
fields[field.name].push(val);
fields[field.name].push(field.value);
} else {
fields[field.name] = field.value;
}
});
//Now all the fields are in the fields object
//You're now going to translate "key[subkey]" string to key[subkey] object
for (var key in fields) {
var parts = key.split(/[[\]]{1,2}/);
parts.length--;
if (parts.length) {
var val = fields[key];
delete fields[key];
addToTree(fields, parts);
setToValue(fields, val, parts);
}
//input field array names (with brackets) are mistakenly treated as strings, this fixes it
}
$.ajax({
url: '/save-pricing.php',
data: JSON.stringify(fields),
contentType: 'application/json',
type: 'post',
success: function(res) {
console.log(res)
},
error: function(res) {
alert('Error! I won\'t tell you what it is. But, I\'ll give you a clue: 21');
console.log(res)
}
})
});
/**
* Adds values to a tree.
* #link https://stackoverflow.com/questions/3663096/how-to-convert-array-to-tree
*/
function addToTree(tree, array) {
for (var i = 0, length = array.length; i < length; i++) {
tree = tree[array[i]] = tree[array[i]] || {}
}
}
/**
* Sets object values.
* #link https://stackoverflow.com/questions/13719593/how-to-set-object-property-of-object-property-of-given-its-string-name-in-ja
*/
function setToValue(obj, value, path) {
for (i = 0; i < path.length - 1; i++) {
obj = obj[path[i]];
}
obj[path[i]] = value;
}
with the PHP side using json_decode:
$data = json_decode(file_get_contents('php://input'), true);
echo '<pre>'. print_r($data, 1) .'</pre>';

For your particular issue you can the jquery.serializeJSON
Here is the link of their github https://github.com/marioizquierdo/jquery.serializeJSON
This will create the correct json object.

This is simplest solution I have for this case.
<?php if(isset($_POST["data"])) {
$post_data = urldecode($_POST["data"]);
parse_str($post_data, $form_data);
// this will give you first element of array by eliminating double quote key ('') in post data array, which is also desired
$form_data = reset($form_data);
echo '<pre>'; print_r($form_data); echo '</pre>'; exit;
} else { ?>
<form method="post" id="submit-form">
<input type="hidden" name="[1008016BSTL][1][part]" value="1008016BSTL" />
<input type="hidden" name="[1008016BSTL][1][price]" value="123" />
<input type="hidden" name="[1008016BSTL][1][priceExVat]" value="102.50" />
<input type="hidden" name="[1008016BSTL][1][fee]" value="10.53" />
<input type="hidden" name="[1008016BSTL][1][profit]" value="68.41" />
<input type="submit" value="Save" />
</form>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$("#submit-form").on('submit', function(e){
e.preventDefault();
var form_data = $("#submit-form").serialize();
$.ajax({
type: "POST",
data: {data: JSON.stringify(form_data)},
success: function(res){
console.log(res);
}
});
});
</script>
<?php } ?>

Related

Why is the array key missing the last ] when passing field data via AJAX to PHP function?

Im using this code to get an object of field input names and values to pass to an AJAX function.
var fields = {};
$("#wrap").find(":input").each(function() {
fields[this.name] = $(this).val();
});
var obj = {fields: fields};
The AJAX call to a PHP function
var data = {
'action': 'my_function',
'fields': obj,
};
jQuery.post( ajaxurl, data, function( response ) {
console.log(response);
});
The fields are:
<div id="wrap">
<input type="number" min="0" name="my_array[123][somelabel]" value="">
<input type="number" min="0" name="my_array[456][somelabel]" value="">
</div>
The PHP just does:
print_r( $_POST['fields'] );
Result & My Expected Result
In the response console log this returns an array with the first key of fields as my_array[123
I am expecting this to be my_array[123] - why is it missing the last ] ?
Change your array assignment code like below:-
var fields = []; //empty array
$("#wrap").find(":input").each(function() {
var obj = {
$(this).attr('name'): $(this).val()
}; //created object with key value pair
fields.push(obj); //add object to array
});

AJAX How to use key:value

My form:
<form action="html_post.php" method="post" id="myform">
<textarea id="textarea" placeholder="Add your comment" name="posting"> </textarea>
<input class="button" type="button" name="send" value="Send">
</form>
I have such code
$(".button").click(function () {
var content = $("#myform").serialize();
$.ajax({
url: "add_post.php",
type: "POST",
data: {
text: content,
action: "add_post"
},
success: function () {
$('#comment_block').load('list_post.php');
document.getElementById('textarea').value = "";
}
})
});
And such php:
echo mysqli_error($connection);
if (strlen($_POST['posting']) >= 5) {
$text = htmlspecialchars($_POST['posting']);
$insert = "INSERT INTO post(content) VALUE ('$text')";
mysqli_query($connection, $insert);
}
But it does not add text to db. I'm just learning ajax and it's my first experience with key:value so can you help me?
And yep, there is no shown errors
The way you've written it, there is no $_POST['posting']. Instead, $_POST['text'] contains a URL-encoded string containing all the inputs in the form, i.e. a string like "posting=blah blah blah".
What you probably want is:
$(".button").click(function () {
var content = $("#myform").serialize();
$.ajax({
url: "add_post.php",
type: "POST",
data: content + '&action=add_post',
success: function () {
$('#comment_block').load('list_post.php');
document.getElementById('textarea').value = "";
}
})
});
Based on your posted code, on the server there will be two keys set in the $_POST variable. These are the ones that you define at your ajax request in javascript: text and action.
So while you check $_POST['posting'] it does not exists, but there are $_POST['text'] and $_POST['action']. $_POST['text'] will contain all the form fields as an URL-encoded string, like "posting=xyz". In order to access these values, you could use the parse_str() php function that parses this string as it were a query string.
So the condition at the server side could be something like as follows.
if (isset($_POST['text'])) {
// $formdata passed in by reference, it will contain all the form fields
parse_str($_POST['text'], $formdata);
}
if (isset($formdata['posting']) && strlen($formdata['posting']) >= 5) {
// Perform db operation
}

I want to click the checkbox to display the database filed values in codeigniter

I want to click checkbox to show the data what i want fetch through ajax call, but it is showing database all data automatically show whats the problem please find out and help me (just i want ajax call)
Controller
//This is my controller
public function laptops()
{
$this->load->model('feature_model');
$filter = array(
'price' => $this->input->get('price'),
'name' =>$this->input->get('name')
);
$data['laptop'] = $this->feature_model->laptops_m($filter);
//echo json_encode($this->feature_model->laptops_m($filter));
$this->load->view('feature/checkbox',$data);
}
//This is my model
function laptops_m($filter = null){
$this->db->select('*')
->from('mobile_phones');
// $query = $this->db->get('laptop_notebook')->result();
// return $query;
if($filter['name']){
$this->db->where('name', $filter['name']);
}
if($filter['price']){
$this->db->where('price', $filter['price']);
}
$query = $this->db->get()->result();
return $query;
}
//This is my view
<input type="checkbox" name="name" value="acer">
<input type="checkbox" name="name" value="lenovo">
<input type="checkbox" name="price" value="1000">
<table>
<tbody>
<?php foreach ($laptop as $laptops_all) { ?>
<tr>
<td><p>Laptop <?php echo $laptops_all->name ?> </p>
</td>
</tr>
<?php } ?>
</tbody>
</table>
Ajax script:
// This is the ajax script function
<script>
$("input[checkbox]").change(function(){
$.ajax({
url: localhost/ci35/feature/laptops,
dataType: 'json',
success: function(data){
$.each(data, function(index, element) {
$("tbody").empty();
$("tbody").append("<tr><td>"+
"Laptop "+element.brand+""+
"</td></tr>");
});
}
});
You try to get data to display from GET array here:
$filter = array(
'price' => $this->input->get('price'),
'name' =>$this->input->get('name')
);
But your GET array is empty because of you don't send any data with your json request. From jQuery documentation:
data
Type: PlainObject or String or Array
Data to be sent to the
server. It is converted to a query string, if not already a string.
It's appended to the url for GET-requests. See processData option to
prevent this automatic processing. Object must be Key/Value pairs. If
value is an Array, jQuery serializes multiple values with same key
based on the value of the traditional setting (described below).
So you should iterate over checked checkboxes and add it's values to array. Then send this array via data property of ajax request.
Try this..add class="searchType" to html checkbox element, then in jquery
$('.searchType').click(function() {
alert($(this).attr('id')); //-->this will alert id of checked checkbox.
if(this.checked){
$.ajax({
url: localhost/ci35/feature/laptops,
dataType: 'json',
success: function(data){
$.each(data, function(index, element) {
$("tbody").empty();
$("tbody").append("<tr><td>"+
"Laptop "+element.brand+""+
"</td></tr>");
});
}
});
}
});
as you are printing the data through success ajax call, no need to use foreach again in view.
Also in your controller, you have to print json data.
public function laptops()
{
$this->load->model('feature_model');
$filter = array(
'price' => $this->input->get('price'),
'name' =>$this->input->get('name')
);
$data['laptop'] = $this->feature_model->laptops_m($filter);
echo json_encode( $data['laptop'] );
// $this->load->view('feature/checkbox',$data);
}

Updating multiple records in PHP using ajax

I'm needing some help with the following code. I am trying to update multiple rows in my database using an ajax call. I am not receiving any error messages and nothing is appearing in my browser log either. I can see that the click function is executing but the database query is not being executed. Can someone point me in the right direction?
Thanks for any help you can give.
Update - The code below has been updated to work. I have commented out the original, non-working code.
My input fields:
<input type="hidden" id="Opportunity_Id" name="Opportunity_Id" value="<?php echo $opportunity->Opportunity_Id; ?>"/>
<input type="hidden" id="Class_Numbers[]" name="Class_Numbers" value="<?php echo $Class_Number; ?>"/>
<input type="text" id="Class_Dates[]" name="Class_Dates" value="<?php echo $Class_Date; ?>"/>
<input type="text" id="Start_Times[]" name="Start_Times" class="col-xs-12 col-sm-11" value="<?php echo $Preferred_Start_Time; ?>"/>
<input type="text" id="End_Times[]" name="End_Times" class="col-xs-12 col-sm-11" value="<?php echo $Preferred_End_Time; ?>"/>
My jQuery function:
/*$("#test").click(function() {
$("#validation-form").ajaxForm({url: 'schedule/schedule_opportunity', type: 'post'});
var form_data = {
Opportunity_Id: $('#Opportunity_Id').val(),
Class_Number: $('#Class_Numbers').val(),
Class_Date: $('#Class_Dates').val(),
Start_Time: $('#Start_Times').val(),
End_Time: $('#End_Times').val(),
ajax: '1'
};
$.ajax({
url: "<?php echo site_url('schedule/schedule_opportunity'); ?>",
type: 'POST',
data: form_data,
dataType: 'json',
cache: false
});
return false;
})*/
$('#validation-form').submit(function(e){
e.preventDefault();
var form = $(this);
$.ajax({
url: "<?php echo site_url('schedule/update_classes'); ?>",
method: form.prop('method'),
data: $('#validation-form').serialize(),
success: function(){
alert('Success');
}
});
})
My controller:
function update_classes() {
$Opportunity_Id = $this->input->post('Opportunity_Id');
$Class_Numbers = $this->input->post('Class_Numbers');
$Class_Dates = $this->input->post('Class_Dates');
$Start_Times = $this->input->post('Start_Times');
$End_Times = $this->input->post('End_Times');
$this->ion_auth_model->update_classes($Opportunity_Id, $Class_Numbers, $Class_Dates, $Start_Times, $End_Times);
}
My model:
function update_classes($Opportunity_Id, $Class_Numbers, $Class_Dates, $Start_Times, $End_Times) {
foreach($Class_Numbers as $key => $Class_Number) {
//$Opportunity_Id = $Opportunity_Id[$key];
$Class_Date = $Class_Dates[$key];
$Start_Time = $Start_Times[$key];
$End_Time = $End_Times[$key];
$Class = array(
'Class_Date' => $Class_Date,
'Start_Time' => $Start_Time,
'End_Time' => $End_Time
);
$this->db->where('Opportunity_Id', $Opportunity_Id);
$this->db->where('Class_Number', $Class_Number);
$this->db->update('Classes', $Class);
}
}
Well, I think it's time for you to do some debugging. What's very unclear to me is how you plan to get multiple values for all the fields from the front-end, but that being said, these are the problems in your code that I see at this point:
Opportunity_Id: $('#Opportunity_Id').val() => I see no field with the ID "Opportunity_Id". (Fixed by question edit)
Class_Number: $('#Class_Numbers').val(), etc. => There is no field with the ID "Class_Numbers". There is a "Class_Numbers[]", but that will not be returned in your lookup. Same goes for all the other fields.
You seem to be under the impression that JQuery will automatically create some sort of array from your textbox values and pass them to the server. That's not going to happen.

Issue renaming directories

I want to rename directories of those whose checkbox has been checked by the user with a single click of the Update button. The textbox and checkbox values are collected in an array and sent to the server via jQuery. Firebug shows the correct array values being passed. The problem is that it renames the first checked directory to Array rather than to the new value inputted in the textbox while the other values remain unchanged.
What am I doing wrong in this code?:
HTML:
<input type="text" name="album_text[]" id="album_text" class="album_text" />
<input type="text" name="album_text[]" id="album_text" class="album_text" />
<input type="text" name="album_text[]" id="album_text" class="album_text" />
<input name="album_checkbox[]" type="checkbox" id="album_checkbox" value="' . $res. '">
<input name="album_checkbox[]" type="checkbox" id="album_checkbox" value="' . $res. '">
JQUERY:
$("#album_update").click(function() {
var album_name = new Array();
$("input[#name='album_checkbox[]']:checked").each(function() {
album_name.push($(this).val());
});
var album_text= new Array();
$("input[name='album_text[]']").each(function(){
if( $(this).val() ) {
album_text.push($(this).val());
}
});
var postData = {
"album_name" : album_name,
"album_text" : album_text,
"album_update" : $("#album_update").val()
};
//make the call
$.ajax({
type: "POST",
url: "updalbums.php",
data: postData,
dataType: "json",
success: function(data){
alert("updated");
}
});
});
PHP:
public function updateAlbum() {
if (isset($_POST['album_text']) && isset($_POST['album_name'])) {
$path = $_SERVER['DOCUMENT_ROOT'] . '/images/';
foreach ($_POST['album_name'] as $albums_name ) {
$album_text = $_POST['album_text'];
rename($path.$albums_name, $path.$album_text);
}
}
}
$album_text is an array because you are drawing straight from the $_POST global $_POST['album_text'], which is an array. You need to identify the correct index.
You could access the index like below but it seems like it would be prone to breaking.
foreach ($_POST['album_name'] as $idx => $albums_name ) {
$album_text = $_POST['album_text'][$idx];
rename($path.$albums_name, $path.$album_text);
}

Categories