Updating multiple records in PHP using ajax - php

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.

Related

$_SESSION is conflicting with $_FILES

I have a form that had a file type input to upload images, but it would always show up the "notice: undefined index" and I saw that the $_FILE was coming empty, but none of the answers that I found online have helped me.
I have a project where after the user registers he has to login and his first page he confirms his data and insert some new ones, one of this new ones is a picture that he can upload, as I said, my initial problem was that the $_FILES was always coming up empty, I searched online and this is a fairly common error but none of the answers have helped me, after a lot of trying I found out what the problem is, but I still have no Idea why, or how to fix it.
At the start of the page that I talked about there's this bit off code here:
if(isset($_SESSION['logado'])){
$dados = $_SESSION['dadosUsu'];
}else{
unset($_SESSION['dadosUsu']);
session_destroy();
header("Location: homeLandingPage.php");
}
to stop unnauthorized people into the page or create a variable with the user data so that it can be used to fill out some of the inputs with the info that the user had already registered.
I found that if I removed this bit off code, the $_FILES global started working and the code runned fine, but if the code was there the problems continued, I have no ideia why this is happening and I couldn't find anything online that talk about a session conflicting with the $_FILES global.
after that there's this bit of ajax:
$(function(){
$('.form').submit(function(){
$.ajax({
url: 'cod_alterarAcc.php',
type: 'POST',
data: $('.form').serialize(),
success: function(data){
if(data != ''){
$('.recebeDados').html(data);
document.getElementById('visor1').value = '<?= $dados['nomeUsu']; ?>';
document.getElementById('visor2').value = '<?= $dados['emailUsu']; ?>';
document.getElementById('visor3').value = '<?= $dados['emailUsu']; ?>';
document.getElementById('visor4').value = '';
document.getElementById('visor5').value = '';
document.getElementById('visor6').value = '';
}
}
});
return false;
});
});
I don't know if it's this but here it's the preview function that is called onChange on the input type file:
function previewImagem() {
var imagem = document.querySelector('input[name=img]').files[0];
var preview = document.querySelector('img[id=dup]');
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (imagem) {
reader.readAsDataURL(imagem);
} else {
preview.src = "";
}
}
here is the form that Im using:
<form enctype="multipart/form-data" class='form' method='post' action='cod_alterarAcc.php'>
<div id="img-perfil">
<img src="imagens/perfil.png" id="dup"/>
<label for="selecao-arquivo" class="selecionar-img">+</label>
<input id="selecao-arquivo" type="file" name="img" class="botao-img" onchange="previewImagem()" />
</div>
<label>Confirme seu nome:</label>
<input type="text" id="visor1" name="nome_usu" value="<?= $dados['nomeUsu']; ?>" />
<label>Altere seu email:</label>
<input type="email" id="visor2" name="email" value="<?= $dados['emailUsu']; ?>" />
<label>Confirme seu email:</label>
<input type="email" id="visor3" name="confirmaEmail" value="<?= $dados['emailUsu']; ?>" />
<label>Sua senha:</label>
<input type="password" id="visor4" name="senha" />
<label>Confirme sua senha:</label>
<input type="password" id="visor5" name="confirmaSenha" />
<label>Insira seu cpf:</label>
<input type="text" id="visor6" name="cpf_usu" />
<div class='recebeDados'></div>
<input type="submit" value="confirmar" />
</form>
on the cod_alterarAcc.php page has some validations using filter_input_array() and then I have this:
$extensao = strtolower(substr($_FILES['img']['name'], -4));
$novo_nome = sha1(time()) . $extensao;
$diretorio = "imgsBanco/";
$ext = strtolower(substr($_FILES['img']['name'], -3));
$tipos = array("png","jpg","gif");
$imagem = $diretorio.$novo_nome;
I have some more validation regarding the other inputs and then this, it's the first time that I use the session in this page:
if (in_array($ext, $tipos)) {
if (move_uploaded_file($_FILES['img']['tmp_name'], $imagem)) {
$codAcesso = $_SESSION['dadosUsu']['codAcesso'];
$codUsu = $_SESSION['dadosUsu']['codUsu'];
$senhaEncript = Bcrypt::hash($infoPost['senha']);
after that I do an update on everything in the database, including the image url which is the $imagem variable, after that I only look at the session one more time to send the user to another page depending on it's user type.
I've also tested for most of the possibilities in here Why would $_FILES be empty when uploading files to PHP? and it didn't worked
Like I said, apparently the only thing that it's messing with the $_FILES it's that part where I use the session on the first page, if someone could help me fix this problem and explain why it's happening in the first place I would appreciate it a lot.
It seems that the default action of the form is conflicting with your AJAX, but if you want to use only AJAX in uploading your file then you want to prevent the default action of the form. Your AJAX request should be look like this.
$('.form').submit(function(e){
e.preventDefault(); // Preventing the default action of the form
var formData = new FormData(this); // So you don't need call serialize()
$.ajax({
url: 'cod_alterarAcc.php',
type: 'POST',
data: formData,
success: function (data) {
if(data != ''){
$('.recebeDados').html(data);
document.getElementById('visor1').value = '<?= $dados['nomeUsu']; ?>';
document.getElementById('visor2').value = '<?= $dados['emailUsu']; ?>';
document.getElementById('visor3').value = '<?= $dados['emailUsu']; ?>';
document.getElementById('visor4').value = '';
document.getElementById('visor5').value = '';
document.getElementById('visor6').value = '';
}
},
cache: false,
contentType: false,
processData: false
});
});
also put your form into FormData and specify your ajax request type.
EDIT
Try to confirm if PHP able to get the data with
print_r($_POST);
print_r($_FILES);
And in your AJAX success function
console.log(data);
EDIT
Forgot to put the parameter e on form.submit

jQuery - send multidimensional form data to PHP script

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 } ?>

Displaying different data in different table columns by switching options in a select

My problem is the following:
I have an ajax function that, according to the option (of a select) selected, associate a record in a database and populate another input, i.e. a p tag.
I have two td tags that have to be populated. Different data has to be displayed, so i want that, according to the input on the first select, on the second td there will be input y, in the third input z and so on... how can it be possible? If i try to append data to more than one tag, the same data is displayed in all the td columns.
Here i attach my code
Main.php
$(document).ready(function() {
$('#L_NAME0').change(function() {
var L_NAME0 = $("#L_NAME0").val();
$.ajax({
type: "POST",
url: "elaborazione_dati.php",
data: "L_NAME0=" + L_NAME0,
dataType: "html",
success: function(msg) {
$("#L_AMT0").html(msg);
$("#L_DESSERV").html(msg);
},
error: function() {
alert("Call failed");
}
});
});
});
Form.php
<label for="L_DESSERV">Descrizione del servizio</label>
<p class="L_DESSERV" id="L_DESSERV"></p>
</td
<td class="h4">
<label for="L_AMT0">Costo del servizio</label>
<p class="L_AMT0" id="L_AMT0"></p>
</td>
elaborazione_dati.php
$tipologia_selezionata = $_POST['L_NAME0'];
$sql = "SELECT * FROM acquisti WHERE durata = '$tipologia_selezionata' ";
$q = $db->prepare($sql);
$q->execute();
$q->setFetchMode(PDO::FETCH_ASSOC);
while($caratt = $q->fetch()) {
echo '<input readonly="readonly" type="hidden" name="L_NAME0" value="'.$caratt['durata'].'"/>';
echo '<input readonly="readonly" type="hidden" name="L_AMT0" value="'.$caratt['prezzi'].'"/>';
echo $caratt['prezzi']; ?> € <?php
}
Any suggestions?
Thanks a lot!
You need to split the results and the easiest way is to return JSON from PHP and then process it on your js code to generate the fields and text.
So in PHP something like:
while($caratt = $q->fetch()) {
$result->durata = $caratt[duratta];
$result->prezzi = $caratt[prezzi];
}
echo json_encode($result);
then in your js something like:
$('#L_NAME0').change(function() {
var L_NAME0 = $("#L_NAME0").val();
$.ajax({
type: "POST",
url: "elaborazione_dati.php",
data: "L_NAME0=" + L_NAME0,
dataType: "json",
success: function(data) {
$("#L_AMT0").html("<input type='hidden' name='L_NAME0' value='"+data.duratta+"'/>"+data.duratta);
$("#L_DESSERV").html("<input type='hidden' name='L_DESSERV' value='"+data.prezzi+"'/>"+data.prezzi+"€");
},
error: function() {
alert("Call failed");
}
});
However it seems confusing that you put another input named L_NAME0 - the id of your select control, but hey, it's your code... :)

Not able to get inputs in controller or model for an ajax call submit form

I have an ajax call for a form submit; it works fine if I pass my sql arguments when I hard code them, however if I want to pass my sql query arguments with inputs (from View) in my model it says: Message: Undefined index: startDate and endDate.
Here is my View:
<?PHP
$formData2 = array(
'class' => 'form-horizontal',
'id' => 'frm2',
);
echo form_open('gallery/fetchAssociates', $formData2);
?>
<input id="startDate" class="span2" size="16" type="text" />
<input id="endDate" class="span2" size="16" type="text" />
<input type="submit" class="btn btn-primary"
value="Submit" id="querystartEnd" name="querystartEnd" />
<?PHP
echo form_close();
?>
and my javascript for AJAX call is as following:
$.ajax({
type: "POST",
async: false,
dataType: "json",
?>",
url: "<?php echo base_url('gallery/fetchAssociates') ?>",
success: function(data) {
html = "<table id='myTable'><thead><tr id='test'><th>ID</th><th>Start Date</th><th> LName</th></tr></thead><tbody id='contentTable'>";
for (var i = 0; i < data.length; i++)
{
html = html + "<tr id='trResponses' ><td><div >" + data[i]['id']
+ " </div></td><td><div >" + data[i]['start'] +
"</div> </td><td><div >" + data[i]['username'] +
"</div></td></tr>";
}
html = html + "</tbody></table>";
$("#resultFrm2").html(html);
},
error: function()
{
alert('error');
}
});
and here is my controller:
public function fetchAssociates() {
//echo($_POST["startDate"]);
//echo($_POST["endDate"]);
//die();
$this->load->model('user_model');
echo json_encode($this->user_model->getAll());
}
and my Model method is as following:
public function getAll()
{
$wtc = $this->load->database('wtc', TRUE);
$sql = "SELECT username, MIN(timeIn) as start
FROM tc_timecard
GROUP BY userid having MIN(timeIn) > ? and MIN(timeIN) < ?
order by MiN(timeIN);";
//$q = $wtc->query($sql, array('2013-01-08', '2013-01-23'));
$q = $wtc->query($sql, array($this->input->post('startDate'),
$this->input->post('endDate')));
if ($q->num_rows() > 0)
{
foreach ($q->result() as $row)
{
$data[] = $row;
}
return $data;
}
}
As you see my comments in my code: if I have
//echo($_POST["startDate"]);
//echo($_POST["endDate"]);
uncommented in firebug in response it says "Message: Undefined index: startDate and endDate."
Also in my controller if I have
// $q = $wtc->query($sql, array('2013-01-08', '2013-01-23'));
un-commented it works but once I want to pass the inputs by the following line of code it does not work :
$q = $wtc->query($sql, array($this->input->post('startDate'), $this->input->post('endDate')));
What can be the reason that I cannot access my inputs in my controller or Model?
If it is not clear for you, please let me know which part you need more clarification.
EDITED:
It is worth mentioning that my ajax call is inside the following block:
$('#frm2').submit(function(e)
{
e.preventDefault();
//My AJAX call here
});
Many thanks in advance,
You are not passing any data through ajax
// Collect data from form which will be passed to controller
var data = {
start_data : $('#startDate').val(),
start_data : $('#endDate').val(),
}
$.ajax({
type: "POST",
async: false,
dataType: "json",
data : data // data here
url: "<?php echo base_url('gallery/fetchAssociates') ?>",
success : function(data){
// Success code here
},
error: function(data){
// error code here
}
})

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