I'm building a form that has a look-ahead input box (using jQuery UI). The input chosen (in this case, bands) is sent to the database via Ajax, then displayed below the input box in either a Plaintiff, Defendant, or Other bin.
For 90% of the cases, it works just fine, asynchronously glorious. The issue arises when a band happens to have quotes or an apostrophe in it. I'm escaping the characters with mysql_real_escape_string in my PHP form handler, but the problem appears to be originating when the data is Ajax'd over.
description=Watts, Michael "5000" becomes description=Watts%2C+Michael+%225000%22.
Here's my jQuery code (nothing fancy, just the serialization) and my PHP code. Note that it works just fine if I manually enter description=Watts, Michael "5000" into my PHP file (as in, it can grab the data that it otherwise cannot).
jQuery code:
$('#party_add').live('click', function(){
//grab the form
var thisform=$(this).parents('form');
//serialize the data
var toSend=thisform.serialize();
//add the caseID we stored in #caseId
var storedCaseId=$('#caseId').text();
toSend=toSend+'&caseId='+storedCaseId;
$.ajax({
type : "POST",
url : 'cases_form_handler.php',
data : toSend,
dataType:'json',
success : function(data){
alert(toSend);
//conjure the relevant parties into their respective places in the table below with some sexy json action
$('.party').empty();
for(var x=0; x < data.length; x++){
if(data[x].partyType==1){
$('.party:first').append('<span class=party_addition id='+data[x].partyId+'>'+data[x].description+'</span><br/>');
}else{
//if defendant, put them in the defendant box
if(data[x].partyType==2){
$('.party:first').next('.party').append('<span class=party_addition id='+data[x].partyId+'>'+data[x].description+'</span><br/>');
}else{
//if other, put them in the other box
if(data[x].partyType==3){
$('.party:first').next('.party').next('.party').append('<span class=party_addition id='+data[x].partyId+'>'+data[x].description+'</span><br/>');
}
}
}
}
}
});
PHP code and failing SQL call:
$description=mysql_real_escape_string($_POST['description']);
$sql="SELECT id FROM varParties WHERE description='$description'";
$result=mysql_query($sql);
while($row=mysql_fetch_assoc($result)){
$partyId=$row['id'];
}
UPDATE:
Here's the json portion of my php
$sql = "SELECT varParties.*,relCasesParties.partyType,relCasesParties.active FROM varParties INNER JOIN relCasesParties ON relCasesParties.partyId = varParties.id WHERE relCasesParties.caseId = '$caseId' AND relCasesParties.active='1'";
//build array of results
$query=mysql_query($sql);
for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
$row = mysql_fetch_assoc($query);
$parties[$x] = array('description'=>$row['description'],'partyId'=>$row['id'],'partyType'=>$row['partyType']);
}
//send it back
echo json_encode($parties);
Where would I use htmlentities?
Use
$description=mysql_real_escape_string(urldecode($_POST['description']));
Now, when it's visible, that you are trying to output JSON string, the answer is different.
for the loop use:
for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
$row = mysql_fetch_assoc($query);
$parties[$x] = array('description'=>addcslashes($row['description'],'"'),'partyId'=>$row['id'],'partyType'=>$row['partyType']);
}
Related
I am running a POST + json code to collect data from database, all results come with only one value (this is correct), however there is only one column which should show more than one value but shows only the first one. What I need to change in my code to get this list instead of the first row result?
I've run one MYSQL query linking three databases those share the same id PCRNo, the first two databases tPCR and tcomplement should only have one result and the third one should receive more results due to we can have more lines with the same id.
This is my JavaScript
<script>
$(document).ready(function(){
$('#table').on('click', '.fetch_data', function(){
var pcr_number = $(this).attr('id');
$.ajax({
url:'fetch.php',
method:'post',
data:{pcr_number:pcr_number},
dataType:"json",
success:function(data){
$('#PCR').val(data.PCRNo);
$('#PCC').val(data.PCC);
$('#PCR_Creation').val(data.Creation_Date);
$('#PCR_Status').val(data.Stage);
$('#Required_Completion').val(data.Required_Completion);
$('#description').val(data.Name);
$('#Comments').val(data.Comments);
$('#originator').val(data.Creator);
$('#change_type').val(data.Category);
$('#product_type').val(data.Product);
$('#req_dept').val(data.Department);
$('#flow').val(data.Flow_Start_Date);
$('#own').val(data.Owning_Site);
$('#impacted').val(data.Impacted_Site);
$('#approval').val(data.Meeting_Status);
$('#review').val(data.Review_Date);
$('#cat').val(data.Cat);
$('#cost').val(data.Cost);
$('#labor').val(data.Labour);
$('#volume').val(data.Volume);
$('#request').val(data.Request);
$('#justification').val(data.Justification);
$('#PCNlist').val(data.PCNNo);
$('#monitor').val(data.Monitor);
$('#env').val(data.Environment);
$('#trial').val(data.Trial);
$('#resp').val(data.Responsible);
$('#deadline').val(data.Deadline);
$('#dataModal').modal('show');
}
});
});
$(document).on('click', '#update', function(){
var pcr_number = document.getElementById("PCR").value;
var Comments= document.getElementById("Comments").value;
var approval= document.getElementById("approval").value;
var review= document.getElementById("review").value;
var cat= document.getElementById("cat").value;
var monitor= document.getElementById("monitor").value;
var env= document.getElementById("env").value;
var trial= document.getElementById("trial").value;
var resp= document.getElementById("resp").value;
var deadline= document.getElementById("deadline").value;
var PCC = document.getElementById("PCC").value;
$.ajax({
url:"edit.php",
method:"POST",
data:{pcr_number:pcr_number, Comments:Comments, PCC:PCC, approval:approval, review:review, cat:cat, monitor:monitor, env:env, trial:trial, resp:resp, deadline:deadline},
dataType:"text",
success:function(data)
{
alert('PCR Information Updated');
}
});
});
});
</script>
this is my fetch.php
<?php
$SelectedPCRNo = $_POST['pcr_number'];
if(isset($_POST['pcr_number']))
{
$output = '';
$hostname = "localhost";
$username = "root";
$password = "";
$databaseName = "change_management";
$dbConnected = #mysqli_connect($hostname, $username, $password);
$dbSelected = #mysqli_select_db($databaseName,$dbConnected);
$dbSuccess = true;
if ($dbConnected) {
if ($dbSelected) {
echo "DB connection FAILED<br /><br />";
$dbSuccess = false;
}
} else {
echo "MySQL connection FAILED<br /><br />";
$dbSuccess = false;
}
$sql = mysqli_query($dbConnected, "SELECT * FROM change_management.tPCR INNER JOIN change_management.tcomplement ON change_management.tPCR.PCRNo = change_management.tcomplement.PCRNo INNER JOIN change_management.tPCN ON change_management.tPCR.PCRNo = change_management.tPCN.PCRNo WHERE tPCR.PCRNo = '".$_POST['pcr_number']."'");
$row = mysqli_fetch_array($sql);
echo json_encode($row);
}
?>
I have no problems with the results and the table is filled OK, only the #PCNlist should be filled with the values of all rows it is related and now just is just coming one value, the first row only. Is there any way to bring the whole PCNlist only changing some code at the fetch.php?
If I understood you correctly, the table tPCN can contain multiple rows associated with each PCR number. And you want to fetch all these rows and return them in your JSON.
If you want to achieve that, but also make sure the other two tables only return one row, then I think simply you should remove the JOIN to tPCN in your first query, and then create a second query to fetch the tPCN rows specifically.
$output = [];
$stmt = $dbConnected->prepare("SELECT * FROM change_management.tPCR INNER JOIN change_management.tcomplement ON change_management.tPCR.PCRNo = change_management.tcomplement.PCRNo WHERE tPCR.PCRNo = ?");
$stmt->bind_param('s', $_POST['pcr_number']);
$stmt->execute();
$result = $stmt->get_result();
//select a single row from the result and assign it as the output variable
if ($row = $result->fetch_assoc()) {
$output = $row;
}
$stmt2 = $dbConnected->prepare("SELECT * FROM change_management.tPCN WHERE PCRNo = ?");
$stmt2->bind_param('s', $_POST['pcr_number']);
$stmt2->execute();
$result2 = $stmt2->get_result();
$output["tPCN"] = array(); //create a new property to put the tPCN rows in
//loop through all the tPCN rows and append them to the output
while ($row2 = $result2->fetch_assoc()) {
$output["tPCN"][] = $row2;
}
echo json_encode($output);
This will produce some JSON with this kind of structure:
{
"PCRNo": "ABC",
"CreationDate": "2019-08-07",
"Name": "A N Other",
//...and all your other properties, until the new one:
"tPCN": [
{
"SomeProperty": "SomeValue",
"SomeOtherProperty": "SomeOtherValue",
},
{
"SomeProperty": "SomeSecondValue",
"SomeOtherProperty": "SomeOtherSecondValue",
}
]
}
You will then need to amend your JavaScript code to be able to deal with the new structure. Since I don't know exactly which fields come from the tPCN table, I can't give you an example for that, but hopefully it's clear that you will need to loop through the array and output the same HTML for each entry you find.
N.B. As you can see I re-wrote the query code to use prepared statements and parameterised queries, so you can see how to write your code in a secure way in future.
P.S. You have a lot of code there in the "success" function just to set the values of individual fields. You might want to consider using a simple JS templating engine to make this less verbose and cumbersome, and generate the HTML you need with the values automatically added into it in the right place. But that's a separate issue, just for the maintainability of your code
I've added this code into my ajax function to bring only what I needed and it works + what #ADyson has posted.
var PCN = data.tPCN;
var i;
var PCNList = '';
for (i = 0; i < PCN.length; i++){
var PCNList = PCNList + PCN[i]['PCNNo'] + ' - ' + PCN[i]['Stage'];
}
$('#PCNlist').val(PCNList);
I have a database where it has 10+ records:
Accid | Firstname | Lastname
1. John Marshall
2. Sherlock Holmes
3. Random Dude
...
I'd display this using echo on php but with AJAX... it first loads up 5 users, and when the user has scrolled at the bottom of the page, it will load another 5 on the list (it adds the Offset's value +=5). Here's my display code:
$sql = "SELECT * FROM users ORDER BY lastname DESC LIMIT 5 OFFSET 5";
$result = mysqli_query($connection,$sql);
While($row=mysqli_fetch_assoc) {
echo $row['lastname']." ".$row['firstname']."<br/>";
}
This list could be very long if I have 100 users let's say.
Whenever the user scrolls at the bottom, another 5 users pops up. Now, if I reached the end of the whole records in the USERS database, I'd like to display something like - "End of User List"
How can I achieve this?
Jquery Code
$.ajax({
type: "GET",
url: "getusers.php",
data: {
'offset': 4
},
success: function(data){
$('#displayusers').append(data);
}
});
I'd like to disagree with #PressingOnAlways answer.
You can just send back a different response from PHP and check it in javascript.
$sql = "SELECT * FROM users ORDER BY lastname DESC LIMIT 5 OFFSET 5";
$result = mysqli_query($connection,$sql);
if(mysqli_num_rows($result) == 0){
die("last");
}
While($row=mysqli_fetch_assoc) {
echo $row['lastname']." ".$row['firstname']."<br/>";
}
Now you can just check it in javascript:
if(response == "last"){
mydiv.append('This is the end');
}
Now, I would like to show you my way of doing things, which (imo) is a lot cleaner:
First, your ajax calls
We're going to make sure our data will be in json format automatically from now on:
$.ajax({
type: 'GET',
url: "getusers.php",
cache: false,
data: {'offset': 4},
dataType: "json"
}).done(function(json){
if(json.hasOwnProperty("last"){
//No more results
//do your thang;
return false;
}
if(getLength(json) < 5){
//Smaller then 5, must have hit the last. Do your thang;
return false;
}
//It came here, so it's all good. Go on
$('#displayusers').append(data);
});
Secondly: Your PHP side
It's never a good plan to echo html over AJAX. It's way more efficient (takes up less servertime + sends smaller amounts of data over the internet highway) than doing it in PHP.
$sql = "SELECT * FROM users ORDER BY lastname DESC LIMIT 5 OFFSET 5";
$result = mysqli_query($connection,$sql);
$lastResponse = array("last" => "last");
if(mysqli_num_rows($result) == 0){
//Always send back json or it'll give you an error
die(json_encode($lastResponse));
}
$return = array();
While($row=mysqli_fetch_assoc) {
$return[] = $row['lastname']." ".$row['firstname'];
}
echo json_encode($return);
Third: A js function to check the arrayLength
//Checks the length of a json object or array
//Returns false if length is 0 or unable to check it
function getLength(obj) {
if (typeof obj == 'undefined') {
return false;
}
var l = 0;
if (typeof obj == 'object') {
l = Object.keys(obj).length;
}
else {
l = obj.length;
}
return (l == 0 ? false : l);
}
The best place to implement this feature would be on the JS client side. Since your PHP script has no way of knowing if it is the end of the list or not, you need to do this on the client. The JS code should check if the results returned from your php script is less than 5, if so, the "End of User List" should be printed.
Im trying to use a dojo ajax function to call a PHP file that then returns the contents of a DB table in JSON format.
My function:
var _getWeatherInfo = function(){
dojo.xhrget({
url: "PHP/weather.php?ntown=" + _ntown,
handleAs: "json",
timeout: 5000,
load: function(responce, details) {
_updateWeathertData
},
error: function(error_msg, details) {
_handleError(error_msg);
}
});
}
My PHP:
<?php include('configHome.php'); ?>
<?php
$ntown = $_GET['ntown'];
$weather = array();
$query="SELECT * FROM `weather` WHERE `town` = '$ntown'";
$result=mysql_query($query);
while($row = mysql_fetch_row($result)) {
$weather[] = $row[0];
}
echo json_encode($weather);
mysql_close();
?>
When using this code I am getting an error message saying that "$ntown = $_GET['ntown'];" is an undefined index. I have tried removing the index all together and using an actual value in the select statement (i.e. SELECT * FROM weather WHERE town = 'Auckland') but all I get back is the value i enter ["Auckland"], and not the 3 other values that are meant to be returned, ["Auckland", "Sunny", "8", "14"].
Any ideas? I can try add more info if needed. Thanks!
There are some other issues with your code, but to get to the one you are asking the question about. You have this:
while($row = mysql_fetch_row($result)) {
$weather[] = $row[0];
}
What you are doing is just taking the first value of the row (of which there is probably only one, and just sending that back. This is what you need:
$weather = mysql_fetch_row($result);
I currently have code which will pull the first element from a database record and print it in an output box.
What is the easiest way to print the rest of the elements of that record to the other relevant output boxes?
My PHP file takes an 'id' specified by the user.
$id = $_POST['id'];
$query = "SELECT * FROM Customers WHERE ID = $id";
$result= mysql_query($query);
if (mysql_num_rows($result) > 0) {
while($row = mysql_fetch_row($result)) {
echo $row[1];
}
}
And this is the code in the HTML file
jQuery(document).ready(function(){
jQuery("input.myid").keyup(function(e){
e.preventDefault();
ajax_search();
});
});
function ajax_search(){
var search_val=jQuery("input.myid").val();
jQuery.post("find.php", {id : search_val}, function(data){
if (data.length>0){
jQuery("input.fname").val(data);
}
});
}
The code takes the id ('myid') and prints to a text box named 'fname'.
I find it easier to json_encode the whole thing (record I mean) and use something like jquery.populate which basically takes an object and fills a form with it (all fields it can find which names' match properties from the object).
I hope this makes sense.
I have a 3 step chained-select sequence, game -> battle -> winning side , which pulls all data from a MySQL database.
After some wandering on the internet, I found a compact jQuery script that performs wonderfully. However, I am at a loss as to how to allow for existing data: <option selected="selected"></option> using this script.
chained select javascript:
<script>
var ajax = new Array();
function getScenNumList(sel)
{
var game = sel.options[sel.selectedIndex].value;
document.getElementById('scenarioNumber').options.length = 0; // Empty scenario number select box
if(game.length>0){
var index = ajax.length;
ajax[index] = new sack();
ajax[index].requestFile = 'js/getPlayData.php?gameName='+game; // Specifying which file to get
ajax[index].onCompletion = function(){ createScenarioNumbers(index) }; // Specify function that will be executed after file has been found
ajax[index].runAJAX(); // Execute AJAX function
}
}
function createScenarioNumbers(index)
{
var obj = document.getElementById('scenarioNumber');
eval(ajax[index].response); // Executing the response from Ajax as Javascript code
}
function getNations(sel)
{
var scenNum = sel.options[sel.selectedIndex].value;
document.getElementById('victor').options.length = 0; // Empty nation select box
if(scenNum.length>0){
var index = ajax.length;
ajax[index] = new sack();
ajax[index].requestFile = 'js/getPlayData.php?scenID='+scenNum; // Specifying which file to get
ajax[index].onCompletion = function(){ createNations(index) }; // Specify function that will be executed after file has been found
ajax[index].runAJAX(); // Execute AJAX function
}
}
function createNations(index)
{
var obj = document.getElementById('victor');
eval(ajax[index].response); // Executing the response from Ajax as Javascript code
}
</script>
excerpt from the PHP database retrieval script (getPlayData.php):
$gameName = mysql_real_escape_string($_GET['gameName']);
$q = "SELECT a, b, c FROM table WHERE game='$gameName' ORDER BY num ASC";
$r = mysql_query($q);
echo "obj.options[obj.options.length] = new Option('#','');\n";
while ($row = mysql_fetch_row($r)) {
$string = mysql_real_escape_string(($row[0].' - '.$row[1])); // needed so quotes ' " don't break the javascript
echo "obj.options[obj.options.length] = new Option('$string','$row[2]');\n";
}
echoing the obj.options is the stock method this script was using. It seems ugly to me, but I don't know any javascript so I didn't want to fiddle with it.
The HTML is simple enough, just a table with a few empty <select> objects with IDs matching those in the javascript and onchange="getXXX(this)" calls.
My question is this: Everything works great for new records, but I'm at a loss as to how I can alter this to support marking one option from each select as selected, assuming I have that data in hand (ex: a user is editing an existing record) ?
Many thanks!
You can see this tutorial for creating an option that is selected as default. http://www.javascriptkit.com/javatutors/selectcontent.shtml One parameter in the option constructor dictate that whether the option is selected or not.
In the PHP file you will edit as follow:
$gameName = mysql_real_escape_string($_GET['gameName']);
$q = "SELECT a, b, c FROM table WHERE game='$gameName' ORDER BY num ASC";
$r = mysql_query($q);
echo "obj.options[obj.options.length] = new Option('#','');\n";
while ($row = mysql_fetch_row($r)) {
$string = mysql_real_escape_string(($row[0].' - '.$row[1])); // needed so quotes ' " don't break the javascript
if ($string ......)
echo "obj.options[obj.options.length] = new Option('$string','$row[2]', false, true);\n";
else
......
}