Saturday, September 24, 2011

Applet to AJAX to PHP methodology

I have an Applet, which adds lines to a database one at a time, by sending an SQL string via AJAX to a PHP script. The Applet data insertion method is as follows:

private void addItem3(String newWord) {
if(LIVE) {
if(jso != null )
try {
jso.call("updateWebPage", new String[] {newWord});
}
catch (Exception ex) {
addItem2("jso call failed... ");
ex.printStackTrace();
}
}
}

Where the parameter newWord being passed to that method might look like:

INSERT INTO mytable (Partid, OpCode, ItemLeft, ItemRight, Raw, Rate) VALUES (684, 1, 2, 5, 1, 34)

The JavaScript function updateWebPage and the PHP script were given in my previous post, so I won't repeat them here.

The thing is, even a single instance of the Applet can generate new lines very quickly, sometimes once a second. So a classroom of 25 students might generate 25 lines a second. How will my ISP server react to all these requests to open a connection, insert a single line of data, and close the connection.

In my experience, a typical eCommerce interaction involves a fairly long data reading session (browsing a catalogue) and then at the end, perhaps the insertion of a single line of data into a purchase order table. And from forum browsing, most Applet games seem to download some data at the start of the game, and then perhaps upload a line of data at the the end of the game. And if it is a game like Pacman, it might last for 10 or 15 minutes, or longer. So I am inclined to believe that your average eCommerce server, and certainly not a budget one like the one I use, is not designed to cope with such frequent data updates from a single source.

This blog is intended for theory questions and problems. Practical implementation thoughts and solutions are the domain of my Rasch blog, so I think I'll transfer this one over there.

Tuesday, September 20, 2011

Applet to JavaScript to PHP post to Database

This post brings together the previous two. In the first, I called PHP code from a JavaScript function using an AJAX command. In the second, I passed an SQL command to a JavaScript function. In this post I describe bringing the two together. Instead of simply displaying the SQL in a text box on the web page, passing it to a PHP file.

The applet code was unchanged, but the JavaScript function was extended from:

<script type="text/javascript">
function updateWebPage(myArg)
{
document.getElementById("txt1").innerHTML=myArg;
}
</script>

to:

<script type="text/javascript">
function updateWebPage(myArg)
{
document.getElementById("txt1").innerHTML=myArg;
if (myArg=="")
{
document.getElementById("cbxItem").innerHTML="";
return;
}
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.getElementById("cbxItem").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","putitem.php?id="+myArg,true);
xmlhttp.send();
}
</script>

And the HTML table had an extra couple of cells added:

<table border=1 align='center' cellpadding=0 cellspacing=0 >
<tr><td style='text-align:center; background-color:#C0C0C0'>Compiled Java Applet</td></tr>
<tr><td><applet code="JSHelloWorld2.class"
width="500" height="80" MAYSCRIPT style="border-width:0;" name="jsap" id="jsap">
</applet> </td></tr>
<tr><td style='text-align:center; background-color:#C0C0C0'>HTML Textbox filled by JavaScript</td></tr>
<tr><td><textarea style='width:500px; height:50px' name='txt1' id='txt1'>Query goes here</textarea></td></tr>
<tr><td style='text-align:center; background-color:#C0C0C0'>HTML diagnostic messages rendered by PHP script</td></tr>
<tr><td><div id="cbxItem">PHP info will populate this space</div></td></tr>
</table>

The PH script was:

<?php
$id = $_GET['id'];
include('dbinfo.php');// collect database variables and connect.
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
// first use encodeURIComponent on javascript to encode the string
// receive json string and prepare it to json_decode
$jsonStr = stripslashes ($id);
$query = $jsonStr;
$result = mysql_query($query) or die(mysql_error());
echo"<p>The query is: $query </p>";
echo"<p>The result is: $result </p>";
mysql_close($con);

?>

I hate it when people put obscure references in code, so for anyone who has not been following this blog, the dbinfo.php structure was given in the Simple Web Application – Data Display page.

On opening, the web page looked as shown below:

And after clicking the button on the applet, it was as shown below:

The result of 1 (or true) returned by the query indicated that a line had been successfully inserted. Inspection of the database using the Simple Web App, confirmed that this was the case. The only minor problem was the loss of the plus sign in "Itemdet", but that can be fixed.

Monday, September 19, 2011

Pass SQL command from Applet to JavaScript function

My last post recorded an important milestone for me, because I managed to call PHP code from a JavaScript function.

On an earlier occasion, I had managed to call a JavaScript function from an Applet.

My next task was to put the two together, and I did this in two steps the first of which (reported in the current post) was to adapt the previous Applet to JavaScript example to display an SQL command. This was essentially a cosmetic exercise, but it acted as a refresher on the code.

The only change to the Applet code was to replace "Hello World" with an SQL string. There is no need to reprint that here as it was given in my previous post on the topic.

In the HTML, I modified the table to display the Applet above the text box, and I widened them both. I also removed the update Applet function, as it was not required for the current exercise. It was then as follows:

<html>
<body>
<script type="text/javascript">
function updateWebPage(myArg)
{
document.getElementById("txt1").innerHTML=myArg;
}
</script>
<form>
<table border=0 align='center' cellpadding=0 cellspacing=0 >
<tr>
<td valign='top'>
<table>
<tr><td style='text-align:center; background-color:#EEEEEE'>Applet</td></tr>
<tr><td>
<applet code="JSHelloWorld2.class"
width="500" height="80" MAYSCRIPT style="border-width:0;" name="jsap" id="jsap">
</applet> </td></tr>
<tr><td style='text-align:center; background-color:#EEEEEE'>JavaScript</td></tr>
<tr><td><textarea style='width:500px; height:50px' name='txt1' id='txt1'>Query goes here</textarea></td></tr>
</table>
</form>
</body>
</html>

It came up initially as shown below:

After clicking the Applet button it was then as shown below:

And to my amazement, I could modify the text (see below) as many times as I liked, and the modified text was transferred across every time.

Sunday, September 18, 2011

PHP and JavaScript/AJAX database query

Including the term JavaScript here is tautologous really because AJAX written out in full is Asynchronous JavaScript and XML. But as combining PHP and JavaScript has become something of a holy grail for me, I thought I'd include it anyway. In fact my September 9 blog entry was originally posted under the title PHP and JavaScript (so keen was I to use it), until I reflected on the text overnight and realised there was actually nothing about JavaScript in the post.

I have been running around in circles a bit over the last couple of months, but they have been good circles, because they have enriched my understanding of a number of web related topics. And my current circle has taken me back to the generally excellent and easy to follow W3Schools website. In my post on their AJAX tutorial, I bemoaned that fact that their exchanging data with a server example only read data from a "measly old text file", rather than a database. However, had I dug deeper in my first post on PHP, I might have noticed that the w3schools tutorial on the topic gives an example of communicating with a database, using AJAX and PHP, in one of the advanced sections. I shall now work through that example.

My first step is to cut and paste their exact web code to see if it works. Should I post it here? When I first began this blog, I posted almost no code, but included an array of links to sources. A couple of years later, when I went back to reread some of my early posts, I found that many of my sources had changed their URL or disappeared altogether. So I started posting code. But the question then arises, should the full 30 or more line copyright notice be included with every code snippet. I think not. That would render the blog unreadable. "Fair Practice Law" in most countries allows you to copy snippets, certainly from literature, as long as you acknowledge your source. Would that apply to a full working web page? Possibly not. I shall refrain from quoting it, and apologise if the source subsequently disappears.

Of course I have posted code for some working web pages in my last few entries, (and in fact below) but I think one, of a couple of important questions, is did I copy something and change it, or did I write something of my own and draw inspiration from a source. It is something of a moot point, but I think there are a couple of things to bear in mind. Did I begin with a downloaded file, or did I begin with a clean sheet of paper? In this case I began clean, because of the database communication differences. A second important question is did I use a single source for inspiration? Again, I used more than one source, for practical and cosmetic reasons.

Meanwhile, back in reality, I have cut and pasted the HTML, and it works. And while I am not posting the HTML, I shall post a screen shot (below), because on an empty page it looks a bit different. But it certainly works. I had a quick look at the dropdown box, and the names were all there as in the tutorial. Obviously I refrained from selecting one because I haven't written a PHP file. And this is where I have to put my thinking cap on, because for this to be useful to me, it has to work with my data, and there are no "names" in my database.

Getting it to work for me involved one major change to the HTML, and a few cosmetic changes. The major change was to rewrite the dropdown box from scratch to make it meaningful for my data. The cosmetic changes were to variable names - not strictly necessary, but they always say variable names should try to reflect what they contain.

An important point to note here, for the unwary, is that parameters passed by AJAX seem to in the form of strings. The index field in my database is an integer, so I was tempted to try and pass an integer through AJAX. But from my notes on AJAX the syntax of the open method is:

xmlhttp.open("METHOD","URL",async);

Where URL is, and will always be a string. So in my code (shown below), my attempts to change the idx variable (in the function, and in the dropdown box) to a number were futile, and had to be abandoned. The variable was passed as a string, but the character was included in the SQL statement (shown further below) as a number.

A final point is that I included some diagnostic lines, but these were pretty redundant as PHP errors were picked up in the parse, and SQL errors were also caught by an error trap in the code. After all this, my HTML was:

<html>
<head>
<head>
<title>AJAXPHPexpt1</title>
<script type="text/javascript">
function showItem(idx)
{
if (idx=="")
{
document.getElementById("cbxItem").innerHTML="";
return;
}
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.getElementById("cbxItem").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","getitem.php?id="+idx,true);
xmlhttp.send();
}
</script>
</head>
<body>
<form>
<select name="itemselection" onchange="showItem(this.value)">
<option value="">Select an item:</option>
<option value="2">2+2=</option>
<option value="4">2+3=</option>
<option value="7">4+3=</option>
</select>
</form>
<br />
<div id="cbxItem"><b>Item info will be listed here.</b></div>
</body>
</html>

And my PHP code was:

<?php
$id = $_GET['id'];
include('dbinfo.php');// collect database variables and connect.
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
$query = "SELECT * FROM mytable WHERE Itemid=".$id;
$result = mysql_query($query) or die(mysql_error());
echo"<p>The item id is now: $id </p>";
echo"<p>The query is: $query </p>";
echo
'<table style="text-align:center;">
<tr bgcolor="#CCCCCC">
<td width="60"><strong>Itemid</strong></td>
<td width="60"><strong>Partid</strong></td>
<td width="60"><strong>OpCode</strong></td>
<td width="60"><strong>Itemdet</strong></td>
<td width="60"><strong>Raw</strong></td>
<td width="60"><strong>Rate</strong></td>
</tr>';
while($row = mysql_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['Itemid'] . "</td>";
echo "<td>" . $row['OpCode'] . "</td>";
echo "<td>" . $row['Partid'] . "</td>";
echo "<td>" . $row['Itemdet'] . "</td>";
echo "<td>" . $row['Raw'] . "</td>";
echo "<td>" . $row['Rate'] . "</td>";
echo "</tr>";
}
mysql_close($con);
?>

And after selecting an item, the page was as shown below:

Saturday, September 17, 2011

Simple Web Application – Delete Data line

Once again I should like to acknowledge the Virginia Tech Simple Web Application sample code, which provided a template for this little project, which has really helped to improve my practical understanding of PHP.

Having said that, the code, required to delete lines from the database, is pretty slim. Once again I bloated it out with some diagnostic HTML, just to check the query. I hate running blind.

The bloated code was as follows:

<?php
$id = $_GET['id'];
if (empty($id)) {
Header("Location: listcontacts.php");
exit;
}
include('dbinfo.php');// collect database variables and connect.
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
$query = "DELETE FROM mytable WHERE Itemid=".$id;
$result = mysql_query($query) or die(mysql_error());
mysql_close($con); //close connection because job finished
// Header("Location: jsphp4.php"); //return to main display form
?>
<html>
<head>
<title>Delete item diagnostics</title>
</head>
<body>
<h1>Delete Item</h1>
<p>The item id is now: <?php echo $id ?> </p>
<p>The query is: <?php echo $query ?> </p>
</body>
</html>

And the page was as shown below:

After checking the query, the slimmed down “production” code was:

<?php
$id = $_GET['id'];
if (empty($id)) {
Header("Location: listcontacts.php");
exit;
}
include('dbinfo.php');// collect database variables and connect.
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
$query = "DELETE FROM mytable WHERE Itemid=".$id;
$result = mysql_query($query) or die(mysql_error());
mysql_close($con); //close connection because job finished
Header("Location: jsphp4.php"); //return to main display form
?>

And of course there is no pic to show, because after the delete code has run we are returned to the main page.

In fact this whole exercise derived from a desire to check how that is done - modifying data in a database while (having the illusion of) remaining on the same page.

So now I have called a JavaScript function from an Applet, and I have called a PHP script, which has modified data in a database, from a button on a web page.

My next step is to call a PHP script from an Applet.

Friday, September 16, 2011

Simple Web Application – Add Data Form

While I must still acknowledge the Virginia Tech Simple Web Application sample code, at this stage in the project I was primarily cutting and pasting from the code shown in my previous posts, and manually making a few small changes from the sample code.

The code used in the Add data line form is very similar to that for the Edit data line form, except that there is no existing data to display, and the SQL command is INSERT rather than UPDATE.

I also removed the input validation code. Any data entered manually into my database is bogus and must be deleted after this exercise has finished, so it really doesn't matter what fields are filled or left empty.

With no data to display, there no need to confirm that a data line was being correctly passed from the main display form, and no need to confirm that the line was being correctly read. I therefore left in just a couple of diagnostic messages at the top of the form:

<p>The query is: <?php echo $query ?> </p>
<p>Status is: <?php echo $jonathan ?> </p>

Of course to view these lines after clicking the add button, it is necessary to comment out the instruction to return to the main form right after adding data as follows:

// Header("Location: jsphp4.php"); //return to main display form

When everything is working the comment strokes (on the left) can be removed, and the diagnostic lines can be removed from the HTML.

My working (diagnostic) code was as follows:

<?php
include('dbinfo.php');// collect database variables and connect.
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
if (isset($_POST['addcontact'])) { // run this when the user hits the "Add Contact" button
$jonathan="Add loop";
$Partid = $_POST['Partid'];
$OpCode = $_POST['OpCode'];
$Itemdet = $_POST['Itemdet'];
$Raw = $_POST['Raw'];
$Rate = $_POST['Rate']; // input validation removed from under here
$query = "INSERT INTO mytable (Partid, OpCode, Itemdet, Raw, Rate) VALUES (".$Partid.",".$OpCode.",'".$Itemdet."',".$Raw.",".$Rate.")";
$result = mysql_query($query) or die(mysql_error()); //adds form inputs
mysql_close($con); //close connection because job finished
Header("Location: jsphp4.php"); //return to main display form
}
?>
<html>
<head>
<title>Add a Line</title>
</head>
<body>
<h1>Add a Line</h1>
<p>The query is: <?php echo $query ?> </p>
<p>Status is: <?php echo $jonathan ?> </p>
<form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<table style="text-align:right;">
<tr><td>Partid:<input name="Partid" type="text" value="<?php echo $Partid; ?>"></td></tr>
<tr><td>Opcode:<input name="OpCode" type="text" value="<?php echo $OpCode; ?>"></td></tr>
<tr><td>Itemdet:<input name="Itemdet" type="text" value="<?php echo $Itemdet; ?>"></td></tr>
<tr><td>Raw:<input name="Raw" type="text" value="<?php echo $Raw; ?>"></td></tr>
<tr><td>Rate:<input name="Rate" type="text" value="<?php echo $Rate; ?>"></td></tr>
<tr><td><input type="submit" name="addcontact" value="Add Line"></td></tr>
</table>
</form>
<p><a href="jsphp4.php">Click here to return to List</a></p>
</body>
</html>

And after clicking the Add Line button, the page, with diagnostic code, was as shown below:

After removing the diagnostic code the page came up as shown below:

Thursday, September 15, 2011

Simple Web Application – Data edit form

The Virginia Tech Simple Web Application sample code works perfectly on their server, but as I reported in my previous post, getting something similar to run with my own database has been a fairly long and frustrating task.

I said in my last post that I constructed my own PHP PEAR database layer, as a result of which, my code and the sample code diverged from an early point. Specifically:

include('dbconnect.php');

was stretched out to:

include('dbinfo.php');
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);

I had some specific problems with certain lines of the sample code. One was:

$result = $database->query($query);

I didn’t understand the funny little -> in this line (I think it might have something to do with Perl, which takes it beyond the scope of this post), nor the general syntax, so I replaced it with:

$result = mysql_query($query) or die(mysql_error());

Another example was

$contact = $result->fetchRow(DB_FETCHMODE_ASSOC,0);

Which I replaced with

$contact = mysql_fetch_row($result);

I also replaced the text references to array members:

$Itemid = $contact['Itemid'];

With array member indices:

$Itemid = $contact[0];

Getting the form to work at all was a long slow process, so I added a series of diagnostic variables displayed in notes above the form. For example:

$jonathan="Default loop";

These enabled me to track which branches of code were executing, and which variables were being properly filled.

Further divergence derived from differences in the style of the data. The sample code set out to teach among other things the different methods of entering personal data on a form (radio buttons etc.), whereas my data is mainly numeric. This first required me modify the SQL to accommodate my data types. And on the cosmetic side, because my data is uniform in style, I wanted a uniform look. I therefore put my data entry fields into a table, whereas the sample code used a lot of line breaks.

After all this, my code was as follows:

<?php
// get contact id
$id = $_GET['id'];
if (!empty($id)) { $_SESSION['recordId']=$id; }
else { $id = $_SESSION['recordId']; }
// if the script has been called without ID or the user hit "Cancel" just return to listing
if (empty($id) || isset($_POST['cancel'])) {
Header("Location: jsphp4.php");
exit;
}
include('dbinfo.php');
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
$query = "SELECT * FROM mytable WHERE Itemid=".$id;
$result = mysql_query($query) or die(mysql_error());
$contact = mysql_fetch_row($result);
$Itemid = $contact[0];
$OpCode = $contact[1];
$Partid = $contact[2];
$Itemdet = $contact[3];
$Raw = $contact[4];
$Rate = $contact[5];
mysql_close($con);
?>
<html>
<head>
<title>Edit Items Table</title>
</head>
<body>
<a href="jsphp4.php">Add a Line</a> | <a href="jsphp4.php">Session Data</a>
<h1>Edit Item</h1>
<p>The item id is now: <?php echo $id ?> </p>
<p>The query is: <?php echo $query ?> </p>
<p>The op code is: <?php echo $query ?> </p>
<form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<table style="text-align:right;">
<tr><td>Itemid:<input name="Itemid" type="text" value="<?php echo $Itemid; ?>"></td></tr>
<tr><td>Opcode:<input name="OpCode" type="text" value="<?php echo $OpCode; ?>"></td></tr>
<tr><td>Partid:<input name="Partid" type="text" value="<?php echo $Partid; ?>"></td></tr>
<tr><td>Itemdet:<input name="Itemdet" type="text" value="<?php echo $Itemdet; ?>"></td></tr>
<tr><td>Raw:<input name="Raw" type="text" value="<?php echo $Raw; ?>"></td></tr>
<tr><td>Rate:<input name="Rate" type="text" value="<?php echo $Rate; ?>"></td></tr>
<tr><td><input type="hidden" name="id" value="<?php echo $id; ?>">
<tr><td><input type="submit" name="ok" value=" OK ">
<tr><td><input type="submit" name="cancel" value="Cancel">
</table>
</form>
</body>
</html>

And it looked like this:

Wednesday, September 14, 2011

Simple Web Application – Data Display page

I can read tutorials 'til I'm blue in the face, but unless I try to adapt the sample code to do something completely different, I don't retain anything. The live "Try it yourself" windows are quite fun, but unless I can get code running on my own or my ISP's server, I can't expose my misunderstandings or the gaps in my knowledge.

The Virginia Tech simple web application sample code works perfectly on their server, but recreating something to perform similar functions with my own database on my own server has been a fairly long and frustrating job.

I said in my last post that I could not see any gaps in the sample code. On closer inspection, I have found a couple, of which the most important was their connection code. They refer to a PHP PEAR database layer in the text and a file called DB.php in their code, but they don’t show what is in the file. So I followed the PHP PEAR link and constructed my own file based on the template given there:

<?php
$dbhost = 'localhost';
$dbuser = 'theuser';
$dbpass = 'thepassword';
$dbname = 'phptst';
?>

This meant that my code and the sample code were beginning to diverge from a fundamental point. Because my PHP PEAR database layer was different, my connection code in the main page was different. Because of that, my query code had to be different, and because of that, my display code had to be different. In fact in the end I based the whole thing on the example previously quoted on my Playing with PHP entry.

In the end, the code in my display table was like the inverse, or a mirror image of the sample code. Their display table was written in HTML, peppered with PHP variables. My display table was a long PHP statement, peppered with HTML strings.

My code was as shown below:

<?php
// if the user hasn't specified any "sort" the default is "Partid"
if ( isset($_GET['sort']) && $_GET['sort']=='OpCode' ) { $_SESSION['sort'] = 'OpCode'; }
else { $_SESSION['sort'] = 'Partid'; }
include('dbinfo.php');
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
$result = mysql_query("SELECT * FROM mytable") or die(mysql_error());
?>
<html>
<head>
<title>Session Data</title>
</head>
<script language="JavaScript">
<!--
function confirmdelete(id)
{
var c = confirm("Do you really want to delete this line?");
if (c) {
window.location="deletecontact.php?id="+id;
}
}
//-->
</script>
<body>
<a href="addcontact.php">Add a Line</a> | My Items
<h1>Session Data</h1>
<table style="text-align:center;">
<tr bgcolor="#CCCCCC">
<td width="70"><strong>Itemid</strong></td>
<td width="70"><strong><?php if ($_SESSION['sort']!='OpCode') { echo '<a href="',$_SERVER['PHP_SELF'],'?sort=OpCode">Partid</a>'; } else { echo 'OpCode ↓'; } ?></strong></td>
<td width="70"><strong><?php if ($_SESSION['sort']!='Partid') { echo '<a href="',$_SERVER['PHP_SELF'],'?sort=Partid">OpCode</a>'; } else { echo 'OpCode ↓'; } ?></strong></td>
<td width="70"><strong>Itemdet</strong></td>
<td width="70"><strong>Raw</strong></td>
<td width="70"><strong>Rate</strong></td>
<td width="70"><strong>Edit</strong></td>
<td width="70"><strong>Delete</strong></td>
</tr>
<?php
while($row = mysql_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['Itemid'] . "</td>";
echo "<td>" . $row['OpCode'] . "</td>";
echo "<td>" . $row['Partid'] . "</td>";
echo "<td>" . $row['Itemdet'] . "</td>";
echo "<td>" . $row['Raw'] . "</td>";
echo "<td>" . $row['Rate'] . "</td>";
echo '<td><a href="editcontact.php?id=' . $row['Itemid'] . '">edit</a></td>';
echo '<td><a href="deletecontact.php?id=' . $row['Itemid'] . '">delete</td>';
echo "</tr>";
}
?>
</table>
</body>

And the page looked like this:

Friday, September 9, 2011

A closer look at PHP database update options

A frustration I've had with most tutorials on using JavaScript with PHP to update a database is that the "add data" function nearly always calls a new page. In my application, I want data added to a database quietly in the background, and I certainly don't want the user dragged away from the Applet page every time a line is added to the database.

After much searching, and searches excluding terms such as "forum", (forum questions seem to dominate this topic in Google), I found an excellent page hosted by Virginia Tech. This is a really good single page tutorial, which takes the reader through all the basics of PHP, from echo "Hello World!"; to a simple web application, which includes all the essential functions of adding data, displaying data, editing data and deleting records. Better still, for each task, it includes the PHP source code, produced HTML, and rendered HTML. There are no zip files to download, and certainly at first glance, no holes or gaps in the code.

Most importantly, for me, the tutorial makes explicitly clear the code required to stay on the same page while information is being posted from a form. So if information is entered on an ordinary HTML page (with a name and extension like myForm.htm) and is to be processed by a page called myCode.php, the opening form tag should look like this:

<form method="post" action="myCode.php">

But if the posting is to be handled on a form containing the processing code (which will need the extension .php - so it might be called something like myCodedForm.php), the opening form tag should look like this:

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">

Alternatively it might look like this:

<form method="post" action="myCodedForm.php">

My plan is to adapt the examples in this tutorial to the creation of a dummy application, which adds lines to my own database, and to describe my progress here. I shall skip the database creation steps, because that has already been described here. That was for a Derby database, but I also described connecting to a MySQL version with PHP here. I shall focus on the code used to add lines, to view the table contents, and to delete lines.

My progress may be a little slow. I have read a couple of tutorials on JavaScript and PHP, but my practical working knowledge is currently very limited. I shall fiddle away, and post any interesting results as they arise.

Tuesday, September 6, 2011

Applet to JavaScript Communication

The raditha.com site, to which I referred in my Javascript to Applet Communication - Example 2 entry, also includes a page on Applet to JavaScript Communication, but I could not find the required HTML/JavaScript, either on the page or in the code files included at the end of the page. This was disappointing because overall it is the best site I have found on what Mozilla calls LiveConnect.

The Java code works, and I shall cite a simplified (less graphics) version here:

import javax.swing.*;
import netscape.javascript.JSObject;
import java.awt.*;
import java.awt.event.*;

public class JSHelloWorld2 extends JApplet {
JTextArea txt = new JTextArea(100,100);
JButton btn = new JButton("Update Page");
JSObject jso;
public JSHelloWorld2() {
txt.setText("Hello World");
getContentPane().setLayout(new BorderLayout());
getContentPane().add(txt);
getContentPane().add(btn,BorderLayout.SOUTH);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(jso != null )
try {
jso.call("updateWebPage", new String[] {txt.getText()});
}
catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
public void init()
{
jso = JSObject.getWindow(this);
}
public void setText(String s)
{
txt.setText(s);
}
}

And the HTML/JavaScript I used was:

<html>
<body>
<script type="text/javascript">
function updateApplet()
{
document.jsap.setText(document.forms[0].txt1.value);
}
function updateWebPage(myArg)
{
document.getElementById("txt1").innerHTML=myArg;
}
</script>
<form>
<table border=0 align='center' cellpadding=0 cellspacing=0 >
<tr>
<td valign='top' width=180>
<table>
<tr><td style='text-align:center; background-color:#EEEEEE'>Applet</td></tr>
<tr><td>
<applet code="JSHelloWorld2.class"
width="180" height="180" MAYSCRIPT style="border-width:0;" name="jsap" id="jsap">
</applet> </td></tr>
</table>
</td>
<td valign='top' width=180>
<table width=180>
<tr><td style='text-align:center; background-color:#EEEEEE'>JavaScript</td></tr>
<tr><td><textarea style='width:180px; height:150px' name='txt1' id='txt1'>Type and click!</textarea></td></tr>
<tr><td align='center'><input type=button value='Update applet' onClick='updateApplet()'></td></tr>
</table>
</td></tr>
</form>
</body>
</html>

The updateWebPage function is referred to in the Java code, but I had to add the function to the web page, which when it first loads comes up as shown below.

This is very similar to the page used to demonstrate Javascript to Applet Communication except that there is an extra button in the applet. Clicking the button on the page has the same effect as before. The text in the page text box is copied across to the applet. But now if you click the button on the Applet, the text from there is copied across to the box on the page (see below).

I could only get it to work once for every page load, but the fact that it works at all is a major step forward for me. I have at last succeeded in calling a JavaScript function from within an applet.

My next step is to learn how to combine JavaScript with PHP to add lines to my database. Build this into a function, and I should be able to call it from within my own applet.

Monday, September 5, 2011

LiveConnect and JavaScript Wrappers

From the LiveConnect page on the Mozilla web site:

LiveConnect is the name of an application programming interface that provides JavaScript with the ability to call methods of Java classes and vice-versa using the existing Java infrastructure.

LiveConnect use by applets is enabled via the use of the "MAYSCRIPT" attribute in applet tags on an HTML page, following which the applet may refer to classes in the netscape.javascript package to access Javascript objects, and scripts may directly call applet methods (using the syntax document.applets.name.methodName()).

From the LiveConnect Overview page on the same site:

In JavaScript, a wrapper is an object of the target language data type that encloses an object of the source language. When programming in JavaScript, you can use a wrapper object to access methods and fields of the Java object; calling a method or accessing a property on the wrapper results in a call on the Java object. On the Java side, JavaScript objects are wrapped in an instance of the class netscape.javascript.JSObject and passed to Java.

When a JavaScript object is sent to Java, the runtime engine creates a Java wrapper of type JSObject; when a JSObject is sent from Java to JavaScript, the runtime engine unwraps it to its original JavaScript object type. The JSObject class provides an interface for invoking JavaScript methods and examining JavaScript properties.

The LiveConnect page has a number of dead links, including one called "LiveConnect Testcases", which sounded interesting, and another called "Core JavaScript 1.5 Reference: LiveConnect". I found a current JavaScript Reference page, but I could find no reference to LiveConnect on the page.

Sunday, September 4, 2011

Javascript to Applet Communication - Example 2

I have found another article on this topic where the code works and I shall cite it here because the Java code is simpler and therefore perhaps more elegant than the previous one.

import javax.swing.*;
import netscape.javascript.JSObject;

public class JSHelloWorld extends JApplet {
JTextArea txt = new JTextArea(100,100);
public JSHelloWorld() {
txt.setText("Hello World");
getContentPane().add(txt);
}

public void setText(String s)
{
txt.setText(s);
}
}

The HTML, on the other hand is a bit more wordy, because the Applet and the JavaScript form are laid out side by side, but I like it:

<html>
<body>
<script type="text/javascript">
function updateApplet()
{
document.jsap.setText(document.forms[0].txt1.value);
}
</script>
<form>
<table border=0 align='center' cellpadding=0 cellspacing=0 >
<tr><td valign='top' width=180>
<table>
<tr><td style='text-align:center; background-color:#EEEEEE'>Applet</td></tr>
<tr><td><applet code="JSHelloWorld.class"
width="180" height="180" MAYSCRIPT style="border-width:0;" name="jsap" id="jsap">
</applet> </td></tr></table>
</td><td valign='top' width=180>
<table width=180>
<tr><td style='text-align:center; background-color:#EEEEEE'>JavaScript</td></tr>
<tr><td><textarea style='width:180px; height:150px' name='txt1'>Type and click!</textarea></td></tr>
<tr><td align='center'><input type=button value='Update applet' onClick='updateApplet()'></td></tr>
</table>
</td></tr>
</form>
</body>
</html>

This comes up as shown below.

You can then type something into the box on the form, or you can leave it as it is and click the button. It then becomes as shown below.

Full original versions of the code can be downloaded from this page.

Friday, September 2, 2011

Java Applet/Javascript Communication

So I have established that for the last decade, not many people have used Applets in web pages. The resulting paucity tutorials or recent examples made it very difficult even to scratch the surface of how to do this. I know when I write notes here, I often skip steps, which seem too obvious or easy, so that when I revisit an entry written two years ago, even I find it hard to follow. So I can't criticize others for being cryptic, or telling only half the story. But it has been frustrating wading through articles with gaps, or code that doesn't work.

But where to begin with an attempt at a full story? I think a revisit to paths and class paths.

In order to compile and run java classes, you need to set a path to the JDK binaries folder. This can be done once at the start of a command window session, or even as a Windows environment variable.

In order to run classes which connect to a database, you need set a "class" path to a special .jar package containing classes pertaining to communication with the database, every time you run the class.

Java Applet/Javascript Communication requires yet another variant. In order to compile a class which will communicate with Javascript, you have to set a class path, every time you compile the class, to a .jar package with the all-informative name of plugin.jar. This contains the classes needed for an applet to call javascript functions. It can be found in /lib directory of the JRE installation (e.g. C:\Program Files\Java\jre7\lib). The command to compile the class myClass then becomes:

javac -classpath "C:\Program Files\Java\jre7\lib\plugin.jar" myClass.java

I wasted a lot of time adding plugin.jar to the JDK binaries folder, and to my code folder, and couldn't think why sample code cut and pasted from web pages wouldn't compile. It doesn't matter where the .jar file is, as long as a path to it is included with every compile command.

The second step included in all the articles on java applet to javascript communication is to add the import:

import netscape.javascript.*;

If you don't include a class path to plugin.jar in your compile command, this line will generate the first of many compile errors.

The third step is to write some code in the java applet which actually works. I hunted and hunted for this. The best example I found was on this web page. I should like give them credit for showing me a solution, but I have modified the code to look more like my earlier Hello World example. The applet code is:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import netscape.javascript.*;

public class HelloWorldB extends Applet {
String text="Hello world!";
JSObject win, doc, form, textField;

public void init() {
win = JSObject.getWindow(this);
doc = (JSObject) win.getMember("document");
form = (JSObject) doc.getMember("textForm");
textField = (JSObject) form.getMember("textField");
setLayout(new BorderLayout());
Panel buttons = new Panel();
Button displayTextButton = new Button("Display Text");
displayTextButton.addActionListener(new ButtonEventHandler());
buttons.add(displayTextButton);
add("South",buttons);
}
public void paint(Graphics g) {
g.drawString(text,30,30);
}

class ButtonEventHandler implements ActionListener {
public void actionPerformed(ActionEvent e){
String s = e.getActionCommand();
if("Display Text".equals(s)) {
text= (String) textField.getMember("value");
repaint();
}
}
}
}

The fourth step included in the articles on java applet to javascript communication is to add "MAYSCRIPT" to the Applet tag.

The web code is then:

<html>
<body>

<applet code="HelloWorldB.class"
WIDTH=200 HEIGHT=70 MAYSCRIPT>
</applet>
<form NAME="textForm">
<P>Enter text and click button:<br>
<INPUT TYPE="text" NAME="textField" SIZE="20"></P>
</FORM>

</body>
</html>

This comes up as shown below:

Then you add text as shown below:

And when you click the button it come up as:

This example takes information from a web page and displays it in an applet. I am actually hoping to do the reverse, but it is a step in the right direction.