Jquery Ajax call to PHP sometimes appends data twice - php

I've written a script using jQuery Ajax and PHP which should fetch data from a MySQL database and append the result as an <option> within a <select> element.
The code should work like this:
When the name in the text input changes, all options of class .modpick are removed from the <select> element. An Ajax call then connects to a PHP script which checks whether there is more than one record in the database with the same name. If not, another Ajax call connects to another PHP script which pulls the data from the database and echos it out as an <option> element. The Ajax callback then appends the data from the PHP script to the <select> element.
The problem I'm having is that sometimes the <option> element is appended twice, so when you open the <select> element it displays the same <option> twice. What is really confusing is that this doesn't happen all the time - only occassionally.
I can't figure out why this is happening, especially as it doesn't happen every time, nor can I identify whether it's a problem with the jQuery or the PHP. Any help would be greatly appreciated.
The code:
jQuery:
$(document).on('change', "#uploadname", function () {
uploadname = $(this).val();
$('.modpick').remove();
$.ajax({
url: "uploadnames.php",
type: "POST",
data: {
uploadname: uploadname
},
success: function (data) {
$('#checkulinputs').html(data);
uploademailcheck = $('#emailupcheckinput').val();
if (uploademailcheck == 'nochoose') {
uploademail = '';
$('#ulemailcheck').slideUp();
$.ajax({
url: "uploadnamesmodules.php",
type: "POST",
data: {
uploadname: uploadname
},
success: function (data) {
$(data).appendTo($('#uploadmoduleselect'));
}
});
}
}
})
})
PHP:
include_once('../../dbconnect.php');
$name = mysqli_real_escape_string($conn, $_POST['uploadname']);
$query = "SELECT * FROM marking_assignments WHERE name = '$name' ORDER BY unit ASC";
$details = $conn->query($query);
while ($row = $details->fetch_assoc()){
$modnamequery = "SELECT mod_name FROM modules WHERE module = '" . $row['unit'] . "'";
$modname = $conn->query($modnamequery);
while ($line = $modname->fetch_assoc()){
$descrip = $line['mod_name'];
}
echo '<option value="' . $row['unit'] . '" id="m' . $row['unit'] . '" class="modpick">' . $descrip . '</option>';
}
HTML (After query has been run - note the two identical <option> elements):
<form id="uploadfeedbackform" method="POST" action="uploadfeedback.php">
<input type="text" class="inputs" name="upload_name" id="uploadname" placeholder="Enter Student Name" />
<div id="checkulinputs"></div>
<div id="ulemailcheck" class="emailchecker"></div>
<select id="uploadmoduleselect" name="uploadmodules">
<option value="choose" class="choosemod">Select Module</option>
<option value="405" id="m405" class="modpick">4.05 Managing Health & Safety at Work</option>
<option value="405" id="m405" class="modpick">4.05 Managing Health & Safety at
</select>
</form>

Seems to me that your change handler can be called multiple times, leading to multiple ajax requests which (quite rightly) fire their success callbacks.
Ajax requests will just queue up rather than replacing the previous request, leading to a possible queue of pending callbacks.
You can store the ajax request in a variable and abort() the request in the event that your handler somehow gets called twice.
Example:
var myRequest;
//in your change handler...
if (myRequest)
{
myRequest.abort();
}
myRequest = $.ajax({...});
This way there will only be one active ajax request at a time, and only one success callback that is pending.

Related

Is there a way to make a form submit twice?

I'm loading values from an XML file and then updating the XML with a form on a php page. My problem is this - I have a query running a count on nodes, which works perfectly fine, but I also want to update nodes with the count and get accurate values back. When I submit my form, it submits the values as they are when I load the file, but in order to update the count properly (because I need the updated node count) I need to have it submit twice. I've tried to have it submit the form on a body onload function but from what I can ascertain when you hit the submit button it doesn't do a true full page refresh. It reloads the page but I've been unable to have it actually run any scripts or onload functions. The alternative that I thought of but can't figure out how to implement is having the count go down if I change the option value to closed.
<!DOCTYPE html>
<?php
$xml->load('test.xml');
$xpath = new DOMXpath($xml);
$liftsopen = $xpath->query("//node/Lifts-Open")->item(0);
$lift1status = $xpath->query("//areas/area[#name='Lift1']/lifts/lift[#name='Lift1']/#status")->item(0);
$lift2status = $xpath->query("//areas/area[#name='Lift2']/lifts/lift[#name='Lift2']/#status")->item(0);
$liftcount = 0;
foreach ( $xpath->query('//lifts/lift[#status="OPEN"]') as $count1 ) {
$liftcount++;
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$lift1->nodeValue = $_POST['lift1statusform'];
$lift2->nodeValue = $_POST['lift2statusform'];
$liftsopen->nodeValue = $liftcount;
$xml->save('test.xml');
}
?>
<body>
<form method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<h4>Lift1</h4>
<select name="lift1statusform" >
<option selected value="<?= htmlspecialchars($lift1status->nodeValue) ?>"><?= htmlspecialchars($lift1status->nodeValue) ?></option>
<option value="OPEN">OPEN</option>
<option value="CLOSED">CLOSED</option>
</select>
<h4>Gondola</h4>
<select name="lift2statusform" >
<option selected value="<?= htmlspecialchars($lift2status->nodeValue) ?>"><?= htmlspecialchars($lift2status->nodeValue) ?></option>
<option value="OPEN">OPEN</option>
<option value="CLOSED">CLOSED</option>
</select>
<input name="submit" type="button" value="Save"/>
</form>
</body>
</html>
used the following Ajax function to submit the form twice:
function Test() {
var form = $('form');
$.ajax({
type: 'POST',
url: form.attr('action'),
data: form.serialize(),
success: function(data) {
$.ajax({
type: 'POST',
url: form.attr('action'),
data: form.serialize(),
success: function(data) {
location.reload(true);
}
});
}
});
}
Would AJAX be a valid solution to your problem?
If you need to perform multiple "form submits", you should check out the capabilities of AJAX. Ajax allows you to send exchange data with a back-end PHP file without leaving (or even refreshing) the current page. Perhaps it is your solution.
As with most js actions, it can be event-driven (that is, triggered one-or-more-times by some event), or repeated inside a loop, etc.
AJAX is most implemented using the jQuery library:
$(document).ready(function(){
$.ajax({
type: 'post',
url: 'my_backend_file.php',
data: {varname:value}
}).done(function(recd){
console.log('data recd from PHP side, if needed: ' + recd);
});
});
although it is equally well handled in vanilla js also.
References and Other Examples:
https://stackoverflow.com/a/54332971/1447509
Should I have one form or two separate forms
https://www.html5rocks.com/en/tutorials/file/xhr2

Prevent a selected <option>-tag from being overwritten by .html()

I have a PHP file that fetches rows of car brands from a database, echoes these as "<option value=\"$brand\">" . $brand . "</option>"; and puts them inside pre-written <select>tags.
My issue is that the first item that appears in the select box is not passing its value onwards.
The value of the select box is changed by this event
$('select[name=model]').on('change', function() {
selectedModel = $("#select-model").val()
});
The <option>-tags are generated by this loop in brands.php:
while ($row = mysqli_fetch_array($result)) {
$brand = $row['brand'];
echo "<option value=\"$brand\">" . $brand . "</option>";
}
The brands are fetched by this function:
function fetchBrands() {
$.ajax({
type: "POST",
url: "script/rent/brands.php",
data: {dateFrom: selectedDateFrom,
dateTo: selectedDateTo,
destination: selectedDestination},
success: function(data) {
$("#select-brand").html(data);
}
});
}
Because the data is posted to #select-brandwith .html() I can't set a default value for the select box because it gets overwritten. Appending the options will result in duplicates etc. as fetchBrands() is dependent on a previous set of radio buttons and select boxes.
What I'd now suggest is that in your success function, add some code that gets the first element in the select tag, updates the selectedBrand, and then triggers the code that's attached to the change event.
If you refactored your code so that you added a reference to the handler code, this would make it easier.
$('select[name=model]').on('change', someFunction());
function someFunction(){
selectedModel = $("#select-model").val()
}
function fetchBrands() {
$.ajax({
type: "POST",
url: "script/rent/brands.php",
data: {dateFrom: selectedDateFrom,
dateTo: selectedDateTo,
destination: selectedDestination},
success: function(data) {
$("#select-brand").html(data);
$("#select-brand").val($("#select-brand option:first").val());
someFunction();
}
});
}
Before extra information was added:
To have an element of a <select>...</select> automatically selected on page render, you need to add the attribute selected="selected" to the <option /> you want to be selected.
Alternatively, add a hook for document load that sets the selected brand.
Or, have the first option as something like this:
<option disabled="disabled" selected="selected">Choose a Brand</option>

Pass JQuery variables to PHP variable [Simple]

I've read lots of threads on passing Jquery variables to PHP, however almost all of the posts were on the "Expert" level, and i couldn't understand a single thing (PHP/Jquery beginner here). Hopefully I can get some help.
Once the user selects from the drop down list, the script function will run. I want to get the user's selection from jquery to a php variable. From then, I want to use the user's selection to retrieve data from the database and display values on the same page itself.
I'm not getting any output.
EDITED: So this is what I did after looking at the ajax function
AFile.php
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#company').change(function(){
$.ajax({
type: 'GET',
url: '<?php echo url_mgt::getTest(); ?>',
data: 'company_name=' + $('#company').val(),
success: function(msg) {
$('#other').html(msg);
}
});
});
});
</script>
</head>
<body>
<select id="company" name="company">
<option value="Company_A">A</option>
<option value="Company_B">B</option>
<option value="Company_C">C</option>
<option value="Company_D">D</option>
</select>
<div id="other"></div>
</body>
companyArray.php
<?php
require('protect.php');
require_once(dirname(__FILE__) . '\..\controller\company_controller.php');
require_once(dirname(__FILE__) . '\..\controller\url.php');
$companyCtrl = new company_controller();
$compArray = $companyCtrl->retrieveAllCompany();
if($_GET['company_name']) {
$get_comp = $_GET['company_name'];
$inSpace = str_replace("_"," ", $get_comp);
foreach($compArray as $company) {
$comp_name = $company->getCompanyName();
if($get_comp == $company) {
$comp_add = $company->getCompanyAddress();
echo $comp_add;
}//end if
}//end foreach
} //end if
?>
I inspected element, but when i click on the drop down list nothing happens, i doubt its going to the companyArray.php. I also don't think its the url_mgt::getTest() link because ive been using this url pattern throughout the project.
use Ajax request on change and then populate the received values from the server on success and you can do what you are asking for.
note: you can't pass a variable from client side (js) to server side (php) without sending it as a request.
You aren't concatenating your data.
'company_name=' $('#company').val(),
should be
'company_name=' + $('#company').val(),

Pulling data from SQL database depending on form input

I am working on a form in which changing one "select" element modifies the values of another "select" element. The values of both the elements come from a MSSQL database. What is the best way to implement code that can accomplish this?
There are two ways that I can think to do it.
Store the table into a javascript variable and make the onchange event of the first element modify the second element.
Send a GET request to the page and reload it, using PHP to modify the second element.
I don't like the first method because storing the database from the PHP side to the javascript side seems kind of hacky and really cumbersome to do. I don't like the second way either, because reloading the page disrupts the user experience and makes him have to scroll down again.
You should use AJAX to pull in data and populate the second select element. In a nutshell, AJAX is simply a separate page request that happens behind the scenes. You can use it to load a simple HTML page or partial and display it in a DOM element, or you can use it to dynamically retrieve structured data.
The best way to do this would be using JSON (JavaScript Object Notation). In this case, you would use Javascript to make an AJAX call to a PHP page, and that PHP page would take an argument in the query string that represents the value of the first select element. With that, you would make a call to your MSSQL database to get all of the corresponding options for the second select, and then echo those out. In turn, the Javascript you use to make the AJAX request can parse the response and interpret it as a JavaScript object literal, allowing you to loop through the results and do what you want with them.
Here's an example (I'm using jQuery, since it makes AJAX really easy).
At the top of your form page:
$(document).ready(function() {
$('#select1').change(function() {
var select1val = $(this).val();
$.getJSON('/path/to/response.php', 'select1=' + select1val, function(response) {
$('#select2').empty();
if(response) {
for(var option in response) {
$('<option/>').val(option.value).html(option.label).appendTo($('#select2'));
}
}
});
});
});
And then your response.php page should look like this:
<?php
$select1 = $_GET['select1'];
// Do validation here, to make sure it's a legitimate value for select1. Never trust the
// user input directly.
// Replace this with whatever code you use to make DB queries.
$options = $mydb->query("SELECT value,label FROM select2_options WHERE select1_value=?", $select1);
echo json_encode($options);
Use Ajax if you don't want to reload the page. Read more about AJAX
$('#select1').change(function() {
var value = $(this).val();
var dataString = 'id='+ value;
if(value != '')
{
$.ajax({
type: "POST",
url: "fetchOptionsForSelect2.php",
data: dataString,
success: function(html) {
$('#select2').html(html);
}
});
}
else
{
//reset select2
$('#select2').html("<option value=''>Select value from select1 first</option>");
}
});
Here is a stand-alone example that does what you want. It might look complicated at first, but AJAX via jQuery is quite straight-forward.
This example uses two files:
1) TEST.PHP - contains the javascript/AJAX, and the HTML with the <select> controls
2) PROCESS.PHP - receives data from test.php (via AJAX), runs a MySQL lookup on that data, returns HTML back to TEST.PHP
TEST.PHP
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#workers").change(function(event) {
var w = $(this).val();
//alert('Value of w is: ' + w);
//return false;
$.ajax({
type: "POST",
url: "process.php",
data: 'worker=' + w,
success:function(data){
//alert(data);
$('#laDiv').html(data);
}
}); //END ajax
});
}); //END $(document).ready()
</script>
</head>
<body>
Worker:
<select id="workers">
<option>Roy</option>
<option>John</option>
<option>Dave</option>
</select>
<div id="laDiv"></div>
</body>
</html>
PROCESS.PHP
<?php
$w = $_POST['worker'];
$ret = '
Fruit Options:
<select id="fruitopts" name="Select2">
';
if ($w == 'Roy'){
$ret .= '
<option>Apples</option>
<option>Oranges</option>
<option>Pears</option>
';
}else if ($w == 'John') {
$ret .= '
<option>Peaches</option>
<option>Grapes</option>
<option>Melons</option>
';
}else if ($w == 'Dave') {
$ret .= '
<option>Nut</option>
<option>Jelly</option>
';
}
$ret .= '</select>';
echo $ret;
Here's what happens:
a. TEST.PHP - User selects choice from dropdown "workers"
b. change() event fires, gets value of ("w"), and sends that to process.php
c. PROCESS.PHP receives a variable key named w in its $_POST[] array, stores in $w
d. PROCESS.PHP does a MySQL lookup on the selected worker (value of $w)
e. PROCESS.PHP constructs some HTML in a var called $ret, then ECHOs it out
f. TEST.PHP receives the HTML string inside the $.ajax success function
g. TEST.PHP calls the received data data (-1 for originality)
h. TEST.PHP injects the received HTML into the DIV with id="laDiv"
Hope that helps.
Use http://www.appelsiini.net/projects/chained
<script src="jquery.chained.min.js"></script>
<select id="mark" name="mark">
<?php
foreach($select1_opt as $opt)
{
echo "<option value=$opt>$opt</option>";
}
?>
</select>
<select id="series" name="series">
<?php
foreach($select2_opt as $opt)
{
echo "<option value=$opt>$opt</option>";
}
?>
</select>

update data in the div

I have a problem with updating the data I display from my db. Initially, when the page opens I display the date corresponding to the current date but then the user can change the date by entering it in a text box and when he clicks update all the data displayed should be deleted and the data corresponding to the new date should be displayed. Right now I have a javascript function which deleted all the data in the div when the button is clicked. The div holds the data I want to change. But I don't know how to add new data into the div. I tried to add php code to look up the database for the data in the javascript function but I don't know how to add it to the text box.
function changedate()
{
document.getElementById("label1").innerText=document.getElementById("datepicker").valu e;
document.getElementById("selecteddate").innerText=document.getElementById("datepicker" ).value;
document.getElementById("teammembers").innerHTML = "";//empties the div(teammembers)
<?php
$con=mysqli_connect("localhost","*****","*****","*****");
$result = mysqli_query($con,"SELECT * FROM users");
while($row = mysqli_fetch_array($result))
{
if(trim($user_data['email'])!=trim($row['email']))
{
$email_users = $row['email'];
//I want to first show this email but I don't know how to add it to the div.
}
}
?>
}
You can use a combination of jQuery and AJAX to do this. Much simpler than it sounds. To see that this is the right answer for you, just view this example.
In the below example, there are two .PHP files: test86a.php and test86b.php.
The first file, 86A, has a simple selection (dropdown) box and some jQuery code that watches for that selection box to change. To trigger the jQuery code, you could use the jQuery .blur() function to watch for the user to leave the date field, or you could use the jQueryUI API:
$('#date_start').datepicker({
onSelect: function(dateText, instance) {
// Split date_finish into 3 input fields
var arrSplit = dateText.split("-");
$('#date_start-y').val(arrSplit[0]);
$('#date_start-m').val(arrSplit[1]);
$('#date_start-d').val(arrSplit[2]);
// Populate date_start field (adds 14 days and plunks result in date_finish field)
var nextDayDate = $('#date_start').datepicker('getDate', '+14d');
nextDayDate.setDate(nextDayDate.getDate() + 14);
$('#date_finish').datepicker('setDate', nextDayDate);
splitDateStart($("#date_finish").val());
},
onClose: function() {
//$("#date_finish").datepicker("show");
}
});
At any rate, when the jQuery is triggered, an AJAX request is sent to the second file, 86B. This file automatically looks stuff up from the database, gets the answers, creates some formatted HTML content, and echo's it back to the first file. This is all happening through Javascript, initiated on the browser - just like you want.
These two files are an independent, fully working example. Just replace the MYSQL logins and content with your own fieldnames, etc and watch the magic happen.
TEST86A.PHP
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
//alert('Document is ready');
$('#stSelect').change(function() {
var sel_stud = $(this).val();
//alert('You picked: ' + sel_stud);
$.ajax({
type: "POST",
url: "test86b.php", // "another_php_file.php",
data: 'theOption=' + sel_stud,
success: function(whatigot) {
//alert('Server-side response: ' + whatigot);
$('#LaDIV').html(whatigot);
$('#theButton').click(function() {
alert('You clicked the button');
});
} //END success fn
}); //END $.ajax
}); //END dropdown change event
}); //END document.ready
</script>
</head>
<body>
<select name="students" id="stSelect">
<option value="">Please Select</option>
<option value="John">John Doe</option>
<option value="Mike">Mike Williams</option>
<option value="Chris">Chris Edwards</option>
</select>
<div id="LaDIV"></div>
</body>
</html>
TEST86B.PHP
<?php
//Login to database (usually this is stored in a separate php file and included in each file where required)
$server = 'localhost'; //localhost is the usual name of the server if apache/Linux.
$login = 'abcd1234';
$pword = 'verySecret';
$dbname = 'abcd1234_mydb';
mysql_connect($server,$login,$pword) or die($connect_error); //or die(mysql_error());
mysql_select_db($dbname) or die($connect_error);
//Get value posted in by ajax
$selStudent = $_POST['theOption'];
//die('You sent: ' . $selStudent);
//Run DB query
$query = "SELECT `user_id`, `first_name`, `last_name` FROM `users` WHERE `first_name` = '$selStudent' AND `user_type` = 'staff'";
$result = mysql_query($query) or die('Fn test86.php ERROR: ' . mysql_error());
$num_rows_returned = mysql_num_rows($result);
//die('Query returned ' . $num_rows_returned . ' rows.');
//Prepare response html markup
$r = '
<h1>Found in Database:</h1>
<ul style="list-style-type:disc;">
';
//Parse mysql results and create response string. Response can be an html table, a full page, or just a few characters
if ($num_rows_returned > 0) {
while ($row = mysql_fetch_assoc($result)) {
$r = $r . '<li> ' . $row['first_name'] . ' ' . $row['last_name'] . ' -- UserID [' .$row['user_id']. ']</li>';
}
} else {
$r = '<p>No student by that name on staff</p>';
}
//Add this extra button for fun
$r = $r . '</ul><button id="theButton">Click Me</button>';
//The response echoed below will be inserted into the
echo $r;
Here is a more simple AJAX example and yet another example for you to check out.
In all examples, note how the user supplies the HTML content (whether by typing something or selecting a new date value or choosing a dropdown selection). The user-supplied data is:
1) GRABBED via jQuery: var sel_stud = $('#stSelect').val();
2) then SENT via AJAX to the second script. (The $.ajax({}) stuff)
The second script uses the values it receives to look up the answer, then ECHOES that answer back to the first script: echo $r;
The first script RECEIVES the answer in the AJAX success function, and then (still inside the success function) INJECTS the answer onto the page: $('#LaDIV').html(whatigot);
Please experiment with these simple examples -- the first (simpler) linked example doesn't require a database lookup, so it should run with no changes.
You want to output a literal JS statement with whatever you get back from php, basically:
document.getElementById("teammembers").innerHTML = // notice no erasing, we just
// overwrite it directly with the result
"<?php
$con=mysqli_connect("localhost","*****","*****","*****");
$result = mysqli_query($con,"SELECT * FROM users");
while($row = mysqli_fetch_array($result))
{
if(trim($user_data['email'])!=trim($row['email']))
{
$email_users = $row['email'];
//I want to first show this email but I don't know how to add it to the div.
// so just show it!
echo $email_users; // think about this for a second though
// what are you trying to achieve?
}
}
?>"
This is a vast question, not very specific. Checkout more about AJAX requests - basically from javascript you will have a call to the server that retrieves your data.
This is a snippet from the javascript library jQuery :
$.ajax({
type: "POST",
url: "emails.php",
data: { user: "John" }
}).done(function( msg ) {
$('teammembers').html(msg);
});
hope this will give you a starting point

Categories