Hi I have two dropdowns and I am populating second one on the basis of first one. My first select is
<select name="projects" id="projects" onchange="populate_users(this.value);">
<option value='1'>ABC</option>
<option value='2'>DEF</option>
</select>
And I populate second select box on the basis of first one which is
<select name="users" id="users">
</select>
Here is my populate_users method
function populate_users(project_id)
{
var url='<?php echo($this->url(array(),'admin/clientproject1'));?>';
url2=url+'project_id='+project_id;
//alert(url2);
jQuery('#users').html('<div style="position:absolute;">'+jQuery('#users').html());
//ajax call
jQuery.ajax({url:url2,success:function(data){jQuery('#users').html(data);}});
}
And on admin/clientproject1 I simply query to table and start a loop to draw options like this
$rd=$db->fetchAll($q);
for($i = 0; $i < count($rd); $i++)
{
?>
<option value="<?php echo($rd[$i]->id);?>">
<?php echo($rd[$i]->username);?></option>
<?php
}
?>
$rd is having values. The second select is populated and all values are showing in
Firefox but in IE it is just showing blank dropdown and not showing any error.
You should return a json string of values and create the option elements in javascript. Then inject those option elements into your select. A bit more coding, but it's better.
Whenever I see the words AJAX, IE, and not populating, I think of the IE cache and how it doesn't play nice with AJAX. Since the issue is browser based, I don't see how it can be a problem with your actual php and the formatting appears to be correct, maybe try setting some headers in the php page that is querying the db.
header("Expires: Sun, 19 Nov 1978 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
My solution is create the 'option adding' in server and javascript 'eval' in client the passing Ajax result:
Server Sample PHP code Populate Select :
leetablaIE.php :
$DBName=$_GET["db"];
$tabla=$_GET["tabla"];
$Query=$_GET["query"];
$id=$_GET["id"];
$User="???????";
$Host="????????";
$Password="????????";
$Link=mysql_connect( $Host, $User, $Password);
if (!$Link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db($DBName, $Link) or die('Could not select database.');
$Result=mysql_db_query ($DBName , $Query , $Link);
echo 'var obj_option;';
echo "obj_option = document.createElement('option');" ;
echo "obj_option.setAttribute('value', '');";
echo "obj_text = document.createTextNode('".utf8_encode('Select Value')."');" ;
echo "obj_option.appendChild(obj_text);";
echo "document.getElementById('$id')".".appendChild(obj_option);"; //myselect
while($Row = mysql_fetch_array($Result)) {
$valor=utf8_encode($Row[0]);
$texto=utf8_encode($Row[1]);
echo "obj_option = document.createElement('option');" ;
echo "obj_option.setAttribute('value', '".$valor."');";
echo "obj_text = document.createTextNode(\"".$texto."\");" ;
echo "obj_option.appendChild(obj_text);";
echo "document.getElementById('$id')".".appendChild(obj_option);"; //myselect
}
mysql_free_result($Result);
in Javascript Client :
function leetabla(db,tabla,query,id,bro){
// bro = passing browser ex: MSIE
// id = passing id select to populate in example myselect
// db = database
// tabla = table (mysql id this case)
// query = query you need to populate ('select ....')
////////////////////////////////////////////////////
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
if(bro!='MSIE'){
document.getElementById(id).innerHTML="";
document.getElementById(id).innerHTML=xmlhttp.responseText;
}
else
{
//alert(xmlhttp.responseText);
eval(xmlhttp.responseText);
}
}
}
if(bro!='MSIE'){
//alert(query);
//normal populate code not in this code 'leetabla.php'
xmlhttp.open("GET","leetabla.php? db="+db+"&tabla="+tabla+"&query="+query+"&id="+id,true);
}
else
{
//alert(query);
// call to php script to IE case leetablaIE.php (upper sample)
xmlhttp.open("GET","leetablaIE.php? db="+db+"&tabla="+tabla+"&query="+query+"&id="+id,true);
}
xmlhttp.send();
}
Related
Please excuse me, I am quite new with backend development.
What I try to accomplish is pretty straight forward. I want to send a POST request to my server. As an example; www.domain.com/api.php?id=foo
And with that value update my SSE with that parameter. But I can't seem to figure it out. I guess I need to store that value somehow in a database or a text file? Preferably in a text file for simplicity.
What I have now:
HTML file:
<!DOCTYPE html>
<html>
<body>
<h1>Getting server updates</h1>
<div id="result"></div>
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("demo_sse.php");
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>
PHP file:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$test = "One";
echo "data: Page: {$test}\n\n";
flush();
?>
So my question is: How do I change the value of the variable 'test' from a POST request so that the SSE is updated?
It works perfectly now, if I change the value in the PHP file it starts spitting that out in the HTML. But how do I change that value with something external like a POST call?
Thank you! And let me know if I need to clarify.
Okay, so I managed to make it work with a SQL database. :) This is my solution:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
// QUERY THE DATABASE FOR CURRENT PAGE NUMBER
$db = new mysqli($host, $username, $password, $database_name); // connect to the DB
$query = $db->prepare("SELECT number FROM page WHERE itemId=1"); // prepate a query
$query->execute(); // actually perform the query
$result = $query->get_result(); // retrieve the result so it can be used inside PHP
$r = $result->fetch_array(MYSQLI_ASSOC); // bind the data from the first result row to $r
// ECHO SERVER SENT EVENT
$pageNumber = $r['number'];
echo "data: Page: {$pageNumber}\n\n";
flush();
// UPDATE QUERY BASED ON GET PARAMATERS
$siteURL = $_GET['page'];
$updateQuery = $db->prepare("UPDATE `page` SET `number` = '$siteURL' WHERE `page`.`itemId` = 1;");
$updateQuery->execute();
?>
I'm trying to set up a PHP server send event, which works okay. But at random intervals it is pushing the same data repeatedly.
Here's a quick scenario to clarify what I'm describing: Let's say I insert a db record at 1:00:00. The record's data is pushed as it should. However, at 1:03:00 that record's data is pushed a second time. Then at 1:03:17, it is pushed again. And I now have 3 instances of the record displayed.
Why is this happening, and why at random intervals?
I increased php execution time, but the issue is still occurring.
In the browser console, I'm getting this error: net::ERR_INCOMPLETE_CHUNKED_ENCODING.
I have this for client side:
<script>
var source = new EventSource('pdo_updates.php');
var pdo_updates;
source.onmessage = function(e) {
pdo_updates = e.lastEventId + '' + e.data + '<br>';
document.getElementById("videoID").innerHTML += pdo_updates;
};
evtSource.close();
</script>
And this for server side:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
function send_msg($id, $msg) {
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
$last_event_id = floatval(isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? $_SERVER["HTTP_LAST_EVENT_ID"] : False);
if ($last_event_id == 0) {
$last_event_id = floatval(isset($_GET["lastEventId"]) ? $_GET["lastEventId"] : False);
}
$last_id = 0;
try {
$conn = new PDO('mysql:host=localhost;dbname=my_db', $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
while(1) {
$id = $last_event_id != False ? $last_event_id : $last_id;
$stmt = $conn->prepare("SELECT id, message FROM messages WHERE id > :id ORDER BY id DESC LIMIT 1");
$result = $stmt->execute(array('id' => $id));
$stmt->bindValue('id', $id);
if ($result) {
while($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($data) {
send_msg($data['id'], $data['message']);
$last_id = $data['id'];
}
}
}
sleep(1);
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
So, after trying just about every keepalive related header, and every apache timeout adjustment config, I ended up running a packet capture. I discovered there was a TCP reset was being triggered by the remote end. I have my site behind Cloudflare, and once I disabled Cloudflare the issue partially disappeared. The TCP session was being refreshed every 100 seconds and would cause the last message to appear again when that happened. This was responsible for the browser console error: net::ERR_INCOMPLETE_CHUNKED_ENCODING
At the same time, however, there was an issue in my submit code. But I'm not 100% sure why.
$.ajax({
type: "POST",
url: url,
data: $("#submitmessage").serialize(), // serializes the form's elements.
success: function(data)
{
$("#myvideo").val("");
}
});
I needed to clear the value in my input field after submit. I haven't had any duplicates since.
I've changed the code with the selection boxes to the below:
<html>
<head>
<script type="text/javascript">
function loadXMLDoc() {
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.frm.modelSelection.innerHTML=xmlhttp.responseText;
}
}
var makevalue=document.frm.makeSelection.value;
xmlhttp.open("GET","http://www.autodeal.co.za/newsite/model-selection?ajaxmake="+makevalue,true);
xmlhttp.send();
}
</script>
</head>
<body>
<?php
$dbName = "F:/Domains/autodeal/autodeal.co.za/wwwroot/newsite/db/savvyautoweb.mdb";
// Throws an error if the database cannot be found
if (!file_exists($dbName)) {
die("Could not find database file.");
}
// Connects to the database
// Assumes there is no username or password
$conn = odbc_connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=$dbName", '', '');
?>
<form action="index.php?option=com_content&view=article&id=99" method="post" name="frm">
<select name="makeSelection" onchange="loadXMLDoc()">
<?php
//Loads the Makes from the database into a dropdown
$resultMake = odbc_exec($conn, "SELECT DISTINCT Make FROM Vehicle ORDER BY Make") or die (odbc_errormsg());
while ($rowMake = odbc_fetch_array($resultMake)) {
echo "<option value='$rowMake[Make]'>$rowMake[Make]</option>";
}
?>
</select><br />
<select name="modelSelection">
</select><br />
<select name="yearSelection">
<option>2004</option>
<option>2005</option>
<option>2006</option>
<option>2007</option>
<option>2008</option>
<option>2009</option>
<option>2010</option>
<option>2011</option>
<option>2012</option>
<option>2013</option>
<option>2014</option>
</select><br />
<select name="priceSelection">
<option>< 5000</option>
<option>5000 - 20 000</option>
<option>20 000 - 50 000</option>
<option>50 000 - 100 000</option>
<option>100 000 - 200 000</option>
<option>200 000 - 300 000</option>
<option>300 000 - 400 000</option>
<option>400 000 - 500 000</option>
<option>50 000 - 1 000 000</option>
<option>> 1 000 000</option>
</select>
<input type="submit" name="submit" value="Go">
</form>
</body>
</html>
Hi,
I've updated the code to reflect the answers below, but now, when you make the first selection, the Model selection box remains empty.
modelSelection.php
<?php
$dbName = "F:/Domains/autodeal/autodeal.co.za/wwwroot/newsite/db/savvyautoweb.mdb";
// Throws an error if the database cannot be found
if (!file_exists($dbName)) {
die("Could not find database file.");
}
$conn = odbc_connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=$dbName", '', '');
//loads the models based on the makes selection into a dependant dropdown
if (isset($_REQUEST['ajaxmake'])) {
$resultModel = odbc_exec($conn, "SELECT Model FROM Vehicle WHERE Make = '".$_REQUEST['ajaxmake']."'") or die (odbc_errormsg());
while ($rowModel = odbc_fetch_array($resultModel)) {
echo "<option value='$rowModel[Model]'>$rowModel[Model]</option>";
die(); //I'm not sure where to put this because I assume this is the reason why this selection must be first
}
}
?>
As far as I can see, the problem is that you are loading the whole request response text inside a select button. I've looked at your request response and it is responding the whole page with the models loaded, so basically it is getting all options and loading them on the Model select box, because you are inserting the whole page on the model select box.
You have multiple options here:
You can create a page that only loads the Model options, so have a file which has only this part:
$dbName = "F:/Domains/autodeal/autodeal.co.za/wwwroot/newsite/db/savvyautoweb.mdb";
// Throws an error if the database cannot be found
if (!file_exists($dbName)) {
die("Could not find database file.");
}
$conn = odbc_connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=$dbName", '', '');
//loads the models based on the makes selection into a dependant dropdown
if (isset($_REQUEST['ajaxmake'])) {
$resultModel = odbc_exec($conn, "SELECT Model FROM Vehicle WHERE Make = '".$_REQUEST['ajaxmake']."'") or die (odbc_errormsg());
while ($rowModel = odbc_fetch_array($resultModel)) {
echo "<option value='$rowModel[Model]'>$rowModel[Model]</option>";
}
}
And change the page you are calling through ajax to point to that page:
xmlhttp.open("GET","newpage.php?ajaxmake="+ makevalue,true);
The other option, and the one I suggest you is to look into some javascript library, such as jQuery which has functions to easen your work.
If you include jQUery library, adding the select name as id="makeSelection" and id="modelSelection" you could write a javascript function like this:
jQuery(document).ready(function(){
jQuery("#makeSelection").change(function(){
jQuery("#modelSelection").load("?ajaxmake="+ makevalue + #modelSelection option");
});
});
BTW! Be aware that you may have a huge security problem in your sql queries, since people can attack you through the ajaxmake variable, and truncate/drop your tables or anything. I suggest you to sanitize and validate the data coming from your requests, specially if you post some sensitive data like your database tables on the internet!!! If you want to know more about SQL Injection (how this security issue is called): How can I prevent SQL injection in PHP?
I am not sure why you have html included in your ajax processing file. Usually you keep a .php file consisting only of php code and then you can be sure no html or script code are being included (which is currently happening in your page now).
For one, try to change your model dropdown code to:
<?php
//loads the models based on the makes selection into a dependant dropdown
if (isset($_REQUEST['ajaxmake'])) {
echo "<select name='modelSelection'>"; //select tag placed here
$resultModel = odbc_exec($conn, "SELECT Model FROM Vehicle WHERE Make = '".$_REQUEST['ajaxmake']."'") or die (odbc_errormsg());
while ($rowModel = odbc_fetch_array($resultModel)) {
echo "<option value='$rowModel[Model]'>$rowModel[Model]</option>";
}
echo "</select><br>";
die(); //<-- the die placed here will not execute the rest of
//the code and also all the options will be populated
}
?>
I tested source code from this tutorial http://query7.com/php-jquery-todo-list-part-1 and just deploy their source taken here http://query7.com/wp-content/uploads/php-jquery-todolist.zip
To my surprise after delete action, I refreshed the screen but item is still not deleted
I can't see any bug in code can you ?
process.php
<?php
//Connect to the database
$connection = mysql_connect('localhost:3316', 'root' , 'root');
$selection = mysql_select_db('notes', $connection);
//Was the form submitted?
if($_POST['submit']){
//Map the content that was sent by the form a variable. Not necessary but it keeps things tidy.
$content = $_POST['content'];
//Insert the content into database
$ins = mysql_query("INSERT INTO `notes` (content) VALUES ('$content')");
//Redirect the user back to the index page
header("Location:index.php");
}
/*Doesn't matter if the form has been posted or not, show the latest posts*/
//Find all the notes in the database and order them in a descending order (latest post first).
$find = mysql_query("SELECT * FROM `notes` ORDER BY id DESC");
//Setup the un-ordered list
echo '<table border="0" cellpadding="5" cellspacing="0" class="list" width="100%">';
//Continue looping through all of them
while($row = mysql_fetch_array($find)){
//For each one, echo a list item giving a link to the delete page with it's id.
echo '<tr><td valign="middle" width="90%">' . $row['content'] . ' </td>
<td valign="middle" width="10%"><form id="form" action="delete.php?id=' . $row['id'] . '" method="post">
<input class="todo_id" name="todo_id" type="hidden" value="' . $row['id'] . '" />
<input class="todo_content" name="todo_content" type="hidden" value="' . $row['content'] . '" />
<input type="image" src="images/delete.png" class="delete" name="delete" width="20px" />
</form>
</td></tr>';
}
//End the un-ordered list
echo '</table>';
?>
<script type="text/javascript">
$(".delete").click(function(){
//Retrieve the contents of the textarea (the content)
var todo_id = $(this).parent().find(".todo_id").val();
var todo_content = $(this).parent().find(".todo_content").val();
//Build the URL that we will send
var url = 'submit=1&id=' + todo_id;
//Use jQuery's ajax function to send it
$.ajax({
type: "POST",
url: "delete.php",
data: url,
success: function(){
//If successful , notify the user that it was added
$("#msg").html("<p class='remove'>You just deleted: <i>" + todo_content + "</i></p>");
$("#content").val('');
todolist();
}
});
//We return false so when the button is clicked, it doesn't follow the action
return false;
});
</script>
delete.php
<?php
//Connect to the database
$connection = mysql_connect('localhost', 'root' , '');
$selection = mysql_select_db('notes', $connection);
//delete.php?id=IdOfPost
if($_POST['submit']){
//if($_GET['id']){
echo $id = $_POST['id'];
//$id = $_GET['id'];
//Delete the record of the post
$delete = mysql_query("DELETE FROM `notes` WHERE `id` = '$id'");
//Redirect the user
header("Location:index.php");
}
?>
process.php connects to a mysql database instance running on port 3316 with user root and password root, while delete.php connects to a mysql instance running on default port 3306 with user root and empty password: start from there
What happens if you put some $_GET variable in your browser and refresh again? http://localhost:8096/todolist?random=idunnosomethingiguess
I suspect that this is a browser caching issue. You can completely prevent this with
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
Of course, if you want to allow caching, then you can just use FF + Web Development toolkit and prevent caching that way.
I have a simple search form with a search box and a result box.
When I type a search word a request is created like: http://www.site.com/php_handler.php?s=hello
In the php script and a result is given back to the script this way:
<?php return $s; ?>
The problem is that my htmlrequest stops at readyState 3 it doesn't get to 4.
The javascript looks like this:
var xmlhttp = sajax_init_object();
function sajax_init_object() {
var A;
try {
A=new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
A=new ActiveXObject("Microsoft.XMLHTTP");
} catch (oc) {
A=null;
}
}
if(!A && typeof XMLHttpRequest != "undefined")
A = new XMLHttpRequest();
if (!A)
sajax_debug("Could not create connection object.");
return A;
}
function getSearchItem()
{
gs=document.forms.mainform.resultsfield;
var searchword=document.forms.mainform.searchform.value;
if (searchword.length>=3)
{
setWaitCursor();
clearResults();
var uri = "http://site.com/ajax_handler.php?s="+searchword;
console.log(uri);
xmlhttp.open("GET", uri, true);
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4) {
processResults(xmlhttp.responseText);
removeWaitCursor();
}else{
console.log(xmlhttp.readyState);
}
}
xmlhttp.send(null);
}
else
{
alert("please add at least 3 characters .");
}
}
Can someone tell me why it stops at 3?
edit: here is also the php code:
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
session_start();
//include main file
require_once($_SESSION["FILEROOT"] . "xsite/init.php");
//check if formulier is posted
$zoekterm = C_GPC::getGETVar("s");
$s="";
if ($zoekterm != "") {
$query="SELECT number,name,city,zib,zip_annex FROM articles WHERE version='edit' AND (naam LIKE '%$school%' OR brinnummer='$school') ORDER BY name";
if ($rs=C_DB::fetchRecordSet($query)) {
while ($row=C_DB::fetchRow($rs)) {
if ($row["plaats"]!="") {
$s.=$row["name"].", ".$row["city"]."|".$row["number"]."\n";
} else {
$s.=$row["name"].", ".$row["zip"].$row["zip_annex"]."|".$row["number"]."\n";
}
}
}
}
return $s;
?>
edit:
I missed a semicolon in my php script and now the ready state only gets to 2
edit:
The problem is even different. It gets to 4 but it doesn't show the result text.
1> Don't send Cache-Control: post-check=0, pre-check=0. These don't do what you think they do, and they're entirely unnecessary.
2> Your AJAX results page needs to send a Content-Length or Connection: Close header.
3> Try adding a random to your request URL to ensure you're not looking at a stale cache entry.
ReadyState 3 => Some data has been received
ReadyState 4 => All the data has been received
Maybe the XMLHTTPRequest object is still waiting for some data.
Are you sure your php script ends correctly ?
Is the content-length alright ?
To debug this you have two options, type the URL directly into the browser [since you are using a GET] and see what is happening.
OR
You can use a tool such as Fiddler and see what is exactly happening with the XMLHttpRequest