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);
}
Related
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 } ?>
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 have following code to get directories of folder ,
<?php
$path = 'templates';
$files = scandir($path);
foreach($files as $result) {
if ($result != "." && $result != ".." && $result != "desktop.ini")
{
echo '<img src="img/folder.png" width="40px"><a name="'.$result.'" class = "folderLink" href="#">'.$result.'</a> <input type="hidden" name="'.$result.'" value="'.$result.'"></img><br><div class="fileListInner"></div>';
}
}
?>
Above code returns dynamic number of folder names. This code is working fine and displayed folder list on success. Here is my form,
<form id="t-files">
<a style="margin-left:160px;" class="list-directories" href="#">Select File Path</a><br><br>
<div id="fileList"></div>
</form>
Now I want to go inside each folder and list sub folders. To do it I get class name of each link and on click even call ajax function. here is the code,
// load directories - inner (settings)
$(document).on("click",".folderLink",function(e){
e.preventDefault();
$.ajax({
type: 'post',
url: 'list-directories-inner.php',
dataType: 'text',
data: $('#t-files').serialize(),
success: function (data) {
$('#fileList').html(data);
}
});
exit();
});
And list-directories-inner.php file,
<?php
foreach ($_POST as $key => $value){
echo "".$key."<br>";
}
$path = 'templates';
$files = scandir($path);
foreach($files as $result) {
if ($result != "." && $result != ".." && $result != "desktop.ini")
{
// echo '<img src="img/folder.png" width="40px">'.$result.'</img><br>';
}
}
?>
How can I pass clicked link( hidden input) name value instead of pass all hidden values? Because in the list-directories-inner.php file I want to get clicked link value to set path. Something like 'templates/post value'. I'm thinking for hours. Please help.
Not sure which link your talking about ect but I gather its the following:
<img src="img/folder.png" width="40px"><a name="'.$result.'" class = "folderLink" href="#">'.$result.'</a> <input type="hidden" name="'.$result.'" value="'.$result.'"></img><br><div class="fileListInner"></div>
If so you could add the $resultvalue to the link as a data attribute so:
<img src="img/folder.png" width="40px" /><a name="'.$result.'" class = "folderLink" href="#" data-path="'.$result.'">'.$result.'</a><br><div class="fileListInner"></div>
Notice the data-pathattribute. Then get the value on the click event.
$(document).on("click",".folderLink",function(e){
e.preventDefault();
var path = $(this).data('path');
getInnerDirectoryList(path);
});
function getInnerDirectoryList(path){
$.ajax({
type: 'post',
url: 'list-directories-inner.php',
dataType: 'text',
data: {path_url: path},
success: function (data) {...},
error: function(msg){....}
});
}
Might have something like the above?
here is a jsbin of a simple version:
https://jsbin.com/yajefi/edit?html,js,output
You should try declaring a function that takes the input id of the clicked folder which will contain the required field instead of the generic function which gets called on every click of a .folderLink class.
Simon's answer should work, but here is an alternative.
You can get the value of the hidden input (since it's the same value as the hidden input's name) like this.
$(document).on("click",".folderLink",function(e){
var folder = $(this).siblings('input:hidden').val();
e.preventDefault();
$.ajax({
type: 'post',
url: 'list-directories-inner.php',
dataType: 'text',
data: {folder: folder},
success: function (data) {
$('#fileList').html(data);
}
});
});
So i have a autocomplete in one of my views, that is working, now i want to add a feature where users searches for product writtes in some key words finds it and selects it, when the name of the product is selected i want to dynamically fill in price for that product, the info is in the database, how can I achieve this?
My JQuery for autocomplete
$(function(){
var controller_path = document.getElementById("get_controller_path").value;
$("#product").autocomplete({
source: controller_path
});
});
My view where i want dynamically the price to popup when autocomplete suggestion is selected:
<td><input type="text" id="product" name="prodname"></td>
<input type="hidden" id="get_controller_path" value="<?echo base_url().'admin_site_offers_ctrl/get_product';?>">
<td><input style="width: 60px" type="text" name="price" id="price"></td>
Controller for autocomplete
public function get_product(){
$this->load->model('offers_for_clients_model');
if (isset($_GET['term'])){
$q = strtolower($_GET['term']);
$this->offers_for_clients_model->get_product($q);
}
}
Model for that autocomplete functionality:
function get_product($q){
$this->db->select('*');
$this->db->like('nosauk_lv', $q);
$query = $this->db->get('produkti');
if($query->num_rows > 0){
foreach ($query->result_array() as $row){
$row_set[] = htmlspecialchars_decode(stripslashes($row['nosauk_lv'])); //build an array
}
echo json_encode($row_set); //format the array into json data
}
}
How should i approach this? Any pointers to right direction would be amazing! Thanks!
P.S The autocomplete is wokring no worries about that.
You can try like this
$("#product").autocomplete({
source: function( request, response ) {
$.ajax({
url: customurl,
data: {term: request.term},
dataType: "json",
success: function( data ) {
response( $.map( data, function( item ) {
// you can set the label value
return {
label: item.value,
value: item.value,
}
}
}));
}
});
},
select: function( event, ui )
{
// Here again you can call ajax function to get the product price
var prodname=$('#prodname').val(ui.prodid);
getproductprice(prodname);
},
change: function( event, ui )
{
var prodname=$('#prodname').val(ui.prodid);
getproductprice(prodname);
}
});
Please make sure in your model get the id of product also in $row_set[].
In html declare like this
<input type="hidden" name="prodname" id="prodname"> // Here you will get product name id after select the productname
In getproductprice function you can call the ajax function to get the price
function getproductprice(prodname)
{
if(prodname>0)
{
$.ajax({
url:customurl,
data: "prodid="+prodname,
dataType: "json",
success: function( data ) {
$('#price').val(data['price']); // whatever your varaible
}
});
}
}
I think this will help to solve your problem. Thanks
Sorry for late reply this worked for me ended up doing this:
$(function(){
var controller_path = document.getElementById("get_controller_path").value;
$("#product").autocomplete({
source: controller_path, // ceļš uz kontrolieri kur atrodas metode, admin_site_offers_ctrl
select: function(a,b){
$(this).val(b.item.value); //grabed the selected value
getProductsOtherInfo(b.item.value);//passed that selected value
}
});
});
Other function made request to database based on the selected values name
and loaded them in the appropriate fields that i needed, like this:
function getProductsOtherInfo(name){
var site_url = document.getElementById('get_products_other_info').value;
/*alert(site_url);*/
$.post(site_url, {
name : name,
site_url : site_url
},
function(rawdata){
var myObject = JSON.parse(rawdata);
$('#cena_pirms_atl').val(myObject[0].cena_ls);
$('#iepcena').html(myObject[0].ped_ien_ls);
$('#nom_id').val(myObject[0].ID);
getPZtotals();
});
}
The controller:
function get_products_other_info(){
$this->load->model('offers_for_clients_model');
$name = trim($_POST['name']);
$data['products_other_info'] = $this->offers_for_clients_model->get_products_other_info($name);
echo json_encode($data['products_other_info']);
}
The model:
function get_products_other_info($name){
$decode_name = htmlspecialchars(stripslashes($name));
$query = $this->db->where('nosauk_lv', $decode_name)->get('produkti')->result();
return $query;
}
View:
<input type="hidden" name="nom_id" id="nom_id">
<td><input style="width: 60px" type="text" name="cena_pirms_atl" id="cena_pirms_atl"></td>
<td id="iepirkcens"><span id="iepcena"></span></td>
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.