tag:blogger.com,1999:blog-88820109434724327602024-03-15T18:09:40.620-07:00Learning JavaHow easy is it to learn Java? I have been using Microsoft languages since Basic A was around in 1982. So how easy will it be for me to jump ship. There is an abundance of teaching material out there, but will it make sense to a total newcomer like me? This blog is intended to answer that question.Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.comBlogger153125tag:blogger.com,1999:blog-8882010943472432760.post-59217898690940540102013-10-22T01:40:00.001-07:002013-10-22T01:41:20.761-07:00Share Price Volatility and Swing TradingTyping "volatility" into Google yields some pretty interesting and, in my
opinion, pretty confused results. The top result from my search was
<a href="http://en.wikipedia.org/wiki/Volatility_(finance)">this
one from Wikipedia</a> and it says it all. There seem to be many
non-scientists regarding volatility as a financial market rainbow, with a crock
of gold at the end of it.<br />
<br />
Anyone with the most basic grounding in geometrical optics knows that a rain
"bow" is really a segment of a rain "ring" and the centre of that ring, and your
head, and the sun, all form a straight line, and the angle between that line and
the line from your head to the colored rings is a function of the size of the
rain droplets. So the rainbow moves with you. You can never reach out and
touch the rings, and you can certainly never navigate to the "base", conceptual
or otherwise.<br />
<br />
I suspect volatility is similar. From much of what is written there seem to
be a fair few searching for crocks of gold, without a clear grasp of the
mechanics.
<br />
<br />
The closest I found to a coherent definition of volatility is standard
deviation. This is is a widely used statistical measure which is easy
enough to calculate. And while it may have applications in calculating the
prices of certain esoteric financial instruments, I am not sure of its direct
application to the construction of a trading strategy, or to the selection of
shares suitable for short term swing trading. To illustrate, I'll use my
favorite mathematical construct, the sine wave.<br />
<br />
The chart below shows a hypothetical price time graph for a hypothetical
company, ABC Co. The mean share price is $1.50, and the standard deviation is 71c.<br />
<div align="center">
<img border="0" height="430" src="http://i1101.photobucket.com/albums/g434/mcart117/ABCCo_zpsf617c41c.png" width="460" />
</div>
The chart below shows a hypothetical price time graph for a second
hypothetical company, XYZ Co. The mean price is also $1.50, and the standard deviation is
also 71c.<br />
<div align="center">
<img border="0" height="430" src="http://i1101.photobucket.com/albums/g434/mcart117/XYZCo_zpscb9a8192.png" width="464" /></div>
So the standard deviation is identical for both companies, and yet from a
common sense perspective most people would describe the share price of XYZ Co as
being much more volatile than that of ABC Co. So on that basis, standard
deviation, does not seem to represent a good estimate of volatility.<br />
<br />
And from a swing trading perspective the two companies are very different.
ABC Co offers a swing trader one buy-sell cycle and a chance to buy back at the
end of the period. XYC Co offers a swing trader three buy-sell cycles over
the same period, as well as a buy back opportunity at the end.<br />
<br />
Without pretending to be a professional mathematician, my gut feeling is that
there will be no simple mathematical formula to identify a share price pattern
conducive to profitable trading. Rather a more long hand approach will be
needed, setting trading parameters, and then tracking a share price over time to
generate hypothetical trading results.Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-51089046219290951982012-03-21T06:12:00.002-07:002012-03-21T06:28:07.235-07:00Windows 8 - my first impression<p>I was so excited about the first beta release of Vista that I built a computer specially to host it, and I liked enough to run it as my main OS for six months, although not quite enough to buy it. I installed Windows 7 on a spare HD sector of my main computer, but rarely used it. But I was so put off by the Microsoft propaganda with the release of Windows 8 "Customer preview" that I have installed it on a $200 used laptop from eBay.</p> <p>And my first impression is that it will remain there. In fact, as I looked the array of icons on the opening screen, I felt I had been time warped back to the early 1990's, and was looking at Windows 3 not Windows 8. I knew clothing fashions went round in circles, but I didn't realize the designers of computer operating systems were that fickle.</p> <p>Of course people will buy it, because it is built into the purchase of computers from shops. Will the corporate sector be bullied into adopting it? I guess if XP is no longer supported, they will have little choice.</p> <p>In my <a href="http://jhippjava.blogspot.com.au/2009/02/windows-7.html">first post</a> on Windows 7, I said I had never quite got a Linux distro to work properly. Since then I have Linux Mint working so well on another second hand laptop that my children are allowed to use nothing else. They can browse the web, play games, and watch recorded TV and movies. So if XP becomes unusable in the future, for want of drivers or whatever, my plan will be to use Linux as a main OS, and to retain a box with XP for Excel spreadsheets and Access databases. I couldn't manage without Excel, and for all its faults as a production database, I still like using Access as a scratch pad and phone book.</p> <p>As for Windows 8, I shall have to dedicate a few painful hours to navigating around it, because I know that in 12 months time, my customers will come pouring through the door wanting me to fix its gremlins. But I'm not looking forward to it. Maybe I shall have found something else to do before then. I shall pray for that.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-7427439490803489412011-12-07T07:43:00.000-08:002011-12-07T07:49:00.705-08:00HTML <div> tag revisitedI was abruptly forced to revisit this topic when I discovered that my <code><div></code> tag laid out login page, which seemed to look so great in Windows Internet Explorer (see below), looked absolutely crap in Firefox (see further below). <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeBIvYsD_ZbGqF7Mn9uA6OmBAueE6f6_T41ygC7LZ_0SOIBEOfSA_OTT8nM7GmK8WDYoXoUNZ01urBV7QhA6MBdH97hqUUvB6TxqDQ47qk4RIJGRisSVlhPgf1zRsFzH8vpA-JuejARZk/s1600/Fig1.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 280px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeBIvYsD_ZbGqF7Mn9uA6OmBAueE6f6_T41ygC7LZ_0SOIBEOfSA_OTT8nM7GmK8WDYoXoUNZ01urBV7QhA6MBdH97hqUUvB6TxqDQ47qk4RIJGRisSVlhPgf1zRsFzH8vpA-JuejARZk/s320/Fig1.png" alt="" id="BLOGGER_PHOTO_ID_5683413573927998450" border="0" /></a></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4EnjPIJKvGvrgqwI-j3rPAZq_MnMdh62hjX4M92VEoLOXE78oR0uKLjwwdRW-EIL8y6e7UDEF5U7keW_V5h_QA37q-q6_OmfPix5MBDzU1_v0lP1_-TmetK_KWVsq961ioWqPOcC9rxc/s1600/Fig2.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 235px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4EnjPIJKvGvrgqwI-j3rPAZq_MnMdh62hjX4M92VEoLOXE78oR0uKLjwwdRW-EIL8y6e7UDEF5U7keW_V5h_QA37q-q6_OmfPix5MBDzU1_v0lP1_-TmetK_KWVsq961ioWqPOcC9rxc/s320/Fig2.png" alt="" id="BLOGGER_PHOTO_ID_5683413575896978834" border="0" /></a></p> <p>So I did some reading, and the theme seemed to be that tables were never intended to do layout. Well I reckon there should be a counter argument, that the <code><div></code> tag was never intended to present data.</p> <p>It seems to me that much of the orthodoxy around HTML is written by graphic artists or publishers, and most of the web sites purported to show the power of <code><div></code> tags and CSS, are littered with graphic art and fancy fonts.</p> <p>For anyone used to programming, meshing <code><div></code> tags and CSS is not technically difficult, but perhaps it is not second nature to graphic artists and literary publishers. The instructions emphasize the importance of closing tags, and they suggest using borders during the design phase to get a visual aid on the layout of the divisions.</p> <p>So I tried that. I show below the HTML for the beginning of a login page:</p> <p><code><body><br /><div id="container"><br /><div id="pageHeader"><br /><h1><span>Rasch-ItemBank</span></h1><br /><h3><span>A <a class="top" href="http://www.interactived.com/softway.htm"><br />Softway</a> Open Source Project <br><br />Hosted by <a class="top" href="http://java.net/projects">Java.net</a></span></h3><br /></div><!-- end of "pageHeader" --><br /><div id="pageBody"><br /><h3><span><h3>Initial Login Screen</h3></span></h3><br /><div id="cellA1"><br /><p><span>Please select user or administrator</span></p><br /></div><!-- end of "cellA1" --><br /><div id="cellB1"><br /><p><span><select name="usertype" class=cbox><br /><option value="user">Student User</option><br /><option value="admin">Administrator</option><br /></select></span></p><br /></div><!-- end of "cellB1" --><br /></div><!-- end of "pageBody" --><br /></div><!-- end of "container" --><br /></body><br /></html></code></p> <p>And below is the CSS to go with it:</p> <p><code>#container {<br />padding: 0 25px 0 120px;<br />margin: 0;<br />position: relative;<br />border: 1px dotted red;<br />}<br />#pageHeader {<br />margin: 5px;<br />border: 1px dotted orange;<br />}<br />#pageBody {<br />margin: 5px;<br />border: 1px dotted green;<br />}<br />#cellA1 {<br />margin: 2px;<br />height: 35px;<br />float: left;<br />border: 1px dotted fuchsia;<br />}<br />#cellB1 {<br />margin: 2px;<br />height: 35px;<br />float: left;<br />border: 1px dotted fuchsia;<br />}</code></p> <p>I put little margins around each "division", and I made the borders different colors for clarity. Having rainbows on my mind, I followed a rainbow sequence: Richard of .. gave .. vain. I show below how it came out:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIrSYAxaPLuoNYA6P9mROfdb83R93kcn7hzDKxUHkkrheV-WJqjGjjSZMRU1w7nCa38aRi0-KC-_7G2Qhz_-Pq3-Xr1qmue-KHCyB3XC54NvqQ4qNfu5kr4M8jp44tsHI3ODGx998bNGA/s1600/Fig3.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 258px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIrSYAxaPLuoNYA6P9mROfdb83R93kcn7hzDKxUHkkrheV-WJqjGjjSZMRU1w7nCa38aRi0-KC-_7G2Qhz_-Pq3-Xr1qmue-KHCyB3XC54NvqQ4qNfu5kr4M8jp44tsHI3ODGx998bNGA/s320/Fig3.JPG" alt="" id="BLOGGER_PHOTO_ID_5683413577751063602" border="0" /></a></p> <p>Notice how the red border, which is supposed to embrace everything, stops short, and leaves off two divisions. And the green border, which was created to embrace the "table" and its heading, wraps itself around the heading only.</p> <p>After many hours of fiddling, I noticed that the "divisions" behave better if they contain background images, but it strikes me that padding out divisions with background images to make them behave predictably, is conceptually not far removed from padding out real tables with spacer gifs.</p> <p>So I shall put my login form, and all other forms back into tables. I may use CSS to format the tables, and I may use divisions in pages and areas of pages devoted to text and graphics. But my data and forms will be laid out in the traditional manner, using tables.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com1tag:blogger.com,1999:blog-8882010943472432760.post-83044566344505104132011-11-21T20:52:00.000-08:002011-11-21T21:22:37.717-08:00Bringing a Custom Swing Component to Life<p>I am sometimes down on the Java documentation, but in the sand plains of lugubrious and often confusing material there is the occasional gem. One example is a lesson from <a href="http://download.oracle.com/javase/tutorial/index.html">The Java Tutorial</a> entitled <a href="http://download.oracle.com/javase/tutorial/uiswing/painting/index.html"> Performing Custom Painting</a>. I was directed to it by a reply to <a href="https://forums.oracle.com/forums/thread.jspa?messageID=9980569#9980569"> this thread</a> in the <a href="https://forums.oracle.com/forums/category.jspa?categoryID=289">Oracle Java Desktop forum</a>.</p> <p>When I first began my efforts to create a rainbow colored Gaussian distribution curve I began with one of the <a href="http://download.oracle.com/javase/tutorial/index.html">Tutorial</a> lessons on colors. I have unfortunately lost the URL for the lesson but the code began something like this:</p> <p><code>import java.awt.Color;<br />import java.awt.Graphics;<br />import java.awt.Graphics2D;<br /><br />import javax.swing.JFrame;<br />import javax.swing.JPanel;<br /><br />public class Colors extends JPanel {<br /><br />public void paintComponent(Graphics g) {<br />super.paintComponent(g);<br /><br />Graphics2D g2d = (Graphics2D) g;<br /><br />g2d.setColor(new Color(255, 0, 0));//vivid red<br />g2d.fillRect(10, 15, 90, 60);</code></p> <p><code>...</code></p> <p><code>}<br /><br />public static void main(String[] args) {<br /><br />JFrame frame = new JFrame("Colors");<br />frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />frame.add(new Colors());<br />frame.setSize(360, 300);<br />frame.setLocationRelativeTo(null);<br />frame.setVisible(true);<br />}<br />}</code></p> <p>It looked as shown below.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Ejz85pW4vZqK6h4paaN_S32mmaNXORXbP6cSzUsT4UfQ8pK65sUrn2CrSzC08VbJaBnsmBUEqTSr2djCBaI2uicZdrDwIQ4aCCfSHKZY-mCCtw_yh-_RUCxHrxKYtCFy5spClso7qlQ/s1600/fig2.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 267px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Ejz85pW4vZqK6h4paaN_S32mmaNXORXbP6cSzUsT4UfQ8pK65sUrn2CrSzC08VbJaBnsmBUEqTSr2djCBaI2uicZdrDwIQ4aCCfSHKZY-mCCtw_yh-_RUCxHrxKYtCFy5spClso7qlQ/s320/fig2.JPG" alt="" id="BLOGGER_PHOTO_ID_5677679120219902642" border="0" /></a></p> <p>I modified this by putting the rectangles side by side and end on to produce a crude histogram as shown below:</p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1AA1Tp9EWEgmnXdurhxYTJ5c9xLStm1RnR_Y3YKMkh9kKYmTcVkU2FtTmyMcyn7sRJfaJ3AT802rkKMAj9wR9uliDX3vRsX_mor1dkAxGslCmrVnIRXzZUVDGsuqoEgqmtK4WxjMYBXk/s1600/fig3.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 150px; height: 120px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1AA1Tp9EWEgmnXdurhxYTJ5c9xLStm1RnR_Y3YKMkh9kKYmTcVkU2FtTmyMcyn7sRJfaJ3AT802rkKMAj9wR9uliDX3vRsX_mor1dkAxGslCmrVnIRXzZUVDGsuqoEgqmtK4WxjMYBXk/s320/fig3.JPG" alt="" id="BLOGGER_PHOTO_ID_5677679121953709154" border="0" /></a></p> <p> </p> <p>I reduced the width of the rectangles (to one pixel) and their number (to 800), and made their height and color the subject of mathematical functions. The colors were produced by three out of phase sine waves. That idea from that came from <a href="http://www.krazydad.com/makecolors.php">this</a> article by Jim Bumgardner. His explanation is very thorough, so I shall not repeat it here, but in recognition of the idea, my first rainbow colored curve was a sine wave, as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuAML8sfYWLQ5eOl0NrkC9xZCeUbCcX4WYMqOW76VpWk6PyS9kZKaqyy5S0nlGtrspXZB6aCF_YXKrGg773cExaLz1H75vdlbTmBhCuCxCp75UbA-Rv0OIB9cLXuy24zVa9eu-Sf9svis/s1600/sine.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 132px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuAML8sfYWLQ5eOl0NrkC9xZCeUbCcX4WYMqOW76VpWk6PyS9kZKaqyy5S0nlGtrspXZB6aCF_YXKrGg773cExaLz1H75vdlbTmBhCuCxCp75UbA-Rv0OIB9cLXuy24zVa9eu-Sf9svis/s320/sine.JPG" alt="" id="BLOGGER_PHOTO_ID_5677679129366414322" border="0" /></a></p> <p>The mathematical function for a sine wave in Java is really simple:</p> <p><code>y = Math.sin(x);</code></p> <p>There is, alas, no inbuilt function for a Normal/Gaussian distribution curve, but <a href="http://en.wikipedia.org/wiki/Normal_distribution">Wikipedia</a> gives the function as:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyxkdCfxRXy61XUbGDYGQ8tJPJNOq3wjjIuXk7w2in6Mn9Y2RTzvSnZlS2ffThAMpXORQdDyQz1f5vt3fvo-GHxtqBDjBKYPgAvOxKDvrhGzsj5qyUoeDF05ufXbRp4OdY949ZoBlqBQk/s1600/normdist.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 45px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyxkdCfxRXy61XUbGDYGQ8tJPJNOq3wjjIuXk7w2in6Mn9Y2RTzvSnZlS2ffThAMpXORQdDyQz1f5vt3fvo-GHxtqBDjBKYPgAvOxKDvrhGzsj5qyUoeDF05ufXbRp4OdY949ZoBlqBQk/s320/normdist.png" alt="" id="BLOGGER_PHOTO_ID_5677680351399457810" border="0" /></a></p> <p>I used the middle part of this expression to produce the rainbow colored Gaussian distribution curve shown at the bottom of my <a href="http://jhippjava.blogspot.com/2011/11/creating-custom-swing-component.html"> previous post</a>. But as I said there, it did nothing. I could not send messages to it or make it change.</p> <p>I will admit that when I first read the reply to <a href="https://forums.oracle.com/forums/thread.jspa?messageID=9980569#9980569"> my forum post</a> recommending the <a href="http://download.oracle.com/javase/tutorial/uiswing/painting/index.html"> Custom Painting</a> tutorial, I was not that optimistic, and I didn't look at it properly until after I had tried all the articles described in my <a href="http://jhippjava.blogspot.com/2011/11/creating-custom-swing-component.html"> previous blog post</a>. But my cynicism was misplaced, and I should have started there.</p> <p>The essential code construction from the <a href="http://download.oracle.com/javase/tutorial/uiswing/painting/index.html">tutorial</a> begins as follows:</p> <p><code>import javax.swing.SwingUtilities;<br />import javax.swing.JFrame;<br /><br />public class SwingPaintDemo1 {<br /><br />public static void main(String[] args) {<br />SwingUtilities.invokeLater(new Runnable() {<br />public void run() {<br />createAndShowGUI();<br />}<br />});<br />}<br /><br />private static void createAndShowGUI() {<br />System.out.println("Created GUI on EDT? "+<br />SwingUtilities.isEventDispatchThread());<br />JFrame f = new JFrame("Swing Paint Demo");<br />f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />f.setSize(250,250);<br />f.setVisible(true);<br />}</code></p> <p>And the first essential point to note is that it uses:</p> <p> <cite>The <code>SwingUtilities</code> helper class to construct this GUI on the Event Dispatch Thread.</cite> </p> <p>I don't fully understand this, but I've been told to do it before, and it was only when I used this structure for my "custom swing component" that I could get it to work properly.</p> <p>The second slightly strange thing that the <a href="http://download.oracle.com/javase/tutorial/uiswing/painting/index.html">tutorial</a> did was to create its own "custom" JPanel:</p> <p><code>class MyPanel extends JPanel {<br /><br />public MyPanel() {<br />setBorder(BorderFactory.createLineBorder(Color.black));<br />}<br /><br />public Dimension getPreferredSize() {<br />return new Dimension(250,200);<br />}<br /><br />public void paintComponent(Graphics g) {<br />super.paintComponent(g);<br /><br />// Draw Text<br />g.drawString("This is my custom Panel!",10,20);<br />}<br />}</code></p> <p>This was all in the same source file, which was modified by replacing:</p> <p><code>f.setSize(250,250);</code></p> <p>with</p> <p><code>f.add(new MyPanel());<br />f.pack();</code></p> <p>It looks trivial, but by following this structure, I was able to use the <code>.pack()</code> command in <a href="http://www.interactived.com/JMTalpha/JMTalpha.htm">my applet</a>. Using my original code construction (as shown above), the first time I inserted the new component, I thought it hadn't worked at all because it did not show, and it was only after adding padding to the gridbaglayout and manually resizing the <a href="http://www.interactived.com/JMTalpha/JMTalpha.htm">applet</a> that I could see it.</p> <p>Another point worth noting is the line which inherits functionality from the parent component. This is described in the <a href="http://download.oracle.com/javase/tutorial/uiswing/painting/index.html">tutorial</a> as follows:</p> <p> <cite>Most of the standard Swing components have their look and feel implemented by separate "UI Delegate" objects. The invocation of <code>super.paintComponent(g)</code> passes the graphics context off to the component's UI delegate, which paints the panel's background.</cite> </p> <p>This avoided me having to mimic the code structure of the standard swing components. I could focus on the code that made my component different.</p> <p>The third thing that the <a href="http://download.oracle.com/javase/tutorial/uiswing/painting/index.html">tutorial</a> did was to create a "sprite" and code to move it around. My "sprite" is my rainbow colored histogram, and I didn't need "event" code to drag it around the page. But I did need code to alter one or more of the parameters used to build the histogram. The code used by the <a href="http://download.oracle.com/javase/tutorial/uiswing/painting/index.html">tutorial</a> was:</p> <p><code>... previous imports<br />import java.awt.event.MouseEvent;<br />import java.awt.event.MouseListener;<br />import java.awt.event.MouseAdapter;<br />import java.awt.event.MouseMotionListener;<br />import java.awt.event.MouseMotionAdapter;<br /><br />... previous unchanged code<br /><br />public MyPanel() {<br /><br />setBorder(BorderFactory.createLineBorder(Color.black));<br /><br />addMouseListener(new MouseAdapter() {<br />public void mousePressed(MouseEvent e) {<br />moveSquare(e.getX(),e.getY());<br />}<br />});<br /><br />addMouseMotionListener(new MouseAdapter() {<br />public void mouseDragged(MouseEvent e) {<br />moveSquare(e.getX(),e.getY());<br />}<br />});<br /><br />}<br /><br />private void moveSquare(int x, int y) {<br />int OFFSET = 1;<br />if ((squareX!=x) || (squareY!=y)) {<br />repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);<br />squareX=x;<br />squareY=y;<br />repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);<br />}<br />}<br /><br /><br />public Dimension getPreferredSize() {<br />return new Dimension(250,200);<br />}<br /><br />protected void paintComponent(Graphics g) {<br />super.paintComponent(g);<br />g.drawString("This is my custom Panel!",10,20);<br />g.setColor(Color.RED);<br />g.fillRect(squareX,squareY,squareW,squareH);<br />g.setColor(Color.BLACK);<br />g.drawRect(squareX,squareY,squareW,squareH);<br />}<br />}</code></p> <p>The fourth slightly strange thing that the <a href="http://download.oracle.com/javase/tutorial/uiswing/painting/index.html">tutorial</a> did was to put the "sprite" is its own class:</p> <p><code>class RedSquare{<br /><br />private int xPos = 50;<br />private int yPos = 50;<br />private int width = 20;<br />private int height = 20;<br /><br />public void setX(int xPos){<br />this.xPos = xPos;<br />}<br /><br />public int getX(){<br />return xPos;<br />}<br /><br />... more set/get functions<br /><br />public void paintSquare(Graphics g){<br />g.setColor(Color.RED);<br />g.fillRect(xPos,yPos,width,height);<br />g.setColor(Color.BLACK);<br />g.drawRect(xPos,yPos,width,height);<br />}<br />}</code></p> <p>I'm not sure whether this was strictly necessary, but I followed the same structure, putting my histogram into the <code>paintSquare(Graphics g)</code> method, although I called it <code>rainbowHist(Graphics g).</code> I also renamed <code>MyPanel()</code> to <code>MyHist()</code>. The six set/get functions I replaced with two:</p> <p><code>public void setMaxValue(int MaxValue){<br />this.MaxValue = MaxValue;<br />}<br /><br />public void setActValue(int ActValue){<br />this.ActValue = ActValue;<br />}</code></p> <p>The <code>moveSquare(int x, int y)</code> function I made as follows:</p> <p><code>public void moveSquare(int MaxValue, int ActValue){<br />myHist.setMaxValue(MaxValue);<br />myHist.setActValue(ActValue);<br />repaint();<br />}</code></p> <p>I didn't need the mouse listeners, so I removed them altogether.</p> <p>Already my custom component was beginning to look a bit like a JProgressBar, with a <code>MaxValue</code> and an <code>ActValue</code>, and "progress" indicated by the relationship between the two. In my initial version I made the number of columns in the histogram a linear function of <code>ActValue</code> as a proportion of <code>MaxValue</code>, just like the colored bit in an ordinary JProgressBar.</p> <p>But I needed to revise this, because I wanted "progress" to be indicated by the <i>area</i> under the curve, not the distance along the <code>x</code> axis.</p> <p> <a href="http://en.wikipedia.org/wiki/Normal_distribution">Wikipedia</a> gives the area under the curve, or "<span id="Cumulative_distribution_function" class="mw-headline">Cumulative distribution function" as:</span></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhf7Ru_bW1ZbCO1nGO5BlwP_aQd_xmpcjdUopp0joru0HtQkhlIsdc3WUFU4SM7pRywnw2pCIS80VnwQd7uaKgQ-ligfWv52US6uHkZFiJz-QxwjcLoRhUpjbKUqQ-TRIB2f6DNBQ6wvyI/s1600/cumdist.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 30px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhf7Ru_bW1ZbCO1nGO5BlwP_aQd_xmpcjdUopp0joru0HtQkhlIsdc3WUFU4SM7pRywnw2pCIS80VnwQd7uaKgQ-ligfWv52US6uHkZFiJz-QxwjcLoRhUpjbKUqQ-TRIB2f6DNBQ6wvyI/s320/cumdist.png" alt="" id="BLOGGER_PHOTO_ID_5677680187719974722" border="0" /></a></p> <p>In this expression "erf" is an abbreviation for "error function", and I was interested to read that much of the work around and even the name of the function derives from measurement theory. Indeed, one of the approximation expressions is:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIit-ZSy5SaC7tsJqtMjgxwflGjCqzO1gXCFq9tkEHoArRmLRMskAzxUa3u7Hp-40Y1ZojsEgo742EnlOMneyYt_NzZaoK2blOrtkV-VDd6jcyE2Kmz9AnsycLL-GFBVVSqMP_IIqzmsM/s1600/erfapprox.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 35px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIit-ZSy5SaC7tsJqtMjgxwflGjCqzO1gXCFq9tkEHoArRmLRMskAzxUa3u7Hp-40Y1ZojsEgo742EnlOMneyYt_NzZaoK2blOrtkV-VDd6jcyE2Kmz9AnsycLL-GFBVVSqMP_IIqzmsM/s320/erfapprox.png" alt="" id="BLOGGER_PHOTO_ID_5677680191177647890" border="0" /></a></p> <p>And this could almost have been lifted straight from the <a href="http://jhippjava.blogspot.com/2009/04/georg-rasch.html">Rasch</a> book. I must say, I've never liked that expression (in fact it gives me the heebie jeebies), so I moved straight down to the <a title="Abramowitz and Stegun" href="http://www.blogger.com/wiki/Abramowitz_and_Stegun">Abramowitz and Stegun</a> approximations, and used the first, because I'm aiming for a visual impression here, and don't need seven decimal places of accuracy:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc69Mv5kvTQGSDFHnF1N-gQNDwJKHlAWlYaUrI8NqYzo692BP8RZ4wzu8tkyfIjiCEJRL9PgoYouMrl_8H0XFrihjLR7jlASy3eTjbF8bUBLgvb-kohczqOJ_Vy3gbw6DUa6q_QdlNy44/s1600/erfstegun.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 39px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc69Mv5kvTQGSDFHnF1N-gQNDwJKHlAWlYaUrI8NqYzo692BP8RZ4wzu8tkyfIjiCEJRL9PgoYouMrl_8H0XFrihjLR7jlASy3eTjbF8bUBLgvb-kohczqOJ_Vy3gbw6DUa6q_QdlNy44/s320/erfstegun.png" alt="" id="BLOGGER_PHOTO_ID_5677680190366150754" border="0" /></a></p><p>Because we are talking about probability here, the theoretical total area under the graph is 1. So while in the initial version, the critical parameter was number of columns:</p> <p><code>for (double i=0; i<ActNoofColumns; i++){</code></p> <p>I now set the histogram to build completely by default:</p> <p><code>for (double i=0; i<MaxNoofColumns; i++){</code></p> <p>and inserted a break to trigger when the area approximation equates to <code> ActValue</code> as a proportion of <code>MaxValue</code>:</p> <p><code>if (jonathan > ProportionofMax) break;</code></p> <p>I used the variable <code>jonathan</code>, because <a href="http://en.wikipedia.org/wiki/Error_function">Wikipedia</a> was a bit vague about the left hand portion of the curve when the mean is zero (and <code> x<0</code>). I guess the measurement theorists who did this work didn't care, because they were only interested in the extreme right hand end of the curve. <a href="http://en.wikipedia.org/wiki/Error_function">Wiki</a> suggested:</p> <p><code>erf(x)=-erf(-x)</code></p> <p>This is correct, but I missed the leading minus sign on the right hand side of the expression, so I did a bit of fiddling around. Anyway, it eventually worked. The illustration below shows my custom component under the JprogressBar it will replace (as well as the curve shown in full for an instance of the component not yet callibrated).</p> <code><code><code><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisOGwl4sYJl6EimMsWYTeLypwkYiKDoc17GiBUA-o0DWNnHqZurjJ1yp9ZM-kEGkR5EEsChTjNuj41YEbjOSey43sqK9-vVCRjw05iCXjPMmKi_IbRsOB6rovq23QFOeBd6SWRI9SyDXY/s1600/fig4.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 276px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisOGwl4sYJl6EimMsWYTeLypwkYiKDoc17GiBUA-o0DWNnHqZurjJ1yp9ZM-kEGkR5EEsChTjNuj41YEbjOSey43sqK9-vVCRjw05iCXjPMmKi_IbRsOB6rovq23QFOeBd6SWRI9SyDXY/s320/fig4.JPG" alt="" id="BLOGGER_PHOTO_ID_5677679125658481474" border="0" /></a></p> </code></code></code>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-65703458574360391272011-11-15T21:34:00.000-08:002011-11-15T21:45:23.340-08:00Creating a Custom Swing ComponentI always return to my blog when I'm stuck, and I'm stuck right now. <p>I want to create a custom Swing component. Specifically, I want something like a <code>JProgressBar</code>, with the following changes:</p> <ol><li>In place of a flat Foreground color, I want a rainbow spectrum, showing only the red range for low Values, and the whole spectrum for values close to the Maximum value;</li><li>Instead of a rectangular box, I want the progress "bar" to take the shape of a normal, or Gaussian, distribution curve;</li><li>I want progress to be displayed by the area under the curve, rather than by a simple linear scale along the x axis.</li></ol> <p>It's not that there isn't stuff out there. I have five tabs open in my browser, specifically addressing the creation of custom components in Swing, as well as the <a href="http://hg.openjdk.java.net/jdk7/jsn/jdk/file/664def01b886/src/share/classes/javax/swing/JProgressBar.java"> source code for the JProgressBar</a>. It is that, like everything to do with Java, it is bloody difficult to read. </p> <p>I shall begin from the horse's mouth as it were, with an article on the <a href="http://www.java.net/">Java.net</a> website entitled: <a href="http://today.java.net/pub/a/today/2007/02/22/how-to-write-custom-swing-component.html"> How to Write a Custom Swing Component</a>. It begins by defining the "building blocks" of Swing components as:</p> <cite><ul><li>The component class itself, which provides an API for creating, changing, and querying the component basic state.</li><li>The model interface and the model default implementation(s) that handle the component business logic and change notifications.</li><li>The UI delegate that handles component layout, event handling (mouse and keyboard), and painting.</li></ul></cite> <p>I understand the first four words of that lot. I hate it when documents, especially formal ones, use abbreviations without definitions, but a Google search on API produces a first page full of formal Sun/Oracle documents, which do that, even in the title.<br /></p><p>According to an archived (by which I mean so old or unimportant that Oracle has not woven itself into the URL) <a href="http://java.sun.com/docs/glossary.html">glossary</a>, API is defined as:</p> <p><cite>Application Programming Interface. The specification of how a programmer writing an application accesses the behavior and state of classes and objects.</cite></p> <p>So if you insert the full definition into the first bullet, you get:</p> <ul><cite> <li>The component class itself, which provides a specification of how a programmer writing an application accesses the behavior and state of classes and objects for creating, changing, and querying the component basic state.</li></cite></ul> <p>And that is gibberish, like so much of the material used to describe Java, and the closer you get to "the horse" often the more confusing it gets. To be fair, if you insert the words behind the acronym, it looks a little better:</p> <ul><cite> <li>The component class itself, which provides an Application Programming Interface for creating, changing, and querying the component basic state.</li></cite></ul> <p>But then it starts to overlap with the second "building block", which begins:</p> <p> <cite>The model interface ... </cite> </p> <p>When I first read that, I wasn't sure whether it said model or modal. Either way it is not clear how the <cite>model interface</cite> differs from the <cite>Application Programming Interface</cite>.<br /></p> <p>The third "building block" opens with:</p><p><cite>The UI delegate ...</cite></p><p>I used the same <a href="http://java.sun.com/docs/glossary.html">glossary</a> to look up UI, and it wasn't even in there. A Google search on UI brings up a slew of pages on GUI, and the weight of evidence suggests "User Interface". So now we have <cite>Application Programming Interface</cite>, <cite>model interface</cite>, and a <cite>User Interface</cite>, each purportedly in their own "building block".</p><p>Are we really dealing with distinct building "building blocks" here, or a "blob" of amorphous building material with fuzzily defined functionality zones?</p> <p>The next title in the article, after <cite>Basic Building Blocks</cite>, is <cite>The Component Class: UI Delegate Plumbing</cite>, which looks to me very like a composite of building blocks 1 and 3. The third heading is <cite>The Model Interface</cite>, so presumably it refers to the second building block. It includes some code, with two class declarations, and it opens with:</p> <p><cite>This (sic) is ... the most important class for a custom component.</cite></p> <p>The article continues, on and on, in a similarly confusing fashion, so I thought I'd cut to the chase and have a look at the <a href="http://today.java.net/today/2007/02/22/flexi-slider-src.zip">source code</a> and see if I could make it work. The code for the main class <code>JFlexiSlider.java</code>, begins with:</p> <p><code>package org.jvnet.flamingo.slider;</code><br /><br /><code>import javax.swing.*;<br /><br />import org.jvnet.flamingo.slider.FlexiRangeModel.Range;<br />import org.jvnet.flamingo.slider.ui.BasicFlexiSliderUI;<br />import org.jvnet.flamingo.slider.ui.FlexiSliderUI;</code></p> <p>Three questions arise from this. Is the web address given for the imported classes in the public domain? Are the classes listed still there? And if so, is Java smart enough to navigate through the Internet to find them? When I tried to compile the class. The first of 18 errors was:</p> <p><code>package org.jvnet.flamingo.slider.FlexiRangeModel does not exist</code></p> <p>Out of curiosity I typed <code>jvnet.org</code> into my browser and it came up blank. I ran a <code>whois</code> on <code>jvnet.org</code>, and this confirmed that the domain name is registered, and to Oracle. So I guess that when this code was written, all the package and import information was meaningful, but now it certainly isn't. And to cut a long story short, the effort of addressing each error in turn to make the code run outweighed any possible benefit, so I gave up.</p> <p>My next port of call was to the <a href="http://hg.openjdk.java.net/jdk7/jsn/jdk/file/664def01b886/src/share/classes/javax/swing/JProgressBar.java"> source code</a> of the existing JProgressBar. One of eleven imported classes was:</p> <p><code>import javax.swing.plaf.ProgressBarUI;</code></p> <p>So I checked out the <a href="http://hg.openjdk.java.net/jdk7/jsn/jdk/file/664def01b886/src/share/classes/javax/swing/plaf/ProgressBarUI.java"> source code</a> for this, which was:</p> <p><code>public abstract class ProgressBarUI extends ComponentUI {<br />}</code></p> <p>To do a proper job I should have downloaded the <a href="http://hg.openjdk.java.net/jdk7/jsn/jdk/file/664def01b886/src/share/classes/javax/swing/plaf/ComponentUI.java"> source code</a> for <code>ComponentUI</code> as well, but to honest, the whole thing was rendered virtually unreadable by all the comments, so I reached another boredom threshold.</p> <p>I then went to a much more readable article entitled <a href="http://chp.smartlog.dk/creating-a-custom-component-in-swing-post24028"> Creating a custom component in Swing</a> by a Danish gentleman called Christian Petersen. As my Rasch Itembank Project is inspired by the Danish Mathematician, Georg Rasch, I was happy to be reading something by one of his countrymen.</p> <p>There were no remote or unreachable packages in the code given with this article (in fact there were no packages at all), and the code compiled and ran perfectly first time. Inspired by this success, and the simplicity of his approach, I went right back to basics, to a lesson in <a href="http://download.oracle.com/javase/tutorial/index.html">The Java Tutorial</a> entitled <a href="http://download.oracle.com/javase/tutorial/uiswing/start/compile.html"> Compiling and Running Swing Programs</a>. This lesson gives a link to <a href="http://download.oracle.com/javase/tutorial/uiswing/examples/start/HelloWorldSwingProject/src/start/HelloWorldSwing.java"> source code</a> for a "program" called HelloWorldSwing.</p> <p>HelloWorldSwing essentially displays a Swing component called JLabel, in another component called JFrame. I took this code and replaced the JLabel with the class for my rainbow colored Gaussian curve as follows:</p> <p><code>import javax.swing.*;<br />public class HelloWorldSwing {<br />private static void createAndShowGUI() {<br />//Create and set up the window.<br />JFrame frame = new JFrame("HelloWorldSwing");<br />frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />//Add the ubiquitous "Hello World" label.<br />NormJ2 label2 = new NormJ2();<br />frame.getContentPane().add(label2);<br />//Display the window.<br />frame.setSize(520, 300);<br />frame.setVisible(true);<br />}<br />public static void main(String[] args) {<br />//Schedule a job for the event-dispatching thread:<br />//creating and showing this application's GUI.<br />javax.swing.SwingUtilities.invokeLater(new Runnable() {<br />public void run() {<br />createAndShowGUI();<br />}<br />});<br />}</code><br />}</p> <p>And it came up as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc76dfxwlfEeTZiKx6Ru2MECGgbgp9tEX7mc3d1Xd2W-2zmthhyGX5toXxmENR4Qnq2xb2ayJIah_n_9MZuZUTxhsvG1Sy-E6_Ekbre3tpjh_QmnQpzmbTcwoTvqozWw3-QvWdlwE7H9c/s1600/fig1.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 185px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc76dfxwlfEeTZiKx6Ru2MECGgbgp9tEX7mc3d1Xd2W-2zmthhyGX5toXxmENR4Qnq2xb2ayJIah_n_9MZuZUTxhsvG1Sy-E6_Ekbre3tpjh_QmnQpzmbTcwoTvqozWw3-QvWdlwE7H9c/s320/fig1.JPG" alt="" id="BLOGGER_PHOTO_ID_5675465551328984306" border="0" /></a></p> <p>I've left all the comments and the HelloWorldSwing heading (and even the component name: <code>label2</code>) to emphasize that creating a custom swing component is really as simple as that. You don't need packages, collections of remote and difficult to find "ui" classes. You just insert one class, compiled with Swing components, into another.</p> <p>As components go, mine is currently somewhat limited. It looks pretty (though I say it myself), but it does nothing else. The purpose of all the guff at the head of this post is to bring components alive, but there has to be a simpler, more commonsense, way to do it.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com10tag:blogger.com,1999:blog-8882010943472432760.post-82577049848752512862011-11-12T04:10:00.000-08:002011-11-12T04:14:44.345-08:00Mixing and Matching<p>My unfamiliarity with PHP and JavaScript is illustrated by the fact that it has only just occurred to me that I don't have to choose between one or the other, but can in fact enjoy both. So for example, bringing my <a href="http://jhippjava.blogspot.com/2011/10/add-user-to-database.html">Add User</a> screen into the PHP fold was simply a matter of changing the file extension and adding:</p> <p><code>session_start();</code></p> <p>at the top of the file. Everything else remained the same. All the JavaScript remained untouched, all the business rules remained the same, and if the business rules were satisfied, the same PHP file was called to run the data transaction. For display purposes the username was called, and usertype was called to ensure only administrators added to the database.<br /></p> <p>I had also been scratching my head about passing PHP variables back to the Applet to enrich the data stored in my database, but then it finally sunk into my head that they didn't need to be passed backwards and forwards. Variables (such as username, and IP) gathered by PHP, could simply be stored as session variables, while the user navigated from the login page to the Applet, and when the Applet called a PHP script, those same variables could be called on the page hosting the PHP script. They could then be woven into enhanced SQL commands on that page, without ever having been near the Applet itself.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-84673360318467599352011-10-29T20:56:00.001-07:002011-10-29T20:56:33.835-07:00Security Points<p>The first point, about the security of <a href="http://www.interactived.com/softway.htm">my web site</a>, is that <a href="http://www.interactived.com/JMTalpha/JMTalpha.htm">Active Math Java</a> is a test bed for code developed for the <a href="http://rasch-itembank.blogspot.com/">Rasch-ItemBank</a> open source <a href="http://java.net/projects/rasch-itembank/">project</a>. It is intended as a free resource for use by any child anywhere in the world with access to a computer connected to the Internet and running Java.</p> <p>So the purpose of <a href="http://jhippjava.blogspot.com/2011/10/creating-login-page-front-end.html"> my login page</a> is not to secure a web resource for which users pay money. Nor is it like a forum, where the login page protects the forum from spammers. It is simply there for the convenience of certain users who have requested the ability to track the performance of their children.</p> <p>The second point, about the security of web sites in general, is that secure pages usually include a server side script, such as PHP, and if security is desired, all the pages have to be in the same or compatible format.</p> <p>Using PHP has some advantages, besides security, such as retaining variables across pages, within sessions.</p> <p>I have enjoyed writing business rules in JavaScript, for a <a href="http://jhippjava.blogspot.com/2011/10/javascript-business-rules.html"> mock login page</a> and a <a href="http://jhippjava.blogspot.com/2011/10/add-user-to-database.html">mock add user page</a>, because I have never liked JavaScript, and I enjoyed getting something to work with it. However, I am now resigned to rewriting everything in PHP, not for security, but for the convenience of retaining and passing variables about the place.</p> <p>Oh boy am I glad this is a blog about learning Java and related languages and not a formal lesson. If it were a formal lesson, any readers might be really pissed off by now, because I have done about 3 180 degree turns.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-11161770638470087582011-10-28T23:03:00.000-07:002011-10-28T23:13:03.411-07:00Add User to DatabaseHaving created <a href="http://jhippjava.blogspot.com/2011/10/web-site-redesign.html">an HTML layout</a> and an external CSS page, and having written <a href="http://jhippjava.blogspot.com/2011/10/javascript-business-rules.html"> business rules</a> for a login page, creating a page with a form to add users to the database was relatively easy. <p>The layout was almost identical to the login screen, except for what I call combo boxes for the age of the student users, and to comply with convention, a password confirmation field. But for that convention, the business rules could have been cut and pasted verbatim from the login page, and that would have made the job nice and easy.</p> <p>Identification of users is not mission critical for me, and if teachers can't record and type in accurately a password on the first attempt, my first instinct was to say "who cares?". But part of the point of this exercise is to make my web site/application look "professional", so I put in the second field.</p> <p>The login rules comprised four independent conditions nested within a super condition, triggered by any of the four being met, the alternative (or else) to which was the calling of the database query code. So where to put the fifth condition, the inequality of the passwords?</p> <p>The nest of four are together because they are not mutually exclusive. Most often the user will click the button with nothing in either field, and you want a message to appear over both fields. Or the name might be too long, and the password field empty.</p> <p>Technically the fifth condition might overlap with one or more of the other four. For example the password fields may be unequal and too long. But if they are too long, and they are told to make them equal first, they will be annoyed if they are told to shorten them after they have made them equal. I guess if I had enough space for messages I could tell them both, but I don't. So in my business rules they have to get the length right (between 1 and eight characters) first, and then make the passwords match. The rules are as follows:</p> <p><code>function busrules(form)<br />{<br />var subtype = form.usertype.value;<br />var subname = form.username.value;<br />var subpass = form.password.value;<br />var subpassc = form.passwordc.value;<br />var subagey = form.ageyears.value;<br />var subagem = form.agemonths.value;<br />var showmessn;<br />var showmessp;<br />var ubercell1v = document.getElementById("ubercell1").innerHTML;<br />var ubercell2v = document.getElementById("ubercell2").innerHTML;<br />var myarg;<br />if (ubercell1v.length > 0)<br />{<br />document.getElementById("ubercell1").innerHTML="";<br />} //end of null check<br />if (ubercell2v.length > 0)<br />{<br />document.getElementById("ubercell2").innerHTML="";<br />} //end of null check<br />if (subname.length > 8 || subname.length ==0 || subpass.length ==0 || subpass.length ==0 )<br />{<br />if (subname.length > 8)<br />{<br />showmessn = "Your user name is too long. Please use 8 characters.";<br />document.getElementById("ubercell1").innerHTML=showmessn;<br />} //end of condition 1<br />if (subname.length ==0)<br />{<br />showmessn = "Oh Dear! You have not entered a user name.";<br />document.getElementById("ubercell1").innerHTML=showmessn;<br />} //end of condition 2<br />if (subpass.length > 8)<br />{<br />showmessp = "Your user password is too long. Please use 8 characters.";<br />document.getElementById("ubercell2").innerHTML=showmessp;<br />} //end of condition 3<br />if (subpass.length ==0)<br />{<br />showmessp = "Oh Dear! You have not entered a user password.";<br />document.getElementById("ubercell2").innerHTML=showmessp;<br />} //end of condition 4<br />} //end of group of 4 conditions<br />else if (subpass != subpassc)<br />{<br />showmessp = "Oh Dear! You need to enter the same password in both password fields.";<br />document.getElementById("ubercell2").innerHTML=showmessp;<br />} //end of condition 5</code></p> <p>Then if all those rules are satisfied, the PHP script for the data connection is called:</p> <p><code>else { //Code below is to set up parameters for the php script<br />if (window.XMLHttpRequest) //format and create request variable according to browser type<br />{// code for IE7+, Firefox, Chrome, Opera, Safari<br />xmlhttp=new XMLHttpRequest();<br />} //end of current option<br />else<br />{// code for IE6, IE5<br />xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");<br />} // end of old option<br />xmlhttp.onreadystatechange=function()<br />{ // this code displays response text<br />if (xmlhttp.readyState==4 && xmlhttp.status==200)<br />{<br />document.getElementById("untencell1").innerHTML=xmlhttp.responseText;<br />}<br />} //the code below calls the php script on the server<br />myarg = "('"+subname+"','"+subpass+"','"+subtype+"',"+subagey+","+subagem+")"<br />xmlhttp.open("POST","adduser.php?myarg="+myarg,true);<br />xmlhttp.send();<br />} //end of master conditional statement<br />} //end of function</code></p> <p>I took the opportunity to tidy up the layout a bit. The "row" divisions I had set up (following the structure of a table) seemed a bit redundant, so I lost them, and I defined the warning divisions more concisely, to stop the form jumping about, when the warnings come up. And I made everything a bit wider:</p> <p><code>.inputtable {margin:50; background-color:#BDEDFF}<br />.row {width:520;}<br />.col1 {text-align:right; float:left; width:300; height:25; margin:0 5 0 5;}<br />.col2 {text-align:left; float:right; width:200; margin:0 5 0 5;}<br />.itext {width:150;}<br />.cbox {width:150; margin-left:5;}<br />.warning {color="red";margin-bottom:0;margin-top:0;float:left; width:520; }</code><br /><br />The PHP script was similar in structure to the login script, but differed in important details (such as running an INSERT command rather than a SELECT query):</p> <p><code><?php<br />include('newinfo.php');// collect database variables.<br />$myarg = $_GET['myarg']; // collect passed variable<br />// To protect MySQL injection<br />$myarg = stripslashes($myarg);<br />// Connect to server and select database.<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />$query = "INSERT INTO $table1 (Softid, PartPass, PartType, AgeYears, AgeMonths) VALUES ";<br />$query = $query . $myarg;<br />$result = mysql_query($query) or die(mysql_error() . $query );<br />if($result==1){<br />echo"<p>Hooray you have added a user</p>";<br />} else {<br />echo"<p>Oh Dear! Something went wrong. Query: <br/>$query </p>";<br />}<br />mysql_close($con);<br />?></code></p> <p>If the password were unequal, but everything else correct, the screen looked as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLv92mW6Ab3CIwZHHJC_6UQbRBNLbQOT6DvTnqBU81rNbdfhec1uI_UIFpTvTwqj0T7AIywbsj4BH-rHcB8SLLf5khXZ_ozM6GiBhuZjWdqXYuaYkiSZbH-oFMT83cQp8zLCQUCwOnUxE/s1600/pic06.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 302px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLv92mW6Ab3CIwZHHJC_6UQbRBNLbQOT6DvTnqBU81rNbdfhec1uI_UIFpTvTwqj0T7AIywbsj4BH-rHcB8SLLf5khXZ_ozM6GiBhuZjWdqXYuaYkiSZbH-oFMT83cQp8zLCQUCwOnUxE/s320/pic06.JPG" alt="" id="BLOGGER_PHOTO_ID_5668791593579321522" border="0" /></a></p> <p>And after successfully adding a user is looked as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgWWy68UUAvICxYi9ow3YoJ3BipHX7v-caX1Js0hMBa5nTSz4ROfV3XOQ9gHKAxdXD71n2I8-8i4jryxuPNvtwIJnQE5AXIJoJOaSrpGfje6pu26AWuWmFtRuUueiKA89S7f5NQrtg1CA/s1600/pic05b.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 302px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgWWy68UUAvICxYi9ow3YoJ3BipHX7v-caX1Js0hMBa5nTSz4ROfV3XOQ9gHKAxdXD71n2I8-8i4jryxuPNvtwIJnQE5AXIJoJOaSrpGfje6pu26AWuWmFtRuUueiKA89S7f5NQrtg1CA/s320/pic05b.JPG" alt="" id="BLOGGER_PHOTO_ID_5668791597736034914" border="0" /></a></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-62716978731583531792011-10-26T04:22:00.000-07:002011-10-26T04:26:31.650-07:00Check Login Details against the DatabaseAfter <a href="http://jhippjava.blogspot.com/2011/10/javascript-business-rules.html"> rewriting my business rules in JavaScript</a>, the time now really had come to create the live database interface. So I busily changed the file extension back to .php and added back the <code>include()</code> statement, and started adding PHP code to the JavaScript function called by the button click event, and paused when I needed to pass a javascript variable to PHP. I had a feeling that what I was doing would not work, and a quick Google search confirmed that it would not. <p>The whole point of converting my business rules to JavaScript was to keep the field input checking local. But as PHP scripts run on the server, you need to call something on the server, and pass any variables to that.</p> <p>It was a bit frustrating because neither of the login page examples I'd found on the web used any business rules at all; they just called a PHP script from the form submit button, one on the same page, one on another.</p> <p>As a first pass I tried AJAX.</p> <p>I had sidestepped the issue in my <a href="http://jhippjava.blogspot.com/2011/10/javascript-business-rules.html"> business rules test page</a> with the line:</p> <p> <code>alert ("Well Done. Your username and password were correctly entered.");</code> </p> <p>I now replaced this with:</p> <p><code>if (window.XMLHttpRequest) //format and create request variable according to browser type<br />{// code for IE7+, Firefox, Chrome, Opera, Safari<br />xmlhttp=new XMLHttpRequest();<br />} //end of current option<br />else<br />{// code for IE6, IE5<br />xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");<br />} // end of old option<br />xmlhttp.onreadystatechange=function()<br />{ // this code displays response text<br />if (xmlhttp.readyState==4 && xmlhttp.status==200)<br />{<br />document.getElementById("untencell1").innerHTML=xmlhttp.responseText;<br />}<br />} //the code below calls the php script on the server<br />xmlhttp.open("POST","logincheck.php?id="+subname+"&pw="+subpass,true);<br />xmlhttp.send();</code></p> <p>I also added one more division to receive a message back from the PHP script:</p> <p><code><div id=untencell1></div></code></p> <p>This cell was placed under the button but within the form division. The PHP script was:</p> <p><code><?php<br />include('newinfo.php');// collect database variables.<br />$id = $_GET['id']; // collect passed variable 1<br />$pw = $_GET['pw']; // collect passed variable 2<br />// To protect MySQL injection<br />$id = stripslashes($id);<br />$pw = stripslashes($pw);<br />// $id = mysql_real_escape_string($id);<br />// $pw = mysql_real_escape_string($pw);<br /><br />// Connect to server and select databse.<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />$query = "SELECT Softid, PartPass FROM $table1 WHERE Softid = '$id' and PartPass = '$pw'";<br />$result = mysql_query($query) or die(mysql_error() . $query );<br />// Mysql_num_row is counting table row<br />$count=mysql_num_rows($result);<br />if($count==1){<br />echo"<p>Hooray you are logged in</p>";<br />} else {<br />echo"<p>Oh Dear! Something went wrong. Query: <br/>$query </p>";<br />}<br />mysql_close($con);<br />?></code></p> <p>A couple of things still need fixing. First the user is not taken anywhere useful after logging in successfully. That is because there is currently nowhere to go. The second is that the diagnostic display of the query on login failure needs removing, after everything is definitely working.</p> <p>After a successful login, the page currently looks as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ4gL0x54Kt3E-BR9g8-Vc23MoyTBut2HA5OW_uNrtX6XdHvfySDWf9ACC7cljOwaXFudgXP7WQwYsgs1wxfx0MAJULWWn9ah1DEBAbU-eoH0k-BA6kzGmafXmgGAh9qi2alKnmVL2wNY/s1600/pic04.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 316px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ4gL0x54Kt3E-BR9g8-Vc23MoyTBut2HA5OW_uNrtX6XdHvfySDWf9ACC7cljOwaXFudgXP7WQwYsgs1wxfx0MAJULWWn9ah1DEBAbU-eoH0k-BA6kzGmafXmgGAh9qi2alKnmVL2wNY/s320/pic04.JPG" alt="" id="BLOGGER_PHOTO_ID_5667760640427733682" border="0" /></a></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com1tag:blogger.com,1999:blog-8882010943472432760.post-50602303136721532342011-10-25T09:05:00.001-07:002011-10-25T09:11:11.956-07:00JavaScript Business Rules<p>In my last two entries, I created the <a href="http://jhippjava.blogspot.com/2011/10/creating-login-page-front-end.html"> front end interface</a> for a login screen, and wrote a couple of simple <a href="http://jhippjava.blogspot.com/2011/10/business-rules.html">business rules</a> in a PHP script to ensure both username and password fields are filled before running a query on the database. The time has now come to write the query and check it against the field entries.</p> <p>Reading tutorials on the topic, I am first fascinated by the level of paranoia and then I become paranoid myself. So instead of getting on with writing a query, I add another business rule prohibiting usernames or passwords over eight characters. Eight is the length of the fields in the database, so it is as silly for users to enter 9 characters as no characters, so I might as well stop them doing it. It won't stop every SQL injection exploit, but it will preclude them from attempting to write essays.</p> <p>I'm looking at a couple of tutorials for inspiration. They both use different SQL injection protection code. One uses the <code>ereg()</code> function, which is apparently being phased out, so I won't use that. The other takes the user to another page on login, which won't work with my business rules code.</p> <p>I have to say I am not sure why I wrote the business rules into a PHP script. If I used Java Script for the business rules, I could take the user to a new page on successful login, and I could completely avoid unnecessary calls on the server itself, as well as on the database. But it will require a complete rethink.</p> <p>To start fiddling, I change the login page back to an HTML file and remove all PHP. I then replace the PHP scripted error messages with division placed in the same place. The first is as follows:</p> <p><code><div id=ubercell1 class=warning></div><br/></code></p> <p>In the CSS file the class <code>warning</code> takes the color red. I then reduce the form tag down from:</p> <p><code><form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"></code></p> <p>to:</p> <p><code><form></code></p> <p>And the button is changed from:</p> <p><code><input type="submit" name="login" value="Log in to Portal" class=itext /></code></p> <p>to:</p> <p><code><input type="button" value="Log in to Portal" class=itext onclick="busrules(this.form)" /></code></p> <p>And of course the PHP code is replaced by the JavaScript function <code>busrules(form)</code>. I spent some time fiddling with the JavaScript, because I don't know it very well. The essential logic is that any one or more of four possible errors will generate a warning and preclude the call to the database. When an error is corrected the warning message must be cleared, but where there is no warning (i.e. if the user gets it right first time) nothing needs to happen. And in this test page, if everything is OK, an alert message says everything is OK.</p> <p>The rest of the page code remained the same, and the page looked the same, but without needing a call back to the server, the error messages came up a lot quicker than they did using PHP. The full JavaScript was:</p> <p><code><script type="text/javascript"><br />function busrules(form)<br />{<br />var subname = form.username.value;<br />var subpass = form.password.value;<br />var showmessn;<br />var showmessp;<br />var ubercell1v = document.getElementById("ubercell1").innerHTML;<br />var ubercell2v = document.getElementById("ubercell2").innerHTML;<br />if (ubercell1v.length > 0)<br />{<br />document.getElementById("ubercell1").innerHTML="";<br />} //end of null check<br />if (ubercell2v.length > 0)<br />{<br />document.getElementById("ubercell2").innerHTML="";<br />} //end of null check<br />if (subname.length > 8 || subname.length ==0 || subpass.length ==0 || subpass.length ==0)<br />{<br />if (subname.length > 8)<br />{<br />showmessn = "Your user name is too long. Please use 8 characters.";<br />document.getElementById("ubercell1").innerHTML=showmessn;<br />} //end of condition 1<br />if (subname.length ==0)<br />{<br />showmessn = "Oh Dear! You have not entered your user name.";<br />document.getElementById("ubercell1").innerHTML=showmessn;<br />} //end of condition 2<br />if (subpass.length > 8)<br />{<br />showmessp = "Your user password is too long. Please use 8 characters.";<br />document.getElementById("ubercell2").innerHTML=showmessp;<br />} //end of condition 3<br />if (subpass.length ==0)<br />{<br />showmessp = "Oh Dear! You have not entered your user password.";<br />document.getElementById("ubercell2").innerHTML=showmessp;<br />} //end of condition 4<br />} else {<br />alert ("Well Done. Your username and password were correctly entered.");<br />} //end of master conditional statement<br />} //end of function<br /></script></code></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-53776991245992869492011-10-23T02:02:00.000-07:002011-10-25T08:41:39.155-07:00PHP Business Rules<p>The purpose of the business rules layer is to prevent gibberish being written to a database. If you have a field designated to record currency values, you don't want someone posting a long letter to their mother to it. Of course if you try to write text to a numeric field the database itself will probably reject it, but doing so wastes server resources and risks corrupting the database.</p><p>And in an age of web applications, where servers and clients are separated by long distance and heavy traffic, sending redundant requests to the server wastes time and annoys the user.</p> <p>There are two aspects to the business rules layer:</p> <ol><li>The coded rules;</li><li>The front end manifestation when one or more of the conditions set out in the rules is not met.</li></ol> <p>In the olden days, if you tried to make an illegal entry into a database field, a new window or dialog box opened up with a rude message, and sometimes the computer would beep at you. The dialog box would then have to be closed manually by the user before they could continue with their work. </p> <p>Nowadays a more subtle approach is preferred. Usually a message is written on to the data entry form itself, just above or close to the field with the inappropriate or missing entry.</p> <p>In the case of a login screen, nothing is being written to the database, and a null field is conceptually similar to an incorrect entry, so some applications skip business rules in the login screen and send null fields for checking against the database along with everything else.</p> <p>My server is particularly slow, and I am always aware of the implicit cost of making unnecessary calls on the database, so I shall write a couple of lines to ensure users at least put something in both username and password fields.</p> <p>The login screen shown in my <a href="http://jhippjava.blogspot.com/2011/10/creating-login-page-front-end.html"> previous post</a> was written in HTML and tested at home. I shall now have to migrate across to PHP and as I don't have PHP installed at home, I shall have to work on my web host server.</p> <p>The PHP script will open with the <code>include()</code> statement and a variable declaration for the error condition:</p> <p><code>include('dbinfo.php'); // get database information<br />$error = false; //boolean used to contain error condition</code></p> <p>It will continue with the equivalent of event code for the button click event. In this case there is no need to register an actual event, because the login button is calling the containing page:</p> <p><code><form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"></code></p> <p>The code for the whole page is rerun when the button is clicked, so there is no need to register the event as such, but rather the condition of <i>having been clicked</i>:</p> <p><code>if (isset($_POST['login'])) {<br />// variables filled with form inputs<br />$usertype = $_POST['usertype'];<br />$username = $_POST['username'];<br />$password = $_POST['password'];<br />// check that neither field is empty<br />if ( !empty($firstname) && !empty($lastname) ) {<br />//run crunchy code<br />} else {<br />$error = true; // error condition met<br />} // end of empty field check<br />} // end of buttonclicked conditional code</code></p> <p>The "crunchy code" will be discussed later. For now, I need to insert a couple of extra lines into the page to use the $error variable. The first insert goes at the top of the <code><div></code> I called <code>row2</code>, which holds the username field:</p> <p><code><?php<br />if ( $error && empty($username) ) {<br />echo '<span style="gt;Oh Dear! You did not enter your name.</span><br>',"\n";<br />}<br />?></code></p> <p>The second insert goes at the top of the <code><div></code> I called <code>row3</code>, which holds the password field:</p> <p><code><?php<br />if ( $error && empty($password) ) {<br />echo '<span style="gt;Oh Dear! You did not enter your password.</span><br>',"\n";<br />}<br />?></code></p> <p>I have to admit that this is easier using the <code><div></code> tag than it would have been using a table. A table would have required a new row, and a cell spanning two column widths for each insert. Using the <code><div></code> tag, I just squashed the new code inside the containing division and above the two floating "cells".</p> <p>The code for the whole page has now become:</p> <p><code><?php<br />include('dbinfo.php'); // get database information<br />$error = false; //boolean used to contain error condition<br />/**<br />* The code below is ignored when the page loads<br />* but is run on reload after button click.<br />*/<br />if (isset($_POST['login'])) {<br />// variables filled with form inputs<br />$usertype = $_POST['usertype'];<br />$username = $_POST['username'];<br />$password = $_POST['password'];<br />// check that neither field is empty<br />if ( !empty($firstname) && !empty($lastname) ) {<br />//run crunchy code<br />} else {<br />$error = true; // error condition met<br />} // end of input check<br />} // end of buttonclicked conditional code<br />?><br /><br /><html><br /><head><br /><title>Active Math Java Private Portal</title><br /><link rel="stylesheet" type="text/css" href="pportal.css" /><br /></head><br /><body><br /><div id="container"><br /><div id="header"><br /><h1 class="top">Rasch-ItemBank</h1><br /><h3 class="top">A<br /><a class="top" href="http://www.interactived.com/softway.htm"><br />Softway</a> Open Source Project <br/><br />Hosted by <a class="top" href="http://java.net/projects">Java.net</a><br /></h3><br /></div><br /><div id="left"><br /><b>Menu</b><br /><br /><a class="menu" href="http://www.interactived.com/softway.htm">Home</a><br /><br /><a class="menu" href="http://www.interactived.com/research.htm">Research</a><br /><br /><a class="menu" href="http://www.interactived.com/software.htm">Software</a><br /></div><br /><div id="content" style="height:400px;width:85%;"><br /><h1 class="main">Active Math Java</h1><br /><h3 class="main">Private Portal<br/><br />The Blueridge School of Apalit, Inc.<br /></h3><br /><div id=logintable class=inputtable><br /><div id=row1 class=row><br /><h3>Initial Login Screen</h3><br /><form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"><br /><div id=row1 class=row><br /><div id=cell11 class=col1>Please select user or admin</div><br /><div id=cell12 class=col2><br /><select name="usertype" class=cbox><br /><option value="user">user</option><br /><option value="admin">admin</option><br /></select><br /></div><br /></div><br/><br /><div id=row2 class=row><br /><?php<br />if ( $error && empty($username) ) {<br />echo '<span style="gt;Oh Dear! You did not enter your name.</span><br>',"\n";<br />}<br />?><br /><div id=cell21 class=col1>Please enter your name</div><br /><div id=cell22 class=col2><input type="text" name="username" class=itext /></div><br /></div><br/><br /><div id=row3 class=row><br /><?php<br />if ( $error && empty($password) ) {<br />echo '<span style="gt;Oh Dear! You did not enter your password.</span><br>',"\n";<br />}<br />?><br /><div id=cell31 class=col1>Please enter your password</div><br /><div id=cell32 class=col2><input type="password" name="password" class=itext /></div><br /></div><br/><br /><div id=row4 class=row><br /><div id=cell41 class=col1>Click button to log in</div><br /><div id=cell42 class=col2><input type="submit" name="login" value="Log in to Portal" class=itext /></div><br /></div><br/><br /></form><br /></div><br /></div><br /></div><br /><br /><div id="footer"><br />Helping Children to Achieve their Potential</div><br /></div><br /></body><br /></html></code></p> <p>And when I clicked the login button, with two empty fields, the page came up as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYNmwLB932z_e6kRSiDD8mAVH_yuTgFyMaii8aEw137rbGaNYITfMM70i6B-i6XFdT713Fm_tBUTXFW9l0XT-NEhzSg4FFD4Y1DGeDR92bf6zA9gtCJcgH718R8BJDuQYcXiacLswskuA/s1600/pic03.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 298px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYNmwLB932z_e6kRSiDD8mAVH_yuTgFyMaii8aEw137rbGaNYITfMM70i6B-i6XFdT713Fm_tBUTXFW9l0XT-NEhzSg4FFD4Y1DGeDR92bf6zA9gtCJcgH718R8BJDuQYcXiacLswskuA/s320/pic03.JPG" alt="" id="BLOGGER_PHOTO_ID_5666610749350176818" border="0" /></a> </p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-70444972687756710232011-10-22T09:35:00.000-07:002011-10-22T09:42:19.967-07:00Creating a login pageThere are three steps to creating a login page, or really any page which exchanges information with a database. <ol><li>Creating the front end interface;</li><li>Writing the business rules;</li><li>Writing the interface with the database.</li></ol> <p>In a <a href="http://jhippjava.blogspot.com/2011/09/simple-web-application-add-data-form.html"> previous post</a> I already described a form which added records to a data table. In that example I was a bit sloppy, because I omitted any business rules code. My excuse was that the data table in that example was intended to be populated automatically, so the input form would never be used in real life.</p> <p>I am now dealing with a request from a school to track student performance, so I have to create a manual database portal or interface for them. The first step is the login screen. At a trivial level, this is just a couple of fields and a button, so not much thought needs to go into it.</p> <p>But as I am using the exercise to stimulate a web site redesign, I have chosen to go a little deeper. My usual method of making forms look reasonably neat is to shove them in a table. But the HTML purists don't like table any more, so I decided to look into using the <code><div></code> tag instead. At the same time, I extended my use of the external CSS page, which I used in my <a href="http://jhippjava.blogspot.com/2011/10/web-site-redesign.html">previous post</a>.</p> <p>Whether correctly or not, I followed the pattern of a table, with a series of horizontal rows, each nested with two "cells", one floating to the left, the other to the right, and all inside a "zone" which I classified as "inputtable", which in turn lay inside the page (code not shown) created in my <a href="http://jhippjava.blogspot.com/2011/10/web-site-redesign.html">previous post</a>:</p> <p><code><div id=logintable class=inputtable><br /><div id=row0 class=row><br /><h3>Initial Login Screen</h3><br /><form><br /><div id=row1 class=row><br /><div id=cell11 class=col1>Please select user or admin</div><br /><div id=cell12 class=col2><br /><select name="usertype" class=cbox><br /><option value="user">user</option><br /><option value="admin">admin</option><br /></select><br /></div><br /></div><br/><br /><div id=row2 class=row><br /><div id=cell21 class=col1>Please enter your name</div><br /><div id=cell22 class=col2><input type="text" name="username" class=itext /></div><br /></div><br/><br /><div id=row3 class=row><br /><div id=cell31 class=col1>Please enter your password</div><br /><div id=cell32 class=col2><input type="password" name="password" class=itext /></div><br /></div><br/><br /><div id=row4 class=row><br /><div id=cell41 class=col1>Click button to log in</div><br /><div id=cell42 class=col2><input type="submit" value="Log in to Portal" class=itext /></div><br /></div><br/><br /></form><br /></div><br /></div></code></p> <p>To accommodate the extra classes, the CSS page was expanded as follows:</p> <p><code>body {<br />margin:10px 0px; padding:0px;<br />text-align:center;<br />}<br />#container {width:800;}<br />#header {background-color:#151B8D;text-align:left;}<br />#left {background-color:#5CB3FF;height:500px;width:15%;float:left;text-align:left;}<br />#content {height:400px;width:85%;}<br />#footer {background-color:#488AC7;clear:both;text-align:center;}<br /><br />a:link {text-decoration:none;} /* unvisited link */<br />a:visited {text-decoration:none;} /* visited link */<br />a:hover {text-decoration:underline;} /* mouse over link */<br />a:active {text-decoration:none;} /* selected link */<br /><br />h1.top {margin-bottom:0;color=#FFFF00;}<br />h3.top {margin-bottom:0;margin-top:0;color=#FFFF00;}<br />a.top {color=#FFFF00;}<br /><br />h1.main {margin-bottom:0;text-align:center;}<br />h3.main {margin-bottom:0;margin-top:0;text-align:center;}<br /><br />a.menu {color=#000000;}<br /><br />.inputtable {margin:50; background-color:#BDEDFF}<br />.row {width:420;}<br />.col1 {text-align:right; float:left; width:200; margin:0 5 0 5;}<br />.col2 {text-align:left; float:right; width:200; margin:0 5 0 5;}<br />.itext {width:150;}<br />.cbox {width:150; margin-left:5;}</code></p> <p>And the finished page looked as follows:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHZEASqorUKXAeRolAR4q5ffde4qG6zXS7WXjsPLtvEK6qnlyjpLzwFOjBb2v-Mpi3OLCYI_eBFHErlJk109OuZTlUL2HL1MBuQn2Zjb502MeH-Rh0w_slBjRJakHBWmkehVgdaIaVVWA/s1600/pic02.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 302px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHZEASqorUKXAeRolAR4q5ffde4qG6zXS7WXjsPLtvEK6qnlyjpLzwFOjBb2v-Mpi3OLCYI_eBFHErlJk109OuZTlUL2HL1MBuQn2Zjb502MeH-Rh0w_slBjRJakHBWmkehVgdaIaVVWA/s320/pic02.JPG" alt="" id="BLOGGER_PHOTO_ID_5666356565456011458" border="0" /></a></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-33868036828130305572011-10-21T04:26:00.000-07:002011-10-21T04:28:34.693-07:00Web site redesignIn my quest to get <a href="http://www.interactived.com/JMT1111/JMT1111.htm"> my Applet</a> talking to a commercially hosted MySQL database, I was forced to update my knowledge of a number of related areas, including HTML. Coincidentally, I get a lot of spam telling me how dreary and old fashioned my MS Front page designed <a href="http://www.interactived.com/softway.htm">website</a> is. <p>A school has asked for a private portal to <a href="http://www.interactived.com/JMT1111/JMT1111.htm">the Applet</a>, and I want the page to remain outside the main <a href="http://www.interactived.com/softway.htm">website</a> navigation structure. I could just give them a form on a plain page. Or I could use the opportunity to play with HTML layouts and CSS.</p> <p>My favorite tutorial site, <a href="http://www.w3schools.com/default.asp"> W3schools</a>, has a nice <a href="http://www.w3schools.com/html/html_layout.asp">sample layout</a>, similar to their own. I have adapted this with my own colors and text. I have also changed the behavior of links, so that they look more like surrounding test, except when they are hovered over. My HTML was as follows:</p> <p> <code><html><br /><head><br /><title>Active Math Java Private Portal</title><br /><style type="text/css"><br />a:link {text-decoration:none;} /* unvisited link */<br />a:visited {text-decoration:none;} /* visited link */<br />a:hover {text-decoration:underline;} /* mouse over link */<br />a:active {text-decoration:none;} /* selected link */<br /></style><br /></head><br /><body><br /><div id="container" style="width:100%"><br /><div id="header" style="background-color:#151B8D"><br /><h1 style="margin-bottom:0;color=#FFFF00;">Rasch-ItemBank</h1><br /><h3 style="margin-bottom:0;margin-top:0;color=#FFFF00;">A<br /><a href="http://www.interactived.com/softway.htm" style="color=#FFFF00;"><br />Softway</a> Open Source Project</h3><br /><h3 style="margin-bottom:0;margin-top:0;color=#FFFF00;">Hosted by<br /><a href="http://java.net/projects" style="color=#FFFF00;">Java.net</a></h3><br /></div><br /><div id="menu" style="background-color:#82CAFA;height:400px;width:15%;float:left;"><br /><b>Menu</b><br /><br /><a href="http://www.interactived.com/softway.htm" style="color=#000000;">Home</a><br /><br /><a href="http://www.interactived.com/research.htm" style="color=#000000;">Research</a><br /><br /><a href="http://www.interactived.com/software.htm" style="color=#000000;">Software</a></div><br /><div id="content" style="height:400px;width:85%;"><br /><h1 style="margin-bottom:0;text-align:center">Active Math Java</h1><br /><h3 style="margin-bottom:0;margin-top:0;text-align:center">Private Portal</h3><br /><h3 style="margin-bottom:0;margin-top:0;text-align:center"><br />The Blueridge School of Apalit, Inc.<br /></h3><br /></div><br /><div id="footer" style="background-color:#56A5EC;clear:both;text-align:center;"><br />Helping Children to Achieve their Potential</div><br /></div><br /></body><br /></html></code> </p> <p>And it came up as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCA2RNiGJYGuk3OHzqYBNvIewiSULvxLSIAOTrAJppL5X-yWrVh2uW4M0J_OvEibjSAPdtId77tLuEtgnNv1lHV14eBOz_5BU_RSIUVrf2zxba1qUobRIgYjji3alpnQFl0BnCIx4aM44/s1600/pic01.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 256px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCA2RNiGJYGuk3OHzqYBNvIewiSULvxLSIAOTrAJppL5X-yWrVh2uW4M0J_OvEibjSAPdtId77tLuEtgnNv1lHV14eBOz_5BU_RSIUVrf2zxba1qUobRIgYjji3alpnQFl0BnCIx4aM44/s320/pic01.JPG" alt="" id="BLOGGER_PHOTO_ID_5665905718478946754" border="0" /></a></p> <p>The <a href="http://www.w3schools.com/css/default.asp">tutorial</a> recommended using an external CSS style sheet, so as to facilitate site wide design changes. That's fine for colors and fonts, but a question running through my mind is how they achieve site wide menu changes. Their own source code betrays few secrets these days because it might have been generated with a script, although it certainly represents a thorough example of using the <code><div></code> tag.</p> <p>I found the CSS tutorial a bit confusing when it came to <a href="http://www.w3schools.com/css/css_id_class.asp">classes</a>, but part of the confusion arose because of my inability to type. Anyway, after some fiddling around, my CSS page looked like this:</p> <p><code>a:link {text-decoration:none;} /* unvisited link */<br />a:visited {text-decoration:none;} /* visited link */<br />a:hover {text-decoration:underline;} /* mouse over link */<br />a:active {text-decoration:none;} /* selected link */<br /><br />h1.top {margin-bottom:0;color=#FFFF00;}<br />h3.top {margin-bottom:0;margin-top:0;color=#FFFF00;}<br />a.top {color=#FFFF00;}<br /><br />h1.main {margin-bottom:0;text-align:center;}<br />h3.main {margin-bottom:0;margin-top:0;text-align:center;}<br /><br />a.menu {color=#000000;}<br /><br />#header {background-color:#151B8D;}<br />#left {background-color:#82CAFA;height:400px;width:15%;float:left;}<br />#content {height:400px;width:85%;}<br />#footer {background-color:#56A5EC;clear:both;text-align:center;}</code></p> <p>And the HTML became:</p> <p><code><html><br /><head><br /><title>Active Math Java Private Portal</title><br /><link rel="stylesheet" type="text/css" href="pportal.css" /><br /></head><br /><body><br /><div id="container" style="width:100%"><br /><div id="header"><br /><h1 class="top">Rasch-ItemBank</h1><br /><h3 class="top">A<br /><a class="top" href="http://www.interactived.com/softway.htm"><br />Softway</a> Open Source Project <br/><br />Hosted by <a class="top" href="http://java.net/projects">Java.net</a><br /></h3><br /></div><br /><div id="left"><br /><b>Menu</b><br /><br /><a class="menu" href="http://www.interactived.com/softway.htm">Home</a><br /><br /><a class="menu" href="http://www.interactived.com/research.htm">Research</a><br /><br /><a class="menu" href="http://www.interactived.com/software.htm">Software</a><br /></div><br /><div id="content" style="height:400px;width:85%;"><br /><h1 class="main">Active Math Java</h1><br /><h3 class="main">Private Portal<br/><br />The Blueridge School of Apalit, Inc.</h3><br /></div><br /><div id="footer"><br />Helping Children to Achieve their Potential</div><br /></div><br /></body><br /></html></code></p> <p>And to my enormous surprise it ended up looking exactly the same as that produced by the single page as shown above.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-24205977511661910292011-09-24T00:59:00.000-07:002011-10-25T23:07:27.416-07:00Applet to AJAX to PHP methodology<p>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:</p> <p><code>private void addItem3(String newWord) {<br />if(LIVE) {<br />if(jso != null )<br />try {<br />jso.call("updateWebPage", new String[] {newWord});<br />}<br />catch (Exception ex) {<br />addItem2("jso call failed... ");<br />ex.printStackTrace();<br />}<br />}<br />}</code></p> <p>Where the parameter <code>newWord</code> being passed to that method might look like:</p> <p><code>INSERT INTO mytable (Partid, OpCode, ItemLeft, ItemRight, Raw, Rate) VALUES (684, 1, 2, 5, 1, 34)</code></p> <p>The JavaScript function updateWebPage and the PHP script were given in my <a href="http://jhippjava.blogspot.com/2011/09/applet-to-javascript-to-php-post-to.html">previous post</a>, so I won't repeat them here.</p> <p>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. </p> <p>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.</p> <p>This blog is intended for theory questions and problems. Practical implementation thoughts and solutions are the domain of my <a href="http://rasch-itembank.blogspot.com/">Rasch blog</a>, so I think I'll transfer this one over there.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-50911322624659221492011-09-20T00:09:00.000-07:002011-09-20T00:17:28.766-07:00Applet to JavaScript to PHP post to DatabaseThis post brings together the <a href="http://jhippjava.blogspot.com/2011/09/pass-sql-command-from-applet-to.html">previous</a> two. In the <a href="http://jhippjava.blogspot.com/2011/09/php-and-javascriptajax-database-query.html"> first</a>, I called PHP code from a JavaScript function using an AJAX command. In the <a href="http://jhippjava.blogspot.com/2011/09/pass-sql-command-from-applet-to.html"> second</a>, 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. <p>The applet code was unchanged, but the JavaScript function was extended from:</p> <p><code><script type="text/javascript"><br />function updateWebPage(myArg)<br />{<br />document.getElementById("txt1").innerHTML=myArg;<br />}<br /></script></code></p> <p>to:</p> <p><code><script type="text/javascript"><br />function updateWebPage(myArg)<br />{<br />document.getElementById("txt1").innerHTML=myArg;<br />if (myArg=="")<br />{<br />document.getElementById("cbxItem").innerHTML="";<br />return;<br />}<br />if (window.XMLHttpRequest)<br />{// code for IE7+, Firefox, Chrome, Opera, Safari<br />xmlhttp=new XMLHttpRequest();<br />}<br />else<br />{// code for IE6, IE5<br />xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");<br />}<br />xmlhttp.onreadystatechange=function()<br />{<br />if (xmlhttp.readyState==4 && xmlhttp.status==200)<br />{<br />document.getElementById("cbxItem").innerHTML=xmlhttp.responseText;<br />}<br />}<br />xmlhttp.open("GET","putitem.php?id="+myArg,true);<br />xmlhttp.send();<br />}<br /></script></code></p> <p>And the HTML table had an extra couple of cells added:</p> <p><code><table border=1 align='center' cellpadding=0 cellspacing=0 ><br /><tr><td style='text-align:center; background-color:#C0C0C0'>Compiled Java Applet</td></tr><br /><tr><td><applet code="JSHelloWorld2.class"<br />width="500" height="80" MAYSCRIPT style="border-width:0;" name="jsap" id="jsap"><br /></applet> </td></tr><br /><tr><td style='text-align:center; background-color:#C0C0C0'>HTML Textbox filled by JavaScript</td></tr><br /><tr><td><textarea style='width:500px; height:50px' name='txt1' id='txt1'>Query goes here</textarea></td></tr><br /><tr><td style='text-align:center; background-color:#C0C0C0'>HTML diagnostic messages rendered by PHP script</td></tr><br /><tr><td><div id="cbxItem">PHP info will populate this space</div></td></tr><br /></table></code></p> <p>The PH script was:</p> <p><code><?php<br />$id = $_GET['id'];<br />include('dbinfo.php');// collect database variables and connect.<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />// first use encodeURIComponent on javascript to encode the string<br />// receive json string and prepare it to json_decode<br />$jsonStr = stripslashes ($id);<br />$query = $jsonStr;<br />$result = mysql_query($query) or die(mysql_error());<br />echo"<p>The query is: $query </p>";<br />echo"<p>The result is: $result </p>";<br />mysql_close($con);</code><br />?></p> <p>I hate it when people put obscure references in code, so for anyone who has not been following this blog, the <code>dbinfo.php</code> structure was given in the <a href="http://jhippjava.blogspot.com/2011/09/simple-web-application-data-display.html"> Simple Web Application – Data Display page</a>.</p> <p>On opening, the web page looked as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtdWT557glT7TcXS_0rhGrjd9llaDcM25BIEGF_6DHUEsG1Tu_x237_dM5hLEzSnH1cxFWzNtCfEAGorrhHitxbESk3Ti4BMikU_Eh0UueAzdCphFmUrHyA4YjtxWaSv8XNXz7dU-eG3I/s1600/pic61.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 219px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtdWT557glT7TcXS_0rhGrjd9llaDcM25BIEGF_6DHUEsG1Tu_x237_dM5hLEzSnH1cxFWzNtCfEAGorrhHitxbESk3Ti4BMikU_Eh0UueAzdCphFmUrHyA4YjtxWaSv8XNXz7dU-eG3I/s320/pic61.jpg" alt="" id="BLOGGER_PHOTO_ID_5654336014676064706" border="0" /></a></p> <p>And after clicking the button on the applet, it was as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHyVu3kgc7qCJnEsER08B5sOzOLMReD0siniquKyKS_83z7gNFnKRVj5dBtFuE7Yz3eyXWH7pGvi0kLT1wDWEMiv0dMqP7njV5Rb1RV1c7dKQMfpXAyXmPy_WJFAT_rPuLgy7aoVyfkCc/s1600/pic62.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 270px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHyVu3kgc7qCJnEsER08B5sOzOLMReD0siniquKyKS_83z7gNFnKRVj5dBtFuE7Yz3eyXWH7pGvi0kLT1wDWEMiv0dMqP7njV5Rb1RV1c7dKQMfpXAyXmPy_WJFAT_rPuLgy7aoVyfkCc/s320/pic62.jpg" alt="" id="BLOGGER_PHOTO_ID_5654336019945076098" border="0" /></a></p> <p>The result of 1 (or true) returned by the query indicated that a line had been successfully inserted. Inspection of the database using the <a href="http://jhippjava.blogspot.com/2011/09/simple-web-application-data-display.html"> Simple Web App</a>, confirmed that this was the case. The only minor problem was the loss of the plus sign in "Itemdet", but that can be fixed.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com1tag:blogger.com,1999:blog-8882010943472432760.post-156870842985021482011-09-19T21:11:00.000-07:002011-09-19T21:18:38.593-07:00Pass SQL command from Applet to JavaScript functionMy last post recorded an important milestone for me, because I managed to call PHP code from a JavaScript function. <p>On an earlier occasion, I had managed to call a JavaScript function from an Applet.</p> <p>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 <a href="http://jhippjava.blogspot.com/2011/09/applet-to-javascript-communication.html"> Applet to JavaScript</a> example to display an SQL command. This was essentially a cosmetic exercise, but it acted as a refresher on the code.</p> <p>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 <a href="http://jhippjava.blogspot.com/2011/09/applet-to-javascript-communication.html"> my previous post</a> on the topic.</p> <p>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:</p> <p><code><html><br /><body><br /><script type="text/javascript"><br />function updateWebPage(myArg)<br />{<br />document.getElementById("txt1").innerHTML=myArg;<br />}<br /></script><br /><form><br /><table border=0 align='center' cellpadding=0 cellspacing=0 ><br /><tr><br /><td valign='top'><br /><table><br /><tr><td style='text-align:center; background-color:#EEEEEE'>Applet</td></tr><br /><tr><td><br /><applet code="JSHelloWorld2.class"<br />width="500" height="80" MAYSCRIPT style="border-width:0;" name="jsap" id="jsap"><br /></applet> </td></tr><br /><tr><td style='text-align:center; background-color:#EEEEEE'>JavaScript</td></tr><br /><tr><td><textarea style='width:500px; height:50px' name='txt1' id='txt1'>Query goes here</textarea></td></tr><br /></table><br /></form><br /></body><br /></html></code></p> <p>It came up initially as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9HKsZeKI0mLPZaOFqEi6D2mHg_2PCyj4-fG1sC82z6aRhzkRJVZLvjLDo2Y17Qvu9VPPJF4cG0jaVHym7V8SD3zpkyTNlxHgXp94w9TM_PxZakyJ0rmiY13qxH-3sXV0qzWFrehTurhQ/s1600/pic51.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 180px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9HKsZeKI0mLPZaOFqEi6D2mHg_2PCyj4-fG1sC82z6aRhzkRJVZLvjLDo2Y17Qvu9VPPJF4cG0jaVHym7V8SD3zpkyTNlxHgXp94w9TM_PxZakyJ0rmiY13qxH-3sXV0qzWFrehTurhQ/s320/pic51.jpg" alt="" id="BLOGGER_PHOTO_ID_5654290984521387106" border="0" /></a></p> <p>After clicking the Applet button it was then as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji8u47cYcPFBib8-ti5IaPFhViQxXIYcXnB5fWYUeBG35iGoHjGPddxQXiSiO3g5ltfzd4dO5IqaQvbUF4btajbiu1Za3JP73vV4KBWEm8SPdKfVCDxOO6FBTtU0q2qHXMU5Gw4qMjOsg/s1600/pic52.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 180px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji8u47cYcPFBib8-ti5IaPFhViQxXIYcXnB5fWYUeBG35iGoHjGPddxQXiSiO3g5ltfzd4dO5IqaQvbUF4btajbiu1Za3JP73vV4KBWEm8SPdKfVCDxOO6FBTtU0q2qHXMU5Gw4qMjOsg/s320/pic52.jpg" alt="" id="BLOGGER_PHOTO_ID_5654290988046353138" border="0" /></a></p> <p>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.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMZTSZNTtMWKefw_lKGzS1cB0AhitkjyXx6rxB-PhKjpek9kj2J6T0kNI6A8LI8__vBB7vx-GbslCRrVvvT7UQw4r6VPjPtbnNLc_BLtxRFSW52ls5Dh3nmpNe8d0XcbzuUYTbF5ZzcVQ/s1600/pic53.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 180px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMZTSZNTtMWKefw_lKGzS1cB0AhitkjyXx6rxB-PhKjpek9kj2J6T0kNI6A8LI8__vBB7vx-GbslCRrVvvT7UQw4r6VPjPtbnNLc_BLtxRFSW52ls5Dh3nmpNe8d0XcbzuUYTbF5ZzcVQ/s320/pic53.jpg" alt="" id="BLOGGER_PHOTO_ID_5654290983979841106" border="0" /></a></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-76101513074211641382011-09-18T00:37:00.000-07:002011-10-25T23:06:09.417-07:00PHP and JavaScript/AJAX database queryIncluding 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 <a href="http://jhippjava.blogspot.com/2011/09/javascript-and-php.html"> September 9 blog entry</a> 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. <p>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 <a href="http://www.w3schools.com/default.asp">W3Schools</a> website. In <a href="http://jhippjava.blogspot.com/2011/08/asynchronous-javascript-and-xml-ajax.html"> my post</a> on their <a href="http://www.w3schools.com/ajax/default.asp">AJAX</a> tutorial, I bemoaned that fact that their <i>exchanging data with a server</i> 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 <a href="http://www.w3schools.com/PHP/default.asp">w3schools tutorial on the topic</a> gives an example of communicating with a database, using AJAX and PHP, in <a href="http://www.w3schools.com/php/php_ajax_database.asp">one of the advanced sections</a>. I shall now work through that example.</p> <p>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.</p> <p>Of course I have posted code for some working web pages in my <a href="http://jhippjava.blogspot.com/2011/09/simple-web-application-data-display.html"> last few entries</a>, (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.</p> <p>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 <a href="http://www.w3schools.com/PHP/default.asp">the tutorial</a>. 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.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj903nMOhddJYL9RLgHQ1Pu7KUMNxpuaZqK2CgBrrFyoEPrCTt1pEGCKJeaieOb1WKafi1jpxVT_P0kfXkkUVfRdBBUjlBziQgEcapkWpKwexVjZtFsY4_L3ygb7BJpdoW4lv3-8K_d_rE/s1600/pic41.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 249px; height: 233px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj903nMOhddJYL9RLgHQ1Pu7KUMNxpuaZqK2CgBrrFyoEPrCTt1pEGCKJeaieOb1WKafi1jpxVT_P0kfXkkUVfRdBBUjlBziQgEcapkWpKwexVjZtFsY4_L3ygb7BJpdoW4lv3-8K_d_rE/s320/pic41.jpg" alt="" id="BLOGGER_PHOTO_ID_5653601429762011106" border="0" /></a></p> <p>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.</p> <p>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 <a href="http://jhippjava.blogspot.com/2011/08/asynchronous-javascript-and-xml-ajax.html">my notes on AJAX</a> the syntax of the open method is:</p> <p><code>xmlhttp.open("METHOD","URL",async); </code></p> <p>Where <code>URL</code> 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.</p> <p>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:</p> <p><code><html><br /><head><br /><head><br /><title>AJAXPHPexpt1</title><br /><script type="text/javascript"><br />function showItem(idx)<br />{<br />if (idx=="")<br />{<br />document.getElementById("cbxItem").innerHTML="";<br />return;<br />}<br />if (window.XMLHttpRequest)<br />{// code for IE7+, Firefox, Chrome, Opera, Safari<br />xmlhttp=new XMLHttpRequest();<br />}<br />else<br />{// code for IE6, IE5<br />xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");<br />}<br />xmlhttp.onreadystatechange=function()<br />{<br />if (xmlhttp.readyState==4 && xmlhttp.status==200)<br />{<br />document.getElementById("cbxItem").innerHTML=xmlhttp.responseText;<br />}<br />}<br />xmlhttp.open("GET","getitem.php?id="+idx,true);<br />xmlhttp.send();<br />}<br /></script><br /></head><br /><body><br /><form><br /><select name="itemselection" onchange="showItem(this.value)"><br /><option value="">Select an item:</option><br /><option value="2">2+2=</option><br /><option value="4">2+3=</option><br /><option value="7">4+3=</option><br /></select><br /></form><br /><br /><br /><div id="cbxItem"><b>Item info will be listed here.</b></div><br /></body><br /></html> </code></p> <p>And my PHP code was:</p> <p><code><?php<br />$id = $_GET['id'];<br />include('dbinfo.php');// collect database variables and connect.<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />$query = "SELECT * FROM mytable WHERE Itemid=".$id;<br />$result = mysql_query($query) or die(mysql_error());<br />echo"<p>The item id is now: $id </p>";<br />echo"<p>The query is: $query </p>";<br />echo<br />'<table style="text-align:center;"><br /><tr bgcolor="#CCCCCC"><br /><td width="60"><strong>Itemid</strong></td><br /><td width="60"><strong>Partid</strong></td><br /><td width="60"><strong>OpCode</strong></td><br /><td width="60"><strong>Itemdet</strong></td><br /><td width="60"><strong>Raw</strong></td><br /><td width="60"><strong>Rate</strong></td><br /></tr>';<br />while($row = mysql_fetch_array($result))<br />{<br />echo "<tr>";<br />echo "<td>" . $row['Itemid'] . "</td>";<br />echo "<td>" . $row['OpCode'] . "</td>";<br />echo "<td>" . $row['Partid'] . "</td>";<br />echo "<td>" . $row['Itemdet'] . "</td>";<br />echo "<td>" . $row['Raw'] . "</td>";<br />echo "<td>" . $row['Rate'] . "</td>";<br />echo "</tr>";<br />}<br />mysql_close($con);<br />?></code></p> <p>And after selecting an item, the page was as shown below:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0ex2yOXXV943H9JOk5gL2FSM_HFsL9xBOEg9erSmBsv49nmyGbv3U8hjDPlVRZsokzUpzjupsAM4kmTMutpQxoslZYdrq0YpFsFmnPobd1KgOTxR79UvsqOKxhYWeRTgtulY1f9nhrGg/s1600/pic42.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 272px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0ex2yOXXV943H9JOk5gL2FSM_HFsL9xBOEg9erSmBsv49nmyGbv3U8hjDPlVRZsokzUpzjupsAM4kmTMutpQxoslZYdrq0YpFsFmnPobd1KgOTxR79UvsqOKxhYWeRTgtulY1f9nhrGg/s320/pic42.jpg" alt="" id="BLOGGER_PHOTO_ID_5653601428000220370" border="0" /></a></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-7319962615925985882011-09-17T00:22:00.000-07:002011-10-25T23:03:48.157-07:00Simple Web Application – Delete Data lineOnce again I should like to acknowledge the <a href="http://www.vt.edu/">Virginia Tech</a> <a href="http://www.hosting.vt.edu/tutorials/phpmysql/#exampleapp">Simple Web Application</a> sample code, which provided a template for this little project, which has really helped to improve my practical understanding of PHP.<p> 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.</p><p> The bloated code was as follows:</p><p> <code><?php<br />$id = $_GET['id'];<br />if (empty($id)) {<br />Header("Location: listcontacts.php");<br />exit;<br />}<br />include('dbinfo.php');// collect database variables and connect.<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />$query = "DELETE FROM mytable WHERE Itemid=".$id;<br />$result = mysql_query($query) or die(mysql_error());<br />mysql_close($con); //close connection because job finished<br />// Header("Location: jsphp4.php"); //return to main display form<br />?><br /><html><br /><head><br /><title>Delete item diagnostics</title><br /></head><br /><body><br /><h1>Delete Item</h1><br /><p>The item id is now: <?php echo $id ?> </p><br /><p>The query is: <?php echo $query ?> </p><br /></body><br /></html></code></p><p> And the page was as shown below:</p><p> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBNIoqwgTxmkPJURHNKQ5wgRv72Gp0a4zbqhD-pBZ0AGC17HLx6dmJe_jdemQYUoyka5lwdAwqa-1mQGs7h1hVQVS0S3awGkij8LXMzb4Mtepf8uC_fweEGdLdjC23I5ofSIg4jNCJ2S4/s1600/pic31.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 249px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBNIoqwgTxmkPJURHNKQ5wgRv72Gp0a4zbqhD-pBZ0AGC17HLx6dmJe_jdemQYUoyka5lwdAwqa-1mQGs7h1hVQVS0S3awGkij8LXMzb4Mtepf8uC_fweEGdLdjC23I5ofSIg4jNCJ2S4/s320/pic31.jpg" alt="" id="BLOGGER_PHOTO_ID_5653226635387853282" border="0" /></a></p><p> After checking the query, the slimmed down “production” code was:</p><p> <code><?php<br />$id = $_GET['id'];<br />if (empty($id)) {<br />Header("Location: listcontacts.php");<br />exit;<br />}<br />include('dbinfo.php');// collect database variables and connect.<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />$query = "DELETE FROM mytable WHERE Itemid=".$id;<br />$result = mysql_query($query) or die(mysql_error());<br />mysql_close($con); //close connection because job finished<br />Header("Location: jsphp4.php"); //return to main display form<br />?></code></p><p> And of course there is no pic to show, because after the delete code has run we are returned to the main page. </p><p> 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.</p> <p>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. </p> <p>My next step is to call a PHP script from an Applet.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com1tag:blogger.com,1999:blog-8882010943472432760.post-71882496978390642332011-09-16T01:06:00.000-07:002011-10-25T23:02:44.510-07:00Simple Web Application – Add Data FormWhile I must still acknowledge the <a href="http://www.vt.edu/">Virginia Tech</a> <a href="http://www.hosting.vt.edu/tutorials/phpmysql/#exampleapp">Simple Web Application</a> sample code, at this stage in the project I was primarily cutting and pasting from the code shown in my <a href="http://jhippjava.blogspot.com/2011/09/simple-web-application-data-edit-form.html">previous posts</a>, and manually making a few small changes from the sample code.<p> 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. </p><p> 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.</p><p> 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><p> <code><p>The query is: <?php echo $query ?> </p><br /><p>Status is: <?php echo $jonathan ?> </p></code></p><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:</p><p> <code>// Header("Location: jsphp4.php"); //return to main display form</code></p><p> When everything is working the comment strokes (on the left) can be removed, and the diagnostic lines can be removed from the HTML.</p><p> My working (diagnostic) code was as follows:</p> <p> <code><?php<br />include('dbinfo.php');// collect database variables and connect.<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />if (isset($_POST['addcontact'])) { // run this when the user hits the "Add Contact" button<br />$jonathan="Add loop";<br />$Partid = $_POST['Partid'];<br />$OpCode = $_POST['OpCode'];<br />$Itemdet = $_POST['Itemdet'];<br />$Raw = $_POST['Raw'];<br />$Rate = $_POST['Rate']; // input validation removed from under here<br />$query = "INSERT INTO mytable (Partid, OpCode, Itemdet, Raw, Rate) VALUES (".$Partid.",".$OpCode.",'".$Itemdet."',".$Raw.",".$Rate.")";<br />$result = mysql_query($query) or die(mysql_error()); //adds form inputs<br />mysql_close($con); //close connection because job finished<br />Header("Location: jsphp4.php"); //return to main display form<br />}<br />?><br /><html><br /><head><br /><title>Add a Line</title><br /></head><br /><body><br /><h1>Add a Line</h1><br /><p>The query is: <?php echo $query ?> </p><br /><p>Status is: <?php echo $jonathan ?> </p><br /><form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"><br /><table style="text-align:right;"><br /><tr><td>Partid:<input name="Partid" type="text" value="<?php echo $Partid; ?>"></td></tr><br /><tr><td>Opcode:<input name="OpCode" type="text" value="<?php echo $OpCode; ?>"></td></tr><br /><tr><td>Itemdet:<input name="Itemdet" type="text" value="<?php echo $Itemdet; ?>"></td></tr><br /><tr><td>Raw:<input name="Raw" type="text" value="<?php echo $Raw; ?>"></td></tr><br /><tr><td>Rate:<input name="Rate" type="text" value="<?php echo $Rate; ?>"></td></tr><br /><tr><td><input type="submit" name="addcontact" value="Add Line"></td></tr><br /></table><br /></form><br /><p><a href="jsphp4.php">Click here to return to List</a></p><br /></body><br /></html></code> </p> <p>And after clicking the Add Line button, the page, with diagnostic code, was as shown below:</p> <p> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR8nKOZciCZfBj7GEO4FnSiJNTsaVbqj8QF8sPj6WzvS87rtn5_DROi4njDGWy4COqtYsczx-73Nz2X6mRj-xRuorJYkMeyI_gx-M-iLWS4YsAEVig3lBPnRPD-NdruG9b0NRic8_K4jw/s1600/pic21.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 260px; height: 356px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR8nKOZciCZfBj7GEO4FnSiJNTsaVbqj8QF8sPj6WzvS87rtn5_DROi4njDGWy4COqtYsczx-73Nz2X6mRj-xRuorJYkMeyI_gx-M-iLWS4YsAEVig3lBPnRPD-NdruG9b0NRic8_K4jw/s320/pic21.jpg" alt="" id="BLOGGER_PHOTO_ID_5652867030015237042" border="0" /></a></p><p> After removing the diagnostic code the page came up as shown below:</p><p> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjht3hSKCN5vcqlPa5dEazyH331jy1PfNbn10sz84o6F3wyK1kob1YDJILrtbs5qXUHsZuzJILSg9NuV4IHSV9mv5R2nGS-vslMfPM4KTw7E9bQsPs8vOin-asjE2wO_YBtEBrXbp76GIE/s1600/pic22.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 257px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjht3hSKCN5vcqlPa5dEazyH331jy1PfNbn10sz84o6F3wyK1kob1YDJILrtbs5qXUHsZuzJILSg9NuV4IHSV9mv5R2nGS-vslMfPM4KTw7E9bQsPs8vOin-asjE2wO_YBtEBrXbp76GIE/s320/pic22.jpg" alt="" id="BLOGGER_PHOTO_ID_5652867027407961234" border="0" /></a></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com1tag:blogger.com,1999:blog-8882010943472432760.post-45343084809076804262011-09-15T18:13:00.001-07:002011-10-25T23:02:06.199-07:00Simple Web Application – Data edit formThe <a href="http://www.vt.edu/">Virginia Tech</a> <a href="http://www.hosting.vt.edu/tutorials/phpmysql/#exampleapp">Simple Web Application</a> 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.<p> I said in <a href="http://jhippjava.blogspot.com/2011/09/simple-web-application-data-display.html">my last post</a> that I constructed my own <a href="http://www.phpbuilder.com/columns/allan20010115.php3">PHP PEAR database layer</a>, as a result of which, my code and the sample code diverged from an early point. Specifically:</p><code> include('dbconnect.php');</code><p> was stretched out to:</p><p> <code>include('dbinfo.php');<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);</code></p><p> I had some specific problems with certain lines of the sample code. One was:</p><p> <code>$result = $database->query($query);</code></p><p> I didn’t understand the funny little <code>-></code> 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:</p><p> <code>$result = mysql_query($query) or die(mysql_error());</code></p><p> Another example was</p><p> <code>$contact = $result->fetchRow(DB_FETCHMODE_ASSOC,0);</code></p><p> Which I replaced with</p><p> <code>$contact = mysql_fetch_row($result);</code></p><p> I also replaced the text references to array members:</p><p> <code>$Itemid = $contact['Itemid'];</code></p><p> With array member indices:</p><p> <code>$Itemid = $contact[0];</code></p><p> 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:</p><p> <code>$jonathan="Default loop";</code></p><p> These enabled me to track which branches of code were executing, and which variables were being properly filled.</p><p> 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.</p><p> After all this, my code was as follows:</p> <p> <code><?php<br />// get contact id<br />$id = $_GET['id'];<br />if (!empty($id)) { $_SESSION['recordId']=$id; }<br />else { $id = $_SESSION['recordId']; }<br />// if the script has been called without ID or the user hit "Cancel" just return to listing<br />if (empty($id) || isset($_POST['cancel'])) {<br />Header("Location: jsphp4.php");<br />exit;<br />}<br />include('dbinfo.php');<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />$query = "SELECT * FROM mytable WHERE Itemid=".$id;<br />$result = mysql_query($query) or die(mysql_error());<br />$contact = mysql_fetch_row($result);<br />$Itemid = $contact[0];<br />$OpCode = $contact[1];<br />$Partid = $contact[2];<br />$Itemdet = $contact[3];<br />$Raw = $contact[4];<br />$Rate = $contact[5];<br />mysql_close($con);<br />?><br /><html><br /><head><br /><title>Edit Items Table</title><br /></head><br /><body><br /><a href="jsphp4.php">Add a Line</a> | <a href="jsphp4.php">Session Data</a><br /><h1>Edit Item</h1><br /><p>The item id is now: <?php echo $id ?> </p><br /><p>The query is: <?php echo $query ?> </p><br /><p>The op code is: <?php echo $query ?> </p><br /><form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"><br /><table style="text-align:right;"><br /><tr><td>Itemid:<input name="Itemid" type="text" value="<?php echo $Itemid; ?>"></td></tr><br /><tr><td>Opcode:<input name="OpCode" type="text" value="<?php echo $OpCode; ?>"></td></tr><br /><tr><td>Partid:<input name="Partid" type="text" value="<?php echo $Partid; ?>"></td></tr><br /><tr><td>Itemdet:<input name="Itemdet" type="text" value="<?php echo $Itemdet; ?>"></td></tr><br /><tr><td>Raw:<input name="Raw" type="text" value="<?php echo $Raw; ?>"></td></tr><br /><tr><td>Rate:<input name="Rate" type="text" value="<?php echo $Rate; ?>"></td></tr><br /><tr><td><input type="hidden" name="id" value="<?php echo $id; ?>"><br /><tr><td><input type="submit" name="ok" value=" OK "><br /><tr><td><input type="submit" name="cancel" value="Cancel"><br /></table><br /></form><br /></body><br /></html></code> </p> <p>And it looked like this:</p><p> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZPce7I0LlFYDc755ZDSqH_Xd103sfHoBYA1dejUIhqTVWOX88ecEZRDKALymGIO0Kc6xCyn1QGaXftzux4R8Xd4OS89UC6VkGbFZi-i9f_PeVseg0KNXz0HfU4NYNYofeH1QPc10qkVM/s1600/pic11.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 206px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZPce7I0LlFYDc755ZDSqH_Xd103sfHoBYA1dejUIhqTVWOX88ecEZRDKALymGIO0Kc6xCyn1QGaXftzux4R8Xd4OS89UC6VkGbFZi-i9f_PeVseg0KNXz0HfU4NYNYofeH1QPc10qkVM/s320/pic11.jpg" alt="" id="BLOGGER_PHOTO_ID_5652759578554773922" border="0" /></a></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-37659601010922457012011-09-14T19:18:00.000-07:002011-10-25T23:01:04.497-07:00Simple Web Application – Data Display pageI 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 "<a href="http://www.w3schools.com/html/default.asp">Try it yourself</a>" 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. <p>The <a href="http://www.hosting.vt.edu/tutorials/phpmysql/#exampleapp"> Virginia Tech simple web application</a> 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.</p> <p>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 <a href="http://www.phpbuilder.com/columns/allan20010115.php3">PHP PEAR database layer</a> 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:</p> <p> <code><?php<br />$dbhost = 'localhost';<br />$dbuser = 'theuser';<br />$dbpass = 'thepassword';<br />$dbname = 'phptst';<br />?></code> </p> <p>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 <a href="http://jhippjava.blogspot.com/2011/08/playing-with-php.html">Playing with PHP</a> entry.</p> <p>In the end, the code in my display table was like the inverse, or a mirror image of the <a href="http://www.hosting.vt.edu/tutorials/phpmysql/#exampleapp"> sample code</a>. Their display table was written in HTML, peppered with PHP variables. My display table was a long PHP statement, peppered with HTML strings.</p> <p>My code was as shown below:</p> <p> <code><?php<br />// if the user hasn't specified any "sort" the default is "Partid"<br />if ( isset($_GET['sort']) && $_GET['sort']=='OpCode' ) { $_SESSION['sort'] = 'OpCode'; }<br />else { $_SESSION['sort'] = 'Partid'; }<br />include('dbinfo.php');<br />$con = mysql_connect( $dbhost, $dbuser, $dbpass );<br />if (!$con)<br />{<br />die('Could not connect: ' . mysql_error());<br />}<br />mysql_select_db($dbname, $con);<br />$result = mysql_query("SELECT * FROM mytable") or die(mysql_error());<br />?><br /><html><br /><head><br /><title>Session Data</title><br /></head><br /><script language="JavaScript"><br /><!--<br />function confirmdelete(id)<br />{<br />var c = confirm("Do you really want to delete this line?");<br />if (c) {<br />window.location="deletecontact.php?id="+id;<br />}<br />}<br />//--><br /></script><br /><body><br /><a href="addcontact.php">Add a Line</a> | My Items<br /><h1>Session Data</h1><br /><table style="text-align:center;"><br /><tr bgcolor="#CCCCCC"><br /><td width="70"><strong>Itemid</strong></td><br /><td width="70"><strong><?php if ($_SESSION['sort']!='OpCode') { echo '<a href="',$_SERVER['PHP_SELF'],'?sort=OpCode">Partid</a>'; } else { echo 'OpCode ↓'; } ?></strong></td><br /><td width="70"><strong><?php if ($_SESSION['sort']!='Partid') { echo '<a href="',$_SERVER['PHP_SELF'],'?sort=Partid">OpCode</a>'; } else { echo 'OpCode ↓'; } ?></strong></td><br /><td width="70"><strong>Itemdet</strong></td><br /><td width="70"><strong>Raw</strong></td><br /><td width="70"><strong>Rate</strong></td><br /><td width="70"><strong>Edit</strong></td><br /><td width="70"><strong>Delete</strong></td><br /></tr><br /><?php<br />while($row = mysql_fetch_array($result))<br />{<br />echo "<tr>";<br />echo "<td>" . $row['Itemid'] . "</td>";<br />echo "<td>" . $row['OpCode'] . "</td>";<br />echo "<td>" . $row['Partid'] . "</td>";<br />echo "<td>" . $row['Itemdet'] . "</td>";<br />echo "<td>" . $row['Raw'] . "</td>";<br />echo "<td>" . $row['Rate'] . "</td>";<br />echo '<td><a href="editcontact.php?id=' . $row['Itemid'] . '">edit</a></td>';<br />echo '<td><a href="deletecontact.php?id=' . $row['Itemid'] . '">delete</td>';<br />echo "</tr>";<br />}<br />?><br /></table><br /></body></code> </p> <p>And the page looked like this:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT4rHCrnNhrZCfjDzG0pEjT5Rb2k2eVthcnQduWOkBNI4vY7YR1hhnxxNrHYEnwEzyEBBTxkrdFJg8sx4-tRGmq-0ddn8_bdr2ckeeX0PyRodK_DKDsM5UeikC0Xj03ae5CL7i_8oYlB0/s1600/pic01.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT4rHCrnNhrZCfjDzG0pEjT5Rb2k2eVthcnQduWOkBNI4vY7YR1hhnxxNrHYEnwEzyEBBTxkrdFJg8sx4-tRGmq-0ddn8_bdr2ckeeX0PyRodK_DKDsM5UeikC0Xj03ae5CL7i_8oYlB0/s320/pic01.jpg" alt="" id="BLOGGER_PHOTO_ID_5652405557712740706" border="0" /></a></p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-49150375119923176542011-09-09T13:14:00.000-07:002011-09-16T02:55:07.221-07:00A closer look at PHP database update options<p>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 <a href="http://www.interactived.com/jartest.htm">my application</a>, I want data added to a database quietly in the background, and I certainly don't want the user dragged away from <a href="http://www.interactived.com/jartest.htm">the Applet page</a> every time a line is added to the database.</p><p> After much searching, and searches excluding terms such as "forum", (forum questions seem to dominate this topic in Google), I found <a href="http://www.hosting.vt.edu/tutorials/phpmysql/">an excellent page</a> hosted by <a href="http://www.vt.edu/">Virginia Tech</a>. This is a really good single page tutorial, which takes the reader through all the basics of PHP, from <code>echo "Hello World!";</code> to a <a href="http://www.hosting.vt.edu/tutorials/phpmysql/#exampleapp">simple web application</a>, 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.</p><p> Most importantly, for me, <a href="http://www.hosting.vt.edu/tutorials/phpmysql/">the tutorial</a> 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:</p><p> <code><form method="post" action="myCode.php"></code></p><p> 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:</p><p> <code><form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"></code></p><p> Alternatively it might look like this:</p><p> <code><form method="post" action="myCodedForm.php"></code></p><p> My plan is to adapt the examples in <a href="http://www.hosting.vt.edu/tutorials/phpmysql/">this tutorial</a> 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 <a href="http://jhippjava.blogspot.com/2011/07/creating-mysql-database-for-gui-applet.html"> here</a>. That was for a Derby database, but I also described connecting to a MySQL version with PHP <a href="http://jhippjava.blogspot.com/2011/08/playing-with-php.html">here</a>. I shall focus on the code used to add lines, to view the table contents, and to delete lines.</p><p> 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.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com1tag:blogger.com,1999:blog-8882010943472432760.post-82055497332839337672011-09-06T01:25:00.000-07:002011-09-06T01:32:17.675-07:00Applet to JavaScript CommunicationThe <a href="http://www.raditha.com/java/alert.php">raditha.com</a> site, to which I referred in my <a href="http://jhippjava.blogspot.com/2011/09/javascript-to-applet-communication.html">Javascript to Applet Communication - Example 2</a> entry, also includes a page on <a href="http://www.raditha.com/java/mayscript.php">Applet to JavaScript Communication</a>, but I could not find the required HTML/JavaScript, either on the page or in the <a href="http://www.raditha.com/java/jsalert.zip">code files</a> included at the end of the page. This was disappointing because overall it is the best site I have found on what <a href="https://developer.mozilla.org/en/LiveConnect">Mozilla</a> calls <a href="http://jhippjava.blogspot.com/2011/09/liveconnect-and-javascript-wrappers.html"> LiveConnect</a>. <p>The Java code works, and I shall cite a simplified (less graphics) version here:</p> <p><code>import javax.swing.*;<br />import netscape.javascript.JSObject;<br />import java.awt.*;<br />import java.awt.event.*;<br /><br />public class JSHelloWorld2 extends JApplet {<br />JTextArea txt = new JTextArea(100,100);<br />JButton btn = new JButton("Update Page");<br />JSObject jso;<br />public JSHelloWorld2() {<br />txt.setText("Hello World");<br />getContentPane().setLayout(new BorderLayout());<br />getContentPane().add(txt);<br />getContentPane().add(btn,BorderLayout.SOUTH);<br />btn.addActionListener(new ActionListener() {<br />public void actionPerformed(ActionEvent e) {<br />if(jso != null )<br />try {<br />jso.call("updateWebPage", new String[] {txt.getText()});<br />}<br />catch (Exception ex) {<br />ex.printStackTrace();<br />}<br />}<br />});<br />}<br />public void init()<br />{<br />jso = JSObject.getWindow(this);<br />}<br />public void setText(String s)<br />{<br />txt.setText(s);<br />}<br />}</code></p> <p>And the HTML/JavaScript I used was:</p> <p><code><html><br /><body><br /><script type="text/javascript"><br />function updateApplet()<br />{<br />document.jsap.setText(document.forms[0].txt1.value);<br />}<br />function updateWebPage(myArg)<br />{<br />document.getElementById("txt1").innerHTML=myArg;<br />}<br /></script><br /><form><br /><table border=0 align='center' cellpadding=0 cellspacing=0 ><br /><tr><br /><td valign='top' width=180><br /><table><br /><tr><td style='text-align:center; background-color:#EEEEEE'>Applet</td></tr><br /><tr><td><br /><applet code="JSHelloWorld2.class"<br />width="180" height="180" MAYSCRIPT style="border-width:0;" name="jsap" id="jsap"><br /></applet> </td></tr><br /></table><br /></td><br /><td valign='top' width=180><br /><table width=180><br /><tr><td style='text-align:center; background-color:#EEEEEE'>JavaScript</td></tr><br /><tr><td><textarea style='width:180px; height:150px' name='txt1' id='txt1'>Type and click!</textarea></td></tr><br /><tr><td align='center'><input type=button value='Update applet' onClick='updateApplet()'></td></tr><br /></table><br /></td></tr><br /></form><br /></body><br /></html></code></p> <p>The <code>updateWebPage</code> 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.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_DfLhw9cF2KkoZgbTEhHDMqYF7kKeyThGO_vFlTwaalj4s-HWLJsfFjNnPj4kgm1r5dZlHQXGCmfUyQlJ5ap96IG3fUES31NMw2QnD3w6Teg0Qyp_Lwg16LysPF-56P3fYm8UFRPVNlw/s1600/pic31.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 311px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_DfLhw9cF2KkoZgbTEhHDMqYF7kKeyThGO_vFlTwaalj4s-HWLJsfFjNnPj4kgm1r5dZlHQXGCmfUyQlJ5ap96IG3fUES31NMw2QnD3w6Teg0Qyp_Lwg16LysPF-56P3fYm8UFRPVNlw/s320/pic31.JPG" alt="" id="BLOGGER_PHOTO_ID_5649160131728974818" border="0" /></a></p> <p>This is very similar to the page used to demonstrate <a href="http://jhippjava.blogspot.com/2011/09/javascript-to-applet-communication.html"> Javascript to Applet Communication</a> 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).</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxvWARqFTpltOfgz2ViZcOxFgVEc5aWbR6Yzx5c8ZNZS2QAF5y1XuazNKvIbWq-AdO-c-Xx1miwEYJFv6N_whJ40RkNinbOPJJbHZUn3as4G-NjzrqiXuzXn4kcOkQykxExqxmNMbAh4w/s1600/pic32.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 311px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxvWARqFTpltOfgz2ViZcOxFgVEc5aWbR6Yzx5c8ZNZS2QAF5y1XuazNKvIbWq-AdO-c-Xx1miwEYJFv6N_whJ40RkNinbOPJJbHZUn3as4G-NjzrqiXuzXn4kcOkQykxExqxmNMbAh4w/s320/pic32.JPG" alt="" id="BLOGGER_PHOTO_ID_5649160130288588098" border="0" /></a></p> <p>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.</p> <p>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 <a href="http://www.interactived.com/jartest.htm">my own applet</a>.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com1tag:blogger.com,1999:blog-8882010943472432760.post-22351730398299830862011-09-05T21:45:00.001-07:002011-09-05T21:45:44.339-07:00LiveConnect and JavaScript Wrappers<p>From the <a href="https://developer.mozilla.org/en/LiveConnect">LiveConnect page on the Mozilla web site</a>:</p> <p> <cite>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. </cite> </p> <p><cite>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 <code>document.applets.name.methodName()</code>).</cite></p> <p>From the <a href="https://developer.mozilla.org/en/JavaScript/Guide/LiveConnect_Overview"> LiveConnect Overview page</a> on the same site:</p> <div id="section_1"> <cite>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 <code>netscape.javascript.JSObject</code> and passed to Java.</cite><p><cite>When a JavaScript object is sent to Java, the runtime engine creates a Java wrapper of type <code>JSObject</code>; when a <code>JSObject</code> is sent from Java to JavaScript, the runtime engine unwraps it to its original JavaScript object type. The <code>JSObject</code> class provides an interface for invoking JavaScript methods and examining JavaScript properties.</cite></p></div> <p>The <a href="https://developer.mozilla.org/en/LiveConnect">LiveConnect page</a> 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 <a href="https://developer.mozilla.org/en/JavaScript/Reference">JavaScript Reference</a> page, but I could find no reference to LiveConnect on the page.</p>Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0tag:blogger.com,1999:blog-8882010943472432760.post-33887764670956424662011-09-04T21:25:00.000-07:002011-09-04T21:41:50.483-07:00Javascript to Applet Communication - Example 2I have found <a href="http://www.raditha.com/java/alert.php">another article</a> 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 <a href="http://jhippjava.blogspot.com/2011/09/java-appletjavascript-communication.html"> previous one</a>. <p> <code>import javax.swing.*;
<br />import netscape.javascript.JSObject;
<br />
<br />public class JSHelloWorld extends JApplet {
<br />JTextArea txt = new JTextArea(100,100);
<br />public JSHelloWorld() {
<br />txt.setText("Hello World");
<br />getContentPane().add(txt);
<br />}
<br />
<br />public void setText(String s)
<br />{
<br />txt.setText(s);
<br />}
<br />}</code></p> <p>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:</p> <p><code><html>
<br /><body>
<br /><script type="text/javascript">
<br />function updateApplet()
<br />{
<br />document.jsap.setText(document.forms[0].txt1.value);
<br />}
<br /></script>
<br /><form>
<br /><table border=0 align='center' cellpadding=0 cellspacing=0 >
<br /><tr><td valign='top' width=180>
<br /><table>
<br /><tr><td style='text-align:center; background-color:#EEEEEE'>Applet</td></tr>
<br /><tr><td><applet code="JSHelloWorld.class"
<br />width="180" height="180" MAYSCRIPT style="border-width:0;" name="jsap" id="jsap">
<br /></applet> </td></tr></table>
<br /></td><td valign='top' width=180>
<br /><table width=180>
<br /><tr><td style='text-align:center; background-color:#EEEEEE'>JavaScript</td></tr>
<br /><tr><td><textarea style='width:180px; height:150px' name='txt1'>Type and click!</textarea></td></tr>
<br /><tr><td align='center'><input type=button value='Update applet' onClick='updateApplet()'></td></tr>
<br /></table>
<br /></td></tr>
<br /></form>
<br /></body>
<br /></html></code></p> <p> This comes up as shown below.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjM1osdoyrfr3E6iMbYX2XbGorLkkJu0pjdGV9qkKfNOCP9Iwcp4tnr6p7TdHIyXdUHYYm1epV9pa_H4A76Gyl_P7tl2KU2Fh-_dP23Q_Gi4NrCQu9DvJ0NvzmEwApHnDfLRTQhHO34muE/s1600/pic21.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 311px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjM1osdoyrfr3E6iMbYX2XbGorLkkJu0pjdGV9qkKfNOCP9Iwcp4tnr6p7TdHIyXdUHYYm1epV9pa_H4A76Gyl_P7tl2KU2Fh-_dP23Q_Gi4NrCQu9DvJ0NvzmEwApHnDfLRTQhHO34muE/s320/pic21.JPG" alt="" id="BLOGGER_PHOTO_ID_5648727552204396002" border="0" /></a></p> <p>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.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxCHHdvc6pKipbg6Ca6U9U9ox-XPK664a7YSn2L52pQkDx_JsIi8epLJjKmO6NdhQsA4obBM4Xr3cvVKLAR1chzS1vz_QV8q3XmTyHLx6xO-9TGxElvJBFi5PbSWO7mWtYxchXvaAIyGU/s1600/pic22.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 311px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxCHHdvc6pKipbg6Ca6U9U9ox-XPK664a7YSn2L52pQkDx_JsIi8epLJjKmO6NdhQsA4obBM4Xr3cvVKLAR1chzS1vz_QV8q3XmTyHLx6xO-9TGxElvJBFi5PbSWO7mWtYxchXvaAIyGU/s320/pic22.JPG" alt="" id="BLOGGER_PHOTO_ID_5648727551993984210" border="0" /></a></p><p>Full original versions of the code can be downloaded from <a href="http://www.raditha.com/java/mayscript.php">this page</a>.</p> Jonathanhttp://www.blogger.com/profile/15714263243558911815noreply@blogger.com0