First I want to describe what I want to do.
I've a table and one column has buttons. Each button represents an ID. When the button is clicked, I store the ID into a variable in javascript. I want to use this ID in a MySQL-Statement to get some informations, which are in more than one row and creare a PDF file with these data.
I want to use ajax to handle the recived data, but I don't know exactly how to.
Until now, this is what I got:
<script>
$("#grid-table").bootgrid({
formatters: {
"buttonID": function(column, row){
return "<button type=\"button\" id=\"edit\" class=\"btn btn-xs btn-default print-pdf\" + data-row-id1=\"" + row.ID + "\" ><span class=\"fa fa-file-pdf-o\"></span></button> ";
}
}).on("click", function(e){
var id = $(this).data("row-id1"); // id is a string
var recv_data1[];
var recv_data2[];
var recv_data3[];
var recv_data4[];
var i = 0;
if(id != ""){
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200) {
// how to get all datas and store them here?
// and get the count of $i
var doc = new jsPDF(); // pdf object
mainPage(doc); // my function to create a pdf background
var xPos = 25;
var yPos = 60;
while(i){
doc.setFontSize(12);
doc.setFontType('normal');
doc.text(70, 55, recv_data1[i]); // here I want to use some of the data
doc.setFontSize(11);
doc.setFontType('bold');
doc.text(xPos+10, yPos+10, recv_data2[i]); // some more data I got from the mysql-statement
doc.text(xPos+55, yPos+10, recv_data3[i]);
doc.text(xPos+80, yPos+10, recv_data4[i]);
i--;
}
doc.save(recv_data1 + '.pdf'); // save pdf file
}
};
xmlhttp.open("GET","get_data.php?id="+ id, true);
xmlhttp.send();
}
});
</script>
PHP-Part from get_data.php:
<?php
include "dbconnect.php";
$revc_id = htmlspecialchars_decode($_GET['id']);
$result = mysqli_query($db, "SELECT *
FROM table
WHERE table.id = 'revc_id';");
$i = 1;
while($row = mysqli_fetch_array($result)) {
// how to handle the fetched array and alle the data to
// more than one variable for the js like
// echo $row['name'] for recv_data1[]
// echo $row['city'] for recv_data2[]
// echo $row['street'] for recv_data3[]
// echo $row['country'] for recv_data4[]
// echo $i to know how many datas are in there
$i++;
}
mysqli_close($db);
?>
This is just a general example of what I want to do and not the original code. So what I want is that the respone I got from get_data.php, which is in the most cases more than one row, to be saved into the array.
I hope you know what I mean, if not fell free to ask please.
Tricky to answer when the code shown is not the actual code but in general you could try something like this.
php
---
$data=array();
while( $row = mysqli_fetch_object( $result ) ) {
$data[]=array(
'name' => $row->name,
'city' => $row->city,
'street' => $row->street,
'country' => $row->country
);
}
echo json_encode( $data );
/* javascript */
document.getElementById('BTTN_ID_ETC').onclick = function(e){
e.preventDefault();
var id = $( this ).data("row-id1");
if( id != "" ){
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if( this.readyState == 4 && this.status == 200 ) {
var json=JSON.parse( this.response );
var doc = new jsPDF();
mainPage( doc );
var xPos = 25;
var yPos = 60;
for( var n in json ){
try{
var obj=json[ n ];
if( typeof( obj )=='object' ){
var name=obj.hasOwnProperty('name') ? obj.name : false;
var city=obj.hasOwnProperty('city') ? obj.city : false;
var street=obj.hasOwnProperty('street') ? obj.street : false;
var country=obj.hasOwnProperty('country') ? obj.country : false;
if( name && city && street && country ){
doc.setFontSize(12);
doc.setFontType('normal');
doc.text(70, 55, name );
doc.setFontSize(11);
doc.setFontType('bold');
doc.text(xPos+10, yPos+10, city );
doc.text(xPos+55, yPos+10, street );
doc.text(xPos+80, yPos+10, country );
}
}
} catch( err ){
console.log( err );
continue;
}
}
doc.save( json[0].name + '.pdf');
}
};
xmlhttp.open( 'GET', 'get_data.php?id='+ id, true );
xmlhttp.send();
}
};
Related
I'm trying to pass to php from javascript elements of an array, for processing, like this:
for(var i=0;i<points.length;++i){
var xmlhttp = new XMLHttpRequest();
var distancesObject = null;
lat = points[i][LAT];
lng = points[i][LNG];
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
if(xmlhttp.response!=null){
distancesObject = JSON.parse(xmlhttp.response);
}
}
};
xmlhttp.open("GET", "Distances.php?lat=" + lat + "&lng=" + lng, true);
xmlhttp.send();
}
It should iterate through every elements of the array and return the object, if it exists in the database, yet it returns null, even though i know for sure the first values are stored in the database.
It only works if I pass values like points[0], points[1].
The php code is:
<?php
$latitude = $_GET['lat']; //"47.158857";
$longitude = $_GET['lng']; // "27.601249"
$query = "SELECT pharmacyDistance, schoolDistance, restaurantDistance, busStationDistance FROM distances WHERE lat='$latitude' and lng='$longitude'";
$result = mysqli_query($dbc,$query);
$count = mysqli_num_rows($result);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
$json_array = json_encode($row);
if($json_array!=null){
echo $json_array;
}
mysqli_close($dbc);
?>
Is there something I'm doing wrong?
Please don't do that way. Really. Add all array items into your url and perform just one request, where you will query for everything you need and return a list. Handle the list in the response. Something like(from top of my head):
var urlParams = [];
points.forEach(function(point) {
urlParams.push("lat[]=" + point.LAT + "&lng[]=" + point.LNG);
});
var xmlhttp = new XMLHttpRequest();
var distancesObject = null;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
if(xmlhttp.response!=null){
distancesObject = JSON.parse(xmlhttp.response);
}
}
};
xmlhttp.open("GET", "Distances.php?" + urlParams.join("&"), true);
xmlhttp.send();
In PHP:
$whereClause = "";
for ($i = 0; $i < count($_GET['lat']); $i++) {
$whereClause.= "(lat='" . $_GET['lat'][$i] . "' and lng='" . $_GET['lng'][$i]. "') and ";
}
$query = "SELECT pharmacyDistance, schoolDistance, restaurantDistance, busStationDistance FROM distances WHERE " . substr($whereClause, 0, (strlen($whereClause) - 4)); // Substr to remove last ' and' from where clause
$result = mysqli_query($dbc,$query);
$count = mysqli_num_rows($result);
$distances = array();
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
$distances[] = $row;
}
$json_array = json_encode($distances);
if($json_array!=null){
echo $json_array;
}
mysqli_close($dbc);
Then you'll have a list of your distances as json and just one hit in your database. Also, is not healthy for your app to call an ajax in a for loop, it will open various parallel async requests, a mess.
This is how the query will looks like approximately:
SELECT ... FROM ... WHERE (lat='1' and lng='1') and (lat='2' and lng='2') and ...
I didn't tested those codes and I don't play with PHP for a while, so I hope the code is ok, forgive any typos or syntax errors.
I believe your problem lies with these 2 lines:
lat = points[i][LAT];
lng = points[i][LNG];
Firstly, you have defined them into the global scope. They should be prefixed with the var keyword unless you've already defined these variables above.
Second, [LAT] is trying to use an (I assume unitiated) variable named LAT. The correct syntax for using a string key name is either points[i]['LAT'] or points[i].LAT.
So, updating your code to
var xmlhttp = new XMLHttpRequest();
var distancesObject = null;
var lat = points[i].LAT;
var lng = points[i].LNG;
Should hopefully solve your problem.
you're overwriting the object which is handling the connection in the for loop, probably faster than the response can return.
try:
var xmlhttp = [];
for(var i=0;i<points.length;++i){
xmlhttp[i] = new XMLHttpRequest();
var distancesObject = null;
lat = points[i][LAT];
lng = points[i][LNG];
xmlhttp[i].onreadystatechange = function() {
if (xmlhttp[i].readyState == 4 && xmlhttp[i].status == 200){
if(xmlhttp[i].response!=null){
distancesObject = JSON.parse(xmlhttp.response);
}
}
};
xmlhttp[i].open("GET", "Distances.php?lat=" + lat + "&lng=" + lng, true);
xmlhttp[i].send();
}
For some weird reason this line of code is not working:
var ajax = ajaxObj("POST", "php_parsers/status_system.php");
What could it be?
I figured it must be the above line using window.alert's since after that line window.alert does not run.
Full code:
The function is called:
$status_ui = '<textarea id="statustext" onkeyup="statusMax(this,250)" placeholder="What's new with you '.$u.'?"></textarea>';
$status_ui .= '<button id="statusBtn" onclick="postToStatus(\'status_post\',\'a\',\''.$u.'\',\'statustext\')">Post</button>';
The function:
function postToStatus(action,type,user,ta){
window.alert("status passed 1");
var data = _(ta).value;
if(data == ""){
alert("Type something first weenis");
return false;
}
window.alert("status passed 2");
_("statusBtn").disabled = true;
var ajax = ajaxObj("POST", "php_parsers/newsfeed_system.php");
window.alert("status passed 3");
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) == true) {
var datArray = ajax.responseText.split("|");
if(datArray[0] == "post_ok"){
var sid = datArray[1];
data = data.replace(/</g,"<").replace(/>/g,">").replace(/\n/g,"<br />").replace(/\r/g,"<br />");
var currentHTML = _("statusarea").innerHTML;
_("statusarea").innerHTML = '<div id="status_'+sid+'" class="status_boxes"><div><b>Posted by you just now:</b> <span id="sdb_'+sid+'">delete status</span><br />'+data+'</div></div><textarea id="replytext_'+sid+'" class="replytext" onkeyup="statusMax(this,250)" placeholder="write a comment here"></textarea><button id="replyBtn_'+sid+'" onclick="replyToStatus('+sid+',\'<?php echo $u; ?>\',\'replytext_'+sid+'\',this)">Reply</button>'+currentHTML;
_("statusBtn").disabled = false;
_(ta).value = "";
} else {
alert(ajax.responseText);
}
}
}
ajax.send("action="+action+"&type="+type+"&user="+user+"&data="+data);
window.alert("status passed 4");
}
newsfeed_system.php
if (isset($_POST['action']) && $_POST['action'] == "status_post"){
// Make sure post data is not empty
if(strlen($_POST['data']) < 1){
mysqli_close($db_conx);
echo "data_empty";
exit();
}
// Make sure type is a
if($_POST['type'] != "a"){
mysqli_close($db_conx);
echo "type_unknown";
exit();
}
// Clean all of the $_POST vars that will interact with the database
$type = preg_replace('#[^a-z]#', '', $_POST['type']);
$data = htmlentities($_POST['data']);
$data = mysqli_real_escape_string($db_conx, $data);
// Insert the status post into the database now
$sql = "INSERT INTO newsfeed(author, type, data, postdate)
VALUES('$log_username','$type','$data',now())";
$query = mysqli_query($db_conx, $sql);
$id = mysqli_insert_id($db_conx);
mysqli_query($db_conx, "UPDATE newsfeed SET osid='$id' WHERE id='$id' LIMIT 1");
mysqli_close($db_conx);
echo "post_ok|$id";
exit();
}
Ajax methods:
function ajaxObj( meth, url ) {
var x = new XMLHttpRequest();
x.open( meth, url, true );
x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
return x;
}
function ajaxReturn(x){
if(x.readyState == 4 && x.status == 200){
return true;
}
}
Please help!
The ajax is not refrenced! You need to include the library or put the code for calling an 'ajaxObj'.
Here is my JavaScript and my PHP for a dynamic ajax search. I am trying to get data from the database and display it in my DOM as a string.
javascript
var searchBox = document.getElementById("searchBox");
var searchButton = document.getElementById("searchButton");
var search = getXmlHttpRequestObject();
searchBox.addEventListener("keyup", ajaxSearch);
function getXmlHttpRequestObject(){
if(window.XMLHttpRequest){
return new XMLHttpRequest();
}
else if (window.ActiveXObject){
return new ActiveXObject("Microsoft.XMLHTTP");
}
else{
alert("Your browser does not support our dynamic search");
}
}
function ajaxSearch(){
var str = escape(document.getElementById('searchBox').value);
search.open("GET", '../searchSuggest.php?search=' + str, true);
search.send(null);
delay(displaySuggestions);
}
function displaySuggestions(){
var ss = document.getElementById("searchSuggestion");
ss.innerHTML = '';
string = search.responseText;
ss.innerHTML = string;
}
function delay(functionName){
setTimeout(functionName, 100);
}
function setSearch(x){
document.getElementById("searchBox").value = x;
document.getElementById("searchSuggestion").innerHTML = "";
}
searchBox.addEventListener('click', ajaxSearch);
window.addEventListener('click', function(){
document.getElementById('searchSuggestion').innerHTML = '';
});
php
<?php
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "Products";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$searchValue = $_GET['search'];
if(isset($searchValue) && $searchValue != ''){
$search = addslashes($searchValue);
$statement = $conn->prepare("SELECT Name FROM Product WHERE Name LIKE('%" . $search . "%') ORDER BY
CASE WHEN Name like '" . $search . " %' THEN 0
WHEN Name like '" . $search . "%' THEN 1
WHEN Name like '% " . $search . "%' THEN 2
ELSE 3
END, Name");
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($result);
echo $json;
}
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
?>
What i want to know i how to get specific values from my response.
[{"Name":"iMac"},{"Name":"iPad 2"},{"Name":"iPhone 5"},{"Name":"iPhone 6"},{"Name":"iPod Touch"},{"Name":"iWatch"}]
For my search to work effectively i need it to display just the string of the product name and not the whole object.
Using a delay rather than the ajax callback is just shockingly prone to failure. Suppose your ajax call takes more than 100ms? It can totally happen. Similarly, why wait 100ms if your server is nice and fast and it finishes in 25?
Ditch the global search object, and change this:
function ajaxSearch(){
var str = escape(document.getElementById('searchBox').value);
search.open("GET", '../searchSuggest.php?search=' + str, true);
search.send(null);
delay(displaySuggestions);
}
to
function ajaxSearch(){
var str = escape(document.getElementById('searchBox').value);
var search = getXmlHttpRequestObject();
if (search) {
search.onreadystatechange = function() {
if (search.readyState == 4 && search.status == 200) {
displaySuggestions(JSON.parse(search.responseText));
}
};
search.open("GET", '../searchSuggest.php?search=' + str, true);
search.send(null);
}
}
Then displaySuggestions receives an array:
function displaySuggestions(results) {
// Use standard array techniques on `results`, e.g., `results[0]` is the first,
// maybe loop while `index < results.length`, maybe use `results.forEach(...)`...
}
Or taking it further, let's add a level of convenience there:
var failed = false;
function getXmlHttpRequestObject(done, failed){
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject){
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
else {
if (!failed) {
alert("Your browser does not support our dynamic search");
failed = true;
}
return null;
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200 {
if (done) {
done(xhr);
}
} else {
if (failed) {
failed(xhr);
}
}
}
};
return xhr;
}
Then:
function ajaxSearch(){
var str = escape(document.getElementById('searchBox').value);
var search = getXmlHttpRequestObject(function(xhr) {
displaySuggestions(JSON.parse(xhr.responseText));
});
if (search) {
search.open("GET", '../searchSuggest.php?search=' + str, true);
search.send(null);
}
}
I'm trying to create a gameserver query for my website, and I want it to load the content, save it, and echo it later. However, it doesn't seem to be echoing. It selects the element by ID and is supposed to echo the content of the VAR.
Here's my HTML code:
<center><div id="cstrike-map"><i class="fa fa-refresh fa-spin"></i> <b>Please wait ...</b><br /></div>
JavaScript:
<script type="text/javascript">
var map = "";
var hostname = "";
var game = "";
var players = "";
$.post( "serverstats-cstrike/cstrike.php", { func: "getStats" }, function( data ) {
map = ( data.map );
hostname = ( data.hostname );
game = ( data.game );
players = ( data.players );
}, "json");
function echoMap(){
document.getElementByID("cstrike-map");
document.write("<h5>Map: " + map + "</h5>");
}
</script>
PHP files:
query.php
/* SOURCE ENGINE QUERY FUNCTION, requires the server ip:port */
function source_query($ip)
{
$cut = explode(":", $ip);
$HL2_address = $cut[0];
$HL2_port = $cut[1];
$HL2_command = "\377\377\377\377TSource Engine Query\0";
$HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3);
fwrite($HL2_socket, $HL2_command); $JunkHead = fread($HL2_socket,4);
$CheckStatus = socket_get_status($HL2_socket);
if($CheckStatus["unread_bytes"] == 0)
{
return 0;
}
$do = 1;
while($do)
{
$str = fread($HL2_socket,1);
$HL2_stats.= $str;
$status = socket_get_status($HL2_socket);
if($status["unread_bytes"] == 0)
{
$do = 0;
}
}
fclose($HL2_socket);
$x = 0;
while ($x <= strlen($HL2_stats))
{
$x++;
$result.= substr($HL2_stats, $x, 1);
}
$result = urlencode($result); // the output
return $result;
}
/* FORMAT SOURCE ENGINE QUERY (assumes the query's results were urlencode()'ed!) */
function format_source_query($string)
{
$string = str_replace('%07','',$string);
$string = str_replace("%00","|||",$string);
$sinfo = urldecode($string);
$sinfo = explode('|||',$sinfo);
$info['hostname'] = $sinfo[0];
$info['map'] = $sinfo[1];
$info['game'] = $sinfo[2];
if ($info['game'] == 'garrysmod') { $info['game'] = "Garry's Mod"; }
elseif ($info['game'] == 'cstrike') { $info['game'] = "Counter-Strike: Source"; }
elseif ($info['game'] == 'dod') { $info['game'] = "Day of Defeat: Source"; }
elseif ($info['game'] == 'tf') { $info['game'] = "Team Fortress 2"; }
$info['gamemode'] = $sinfo[3];
return $info;
}
cstrike.php
include('query.php');
$ip = 'play1.darkvoidsclan.com:27015';
$query = source_query($ip); // $ip MUST contain IP:PORT
$q = format_source_query($query);
$host = "<h5>Hostname: ".$q['hostname']."</h5>";
$map = "<h5>Map: ".$q['map']."</h5>";
$game = "<h5>Game: ".$q['game']."</h5>";
$players = "Unknown";
$stats = json_encode(array(
"map" => $map,
"game" => $game,
"hostname" => $host,
"players" => $players
));
You need to display the response in the $.post callback:
$.post( "serverstats-cstrike/cstrike.php", { func: "getStats" }, function( data ) {
$("#map").html(data.map);
$("#hostname").html(data.hostname);
$("#game").html(data.game);
$("#players").html(data.players);
}, "json");
You haven't shown your HTML, so I'm just making up IDs for the places where you want each of these things to show.
There are some things that I can't understand from your code, and echoMap() is a bit messed up... but assuming that your php is ok it seems you are not calling the echomap function when the post request is completed.
Add echoMap() right after players = ( data.players );
If the div id you want to modify is 'cstrike-map' you could use jQuery:
Change the JS echoMap to this
function echoMap(){
$("#cstrike-map").html("<h5>Map: " + map + "</h5>");
}
So what I did was I had to echo the content that I needed into the PHP file, then grab the HTML content and use it.
That seemed to be the most powerful and easiest way to do what I wanted to do in the OP.
<script type="text/javascript">
$(document).ready(function(){
$.post("stats/query.cstrike.php", {},
function (data) {
$('#serverstats-wrapper-cstrike').html (data);
$('#serverstats-loading-cstrike').hide();
$('#serverstats-wrapper-cstrike').show ("slow");
});
});
</script>
PHP
<?php
include 'query.php';
$query = new query;
$address = "play1.darkvoidsclan.com";
$port = 27015;
if(fsockopen($address, $port, $num, $error, 5)) {
$server = $query->query_source($address . ":" . $port);
echo '<strong><h4 style="color:green">Server is online.</h4></strong>';
if ($server['vac'] = 1){
$server['vac'] = '<img src="../../images/famfamfam/icons/tick.png">';
} else {
$server['vac'] = '<img src="../../images/famfamfam/icons/cross.png">';
}
echo '<b>Map: </b>'.$server['map'].'<br />';
echo '<b>Players: </b>'.$server['players'].'/'.$server['playersmax'].' with '.$server['bots'].' bot(s)<br />';
echo '<b>VAC Secure: </b> '.$server['vac'].'<br />';
echo '<br />';
} else {
echo '<strong><h4 style="color:red">Server is offline.</h4></strong>';
die();
}
?>
I want a user to input a country, then it will output its population. My javascript is suppose to look up the country that the user input when the button is clicked, then goes through the PHP file and gets the country's population.
my HTML is:
<label>
Country:
<input name="country" type="text" id="country"></label>
<input type="button" value="Find population" id="findPop">
<p id="output"></p
and javascript:
var countryFound = function(data) {
var theCountry = $("#country").val();
var population = data["country"];
if (data["country"])
{
$("#output").html(theCountry + " population is " + population);
}
else {
$("#output").html(theCountry + " is not found");
}
};
$("#findPop").click(function(){
var theCountry = $("#country").val();
$("#output").html("Loading...");
$.getJSON("countrylookup.php", "country="+theCountry , countryFound);
});
my PHP code is:
if (isset($_GET['country'])) { // get the parameters country
$column = 'country';
$value = $_GET['country'];
else {
print -1; // an error code
return;
}
$data = array( 'country'=>'Peru', 'capital'=>'Lima', 'area'=>'1285220', 'population'=>'29907003', 'continent'=>'South America' ),
array( 'country'=>'Philippines', 'capital'=>'Manila', 'area'=>'300000', 'population'=>'99900177', 'continent'=>'Asia' );
function findData ( $whichColumn, $data, $searchValue)
{
$result = array();
foreach ($data as $row) {
if ($row[$whichColumn] == $searchValue)
$result[] = $row;
}
return $result;
}
print json_encode ( findData($column, $data, $value) );
but for some reason, when I input Peru as the country, it says Peru is not found. Am I not retrieving the correct data from the php or what? I'm pretty sure that my php code is correct.
Here's how I'd do it :
$(function() {
$("#findPop").on('click', function(){
var theCountry = $("#country").val();
$("#output").html("Loading...");
$.getJSON("countrylookup.php", {country: theCountry}, function(data) {
var population = data[0] != "false" ? data.population : false,
msg = population ? (" population is " + population) : " is not found";
$("#output").html(theCountry + msg);
});
});
});
PHP
$value = isset($_GET['country']) ? strtolower(trim($_GET['country'])) : false;
$result = false;
if ($value) {
$data = array(
'peru' => array(
'capital'=>'Lima',
'area'=>'1285220',
'population'=>'29907003',
'continent'=>
'South America'
),
'philippines' => array(
'capital'=>'Manila',
'area'=>'300000',
'population'=>'99900177',
'continent'=>'Asia'
)
);
if (array_key_exists($value, $data)) $result = $data[$value];
}
echo json_encode($result);
For the jQuery side, I recommend using the .get() function.
$("#findPop").click(function(){
var theCountry = $("#country").val();
$("#output").html("Loading...");
$.get("countrylookup.php", function(data) {
if(data) {
// Do whatever you want to do with the data, e.g.:
var population = data.population,
theCountry = $("#country").val();
// Do more magic
$("#output").html(theCountry = " population is " + population)
} else {
// Error handling
}
});
});
There is a } missing before the else in the fourth line of the PHP code.