Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 03-14-2013, 09:23 PM   PM User | #1
geno11x11
New Coder

 
Join Date: Feb 2013
Posts: 19
Thanks: 1
Thanked 0 Times in 0 Posts
geno11x11 is an unknown quantity at this point
Event Handlers: Trouble using HTML, PHP, Javascript & DOM

Hello everyone, I'm having a conceptual breakdown... I am stuck on event handlers. The task is to click a table row (or just a cell if necessary) to trigger a routine to break out the record to display the full record set, update it, or delete it. I have tried a whole variety of traditional and modern event handlers and listeners, but as you have probably already guessed, nothing has worked. I have broken it down to the simplest possible in-element handler but still no joy.

I suspect that the problem may be the order of processing; I have learned that PHP is the first in order, so perhaps attaching event handlers to echoed HTML won't work. I'm grasping at straws here, and I hope someone can clear up the issue. I would like an explanation of the theory, not just a code fix, so the proverbial light will illuminate.

The end code will be much more involved, but here is the most basic version to simply get the onclick handler to function with a simple 'hello' alert. Why doesn't it work?

Code:
<?php
class PNS 
{
function displayPage($db,$num)
	{
	$line=1;
	echo "<div id='wrap'>";	
	echo "<table id='myTable' align='center'>";
	echo "<tr>";

	$sql="SELECT * FROM Complex ORDER BY Name" . $num;  
	$result = $db->query($sql);
	for($i=1;$i<=4;$i++)   				

//   Column headings: The MySQL table column names
	{
		$column=$result->fetch_field_direct($i);
		$colName=$column->name;
		echo "<th>$colName</th>";
	}
		echo "</tr>";
	
		
		while($row = mysqli_fetch_assoc($result))		//Get Rows - Display in column format
		{
		
//  Table row data in table columns

		echo "<tr id='myRow'><td class='link' id='myCell'><a href='#' onclick='alert('hello!')>".$row['Key_ID']." - ".$row['Name']."</td>
								<td class='link'><a href='#1'>".$row['Address1']."</td>
								<td class='link'><a href='#1'>".$row['Address2']."</td>
								<td class='link'><a href='#1'>".$row['City']." ".$row['State']." ".$row['Zip']."</td></tr>";
		$line++;
		}	

echo "</table></div>";

	}		//end of function
}			//end of class pagination
?>
geno11x11 is offline   Reply With Quote
Old 03-14-2013, 09:25 PM   PM User | #2
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,448
Thanks: 0
Thanked 496 Times in 488 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
The browser only sees the HTML and the JavaScript so you need to look at whet that looks like in order to work out how the JavaScript will interact with the HTML.

The PHP is irrelevant unless you set up an ajax call in JavaScript that calls a completely separate PHP script on the server to perform additional server side processing after the page has loaded.
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/
felgall is offline   Reply With Quote
Old 03-14-2013, 09:41 PM   PM User | #3
xelawho
Senior Coder

 
xelawho's Avatar
 
Join Date: Nov 2010
Posts: 2,437
Thanks: 52
Thanked 453 Times in 451 Posts
xelawho will become famous soon enoughxelawho will become famous soon enough
you may well solve your problem (or at least give us a shot at solving it) by posting the rendered html. Once your page has loaded, just view source and copy/paste the html here. fwiw, I would be much more inclined to let the php set up the html and then add an event listener with javascript afterwards
xelawho is offline   Reply With Quote
Old 03-14-2013, 09:49 PM   PM User | #4
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,168
Thanks: 59
Thanked 3,993 Times in 3,962 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
It doesn't work because you don't understand where the limits of your quoted strings are, both in PHP and in the resultant HTML.

Start with this:
Code:
echo "<tr id='myRow'><td class='link' id='myCell'><a href='#' onclick='alert('hello!')>".$row['Key_ID']." - ".$row['Name']."</td>
The first PHP quotes string there is this:
Code:
"<tr id='myRow'><td class='link' id='myCell'><a href='#' onclick='alert('hello!')>"
So what that writes out to the HTML is then this:
Code:
<tr id='myRow'><td class='link' id='myCell'><a href='#' onclick='alert('hello!')>
So now let's find all the quoted strings in that HTML. I will color them red.
Code:
<tr id='myRow'><td class='link' id='myCell'><a href='#' onclick='alert('hello!')>
OOPS!!! Look at that last one. Is 'alert(' *REALLY* the string you want?

Of course not.

What you *need* is something like onclick='alert("hello!")'

And to do that, you must somehow get that "hello" into your PHP code.

But that's pretty easy:
Code:
"<tr id='myRow'><td class='link' id='myCell'><a href='#' onclick='alert(\"hello!\")'>"
Now, that's all well and good. But the real problem is that you, like most PHP users, seem addicted to creating the big long echo commands.

And in the process of doing this you have created some VERY ILLEGAL HTML! Just for example, you have several <a> tags with no matching </a> tags!!!

Why?

Wouldn't it be simpler and MORE READABLE to do this?
Code:
while($row = mysqli_fetch_assoc($result))
{
?>		
    <tr id="myRow">
        <td class="link" id="myCell">
            <a href="#" onclick="alert('hello!')">
                <?php echo $row['Key_ID'] . " - " . $row['Name']; ?>
            </a>
       </td>
       <td class="link">
           <a href="#1">
               <?php echo $row['Address1']; ?>
           </a>
       </td>
       <td class="link">
           <a href="#1">
               <?php echo $row['Address2]; ?>
           </a>
       </td>
       <td class="link">
           <a href="#1">
               <?php echo $row['City'] . ", " . $row['State'] . " " . $row['Zip']; ?>
           </a>
       </td>
    </tr>
<?php
    $line++;
}	
?>
And in the process of doing this, we find several more things wrong:

(1) What is the point of all those <a href="#1"> links? If you click on those, they won't do anything useful.
(2) ID's *MUST* be UNIQUE on an ENTIRE HTML PAGE. Here, you will be giving every row the same id of "myRow" and every first td cell the same id of "myCell". BOGUS.
(3) If you were to give your <tr> a class, then you woudn't have to assign the class to each and every <td>. (Not an error; just an observation about more compact HTML/CSS.)

************

SO....

As Felgall said, the PHP code is irrelevant to what the browser sees and what the browser needs.

Clearly, your first task is to create *LEGAL* HTML.

To that end, the best debugging tool you can use is also the simplest:
(1) Bring up your page in your browser.
(2) Click on the VIEW menu of your browser (or equivalent)
(3) Click on the SOURCE or PAGE SOURCE menu item.
Presto. You will be seeing the HTML *as the browser sees it*. And then you can start looking for your HTML errors.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Users who have thanked Old Pedant for this post:
geno11x11 (03-14-2013)
Old 03-14-2013, 09:54 PM   PM User | #5
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,168
Thanks: 59
Thanked 3,993 Times in 3,962 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
By the by, not relevant to JS or HTML coding, but...

It's a bad idea to do this:
Code:
	$sql="SELECT * FROM Complex ORDER BY Name" . $num;
(and what is the $num there for, by the by?)

You really should never use SELECT * if you can help it.

In this case, you clearly know the fields from the table that you need for this page, so:
Code:
$sql = "SELECT Key_ID, Name, Address1, Address2, City, State, Zip "
     . " FROM Complex ORDER BY Name";
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 03-14-2013, 10:02 PM   PM User | #6
Airblader
Regular Coder

 
Join Date: Jan 2013
Location: Germany
Posts: 348
Thanks: 3
Thanked 43 Times in 43 Posts
Airblader can only hope to improve
It's also a really bad idea not to sanitize any kind of variable you put into a query (independent of whether you need $num in this case or not). Better yet, use prepared statements.
Airblader is offline   Reply With Quote
Old 03-14-2013, 10:51 PM   PM User | #7
geno11x11
New Coder

 
Join Date: Feb 2013
Posts: 19
Thanks: 1
Thanked 0 Times in 0 Posts
geno11x11 is an unknown quantity at this point
The light is shining brightly! I am embarrassed to reveal the total amount of time I have spent on this issue (hint - measured in days), but in just a few minutes my problem is solved and I have learned an invaluable troubleshooting technique.

The trouble, revealed in the page source, was glaringly obvious. As several contributors pointed out but Old Pedant broke out the most clearly, my use of single and double quotation marks was the culprit. How many times I have repeated this error......

I am in the process of digesting the rest of the corrections, suggestions, and remarks, but for now my heartfelt thanks to all who contributed!!
geno11x11 is offline   Reply With Quote
Old 03-14-2013, 11:18 PM   PM User | #8
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,168
Thanks: 59
Thanked 3,993 Times in 3,962 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
I'd like to suggest some ways to proceed.

For starters, let's get rid of *ALL* your <a> tags. I can't see them doing anything useful.

And then let's identify each row uniquely and make each row clickable.
Code:
?>
<table id="myTable">
<?php
while($row = mysqli_fetch_assoc($result))
{
    $id = $row["Key_ID"];
?>		
    <tr id="ROW<?php echo $id;?>">
        <td class="link">
                <?php echo $row['Key_ID'] . " - " . $row['Name']; ?>
       </td>
       <td class="link">
               <?php echo $row['Address1']; ?>
       </td>
       <td class="link">
               <?php echo $row['Address2]; ?>
       </td>
       <td class="link">
               <?php echo $row['City'] . ", " . $row['State'] . " " . $row['Zip']; ?>
       </td>
    </tr>
<?php
    $line++;  // ??? what is this for?  I don't see it doing anything useful???
}	
?>
</table>
And then, at the very bottom of your page, you put this (and not in <?php...?> tags)
Code:
<script type="text/javascript">
(
  function( )
  {
      var tbl = document.getElementById("myTable");
      var trs = tbl.rows;
      for ( var t = 0; t < trs.length; ++t )
      {
          var tr = trs[t]; // one row
          if ( tr.id.substring(0,3) == "ROW" )
          {
              tr.onclick = pickRow;
          }
      }

      function pickRow( )
      {
          var keyid = this.id.substring(3); // get the ID of the <tr> past the "ROW"
          alert( "You clicked on the row with keyid " + keyid );
      }
  }
)();
</script>
</body>
</html>
Now, eventually, you will replace the alert( ) in that code with something that will actually make use of the keyid value. For example, you might then use AJAX to send that id back to the PHP server to get more information about that particular id.

But this will get your started.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 03-31-2013, 08:13 PM   PM User | #9
geno11x11
New Coder

 
Join Date: Feb 2013
Posts: 19
Thanks: 1
Thanked 0 Times in 0 Posts
geno11x11 is an unknown quantity at this point
JS to execute php script passing variable

Hello everyone on Easter morning...

Since my last post, I have been busy reviewing DOM and javascript tutorials which have done quite a lot to clarify things. After some additional coding to my project, I am of the opinion that the remaining fog lies in the area of passing variables and control between the html, javascript, and php layers. So, I am stuck once more, having broken Old Pedant's function that was working beautifully earlier....

The task: Take the record number of the clicked row and pass that value to a new php script [displayRec.php], and load the record for display, edit & save, or delete. Ideally, I would like the new window to overlay the window of the clicked row, and when work is done, return to the previous window for another selection.

I tried AJAX [ajax_post( )] to transfer the value of keyid to displayRec.php but without success, and that code has broken the original script. Some AJAX response code is present for testing purposes, but that is not needed.

My questions:
  • Why did ajax_post() break the original script?
  • Using js, how do I execute displayRec.php while passing keyid?

The modified script

Code:
<script type="text/javascript" src="js/ajax.js">
(
	function( )
	{
		var tbl = document.getElementById("myTable");
		var trs = tbl.rows;
		for ( var t = 0; t < trs.length; ++t )
		{
			var tr = trs[t]; // one row
			if ( tr.id.substring(0,3) == "ROW" )
			{
				tr.onclick = pickRow;
			}
		}

		function pickRow( )
		{
			var keyid = this.id.substring(3); // get the ID of the <tr> past the "ROW"
			alert( "You clicked on the row with keyid " + keyid );
			ajax_post(keyid);
 		}
		function ajax_post( )
		{
			var ajax = ajaxObj("POST", "displayRec.php");
			ajax.onreadystatechange = function() 
			{
				if(ajaxReturn(ajax) == true) 
				{
					alert(ajax.responseText);
					//document.getElementById("status").innerHTML = response;
				}
			}
		ajax.send("keyid=" . keyid );
		}

	}
)();

</script>

The script, displayRec.php:

Code:
<?php
//<!-- ******** displayRec.php ******** -->
$sample=0;
if(isset($_POST["keyid"])){
    echo $_POST["keyid"]." is ".$_POST["keyid"];
exit();
}
echo "displayRec worked!";
?>

As always, I want to understand the fix so please explain your suggestions in detail, and theory, concepts, and references are always welcome.

Thanks again and happy Easter
geno11x11 is offline   Reply With Quote
Old 04-01-2013, 03:52 AM   PM User | #10
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,168
Thanks: 59
Thanked 3,993 Times in 3,962 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
I don't know what is in your "js/ajax.js" file, but that AJAX code looks wrong, to me. (It could be right, depending on what's in "ajax.js", but it just *FEELS* wrong.)

To test my theory, temporarily comment out that js/ajax.js inclusion and try coding it by hand:
Code:
    function ajax_post( )
    {
        var ajax = window.XMLHttpRequest != null 
                 ? new XMLHttpRequest() 
                 : new ActiveXObject("Microsoft.XMLHTTP");
        ajax.open( "POST", "displayRec.php", true );
        ajax.onreadystatechange = 
           function( )
           {
               if (ajax.readyState==4 && ajax.status==200)
               {
                   alert("Answer from AJAX: " + ajac.responseText );
               }
           }
        ajax.send("keyid=" + keyid );
    }
But in the process of writing that I saw your goof.

How hard will you kick yourself?
Code:
	ajax.send("keyid=" . keyid );
Hmmm...since when does JavaScript use a period to mean string concatenation? Too much PHP on the brain? <grin/>

On the other hand, look how small my AJAX code is. Is there really any need for "ajax.js"?

}
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 04-01-2013, 08:23 PM   PM User | #11
geno11x11
New Coder

 
Join Date: Feb 2013
Posts: 19
Thanks: 1
Thanked 0 Times in 0 Posts
geno11x11 is an unknown quantity at this point
Script still broken --

Whatever the cause, the problem is sticky. The odd part is that the entire script is broken - even the alert in pickRow( ). I removed the Ajax.js source file and substituted Old Pedant's script mods with a slight correction:

Code:
                   alert("Answer from AJAX: " + ajac.responseText );
I note that in Old Pedant's script, ajax.responseText returns the echo back to the original script. Is it possible to execute displayRec.php, passing keyid via $_POST, as an HTML POST form would behave, or must it always be returned?

Full script:
Code:
<script type="text/javascript">
(
	function( )
	{
		var tbl = document.getElementById("myTable");
		var trs = tbl.rows;
		for ( var t = 0; t < trs.length; ++t )
		{
			var tr = trs[t]; // one row
			if ( tr.id.substring(0,3) == "ROW" )
			{
				tr.onclick = pickRow;
			}
		}

		function pickRow( )
		{
			var keyid = this.id.substring(3); // get the ID of the <tr> past the "ROW"
			alert( "You clicked on the row with keyid " + keyid );
			ajax_post(keyid);
 		}
	    function ajax_post( )
		{
			var ajax = window.XMLHttpRequest != null 
					 ? new XMLHttpRequest() 
					 : new ActiveXObject("Microsoft.XMLHTTP");
			ajax.open( "POST", "displayRec.php", true );
			ajax.onreadystatechange = 
			   function( )
			   {
				   if (ajax.readyState==4 && ajax.status==200)
				   {
					   alert("Answer from AJAX: " + ajax.responseText );
				   }
			   }
			ajax.send("keyid=" + keyid );
		}
)();

</script>
displayRec.php

Code:
<?php
//<!-- ******** displayRec.php ******** -->
if(isset($_POST["keyid"]))
{
    echo "keyid=" . $_POST["keyid"];
//	exit();
}
echo "displayRec functioning!";
?>
geno11x11 is offline   Reply With Quote
Old 04-01-2013, 09:15 PM   PM User | #12
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,168
Thanks: 59
Thanked 3,993 Times in 3,962 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
My head hurts.
Quote:
ajax.responseText returns the echo back to the original script. Is it possible to execute displayRec.php, passing keyid via $_POST, as an HTML POST form would behave, or must it always be returned?
WHAT? I don't understand the question, at all.

We *ARE* using AJAX to execute displayRec.php. We *ARE* passing the keyid via $_POST. In what what way is this *NOT* what an HTML POST would do?

I don't know what "returns the echo" means. What exactly are you seeing in that alert of the responseText??

I do see I missed one thing in my AJAX code. I forgot to set the Content-Type to allow POST. Is that the problem?

It should be
Code:
	    function ajax_post( )
		{
			var ajax = window.XMLHttpRequest != null 
					 ? new XMLHttpRequest() 
					 : new ActiveXObject("Microsoft.XMLHTTP");
			ajax.open( "POST", "displayRec.php", true );
			ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
			ajax.onreadystatechange = 
			   function( )
			   {
				   if (ajax.readyState==4 && ajax.status==200)
				   {
					   alert("Answer from AJAX: " + ajax.responseText );
				   }
			   }
			ajax.send("keyid=" + keyid );
		}
Apologies if that's the only problem. I use GET for virtually all my AJAX stuff, so I tend to forget about content-type (not used with GET).
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 04-04-2013, 09:53 PM   PM User | #13
geno11x11
New Coder

 
Join Date: Feb 2013
Posts: 19
Thanks: 1
Thanked 0 Times in 0 Posts
geno11x11 is an unknown quantity at this point
I will try to clarify my earlier question.

Old Pedant's ajax_post function sends keyid via $_POST to displayRec.php, accepts the returned value displayRec.php via ajax.responseText, then displays a message in an alert box. In this case, returning data from displayRec.php is not useful. Instead, I want to execute displayRec.php independently of the calling file to begin processing the record associated with keyid, in the same way that would occur if it were sent using POST or GET via a FORM. Is there an AJAX method or another way to accomplish this?

Lastly, there is still a problem with the script as the alert box does not activate when the row is clicked. I presume ajax_post( ) mucked things up as pickRow( ) stopped working after it was added.

Last edited by geno11x11; 04-05-2013 at 02:07 AM..
geno11x11 is offline   Reply With Quote
Old 04-05-2013, 12:37 AM   PM User | #14
geno11x11
New Coder

 
Join Date: Feb 2013
Posts: 19
Thanks: 1
Thanked 0 Times in 0 Posts
geno11x11 is an unknown quantity at this point
Update: All functions are now working. The problem was that keyid needed to be passed between pickRow() and ajax_post():

Code:
ajax_post(keyid);
Code:
function ajax_post(keyid) {
Now the problem of executing a php file with AJAX ... anyone have that solution?
geno11x11 is offline   Reply With Quote
Old 04-17-2013, 09:19 PM   PM User | #15
geno11x11
New Coder

 
Join Date: Feb 2013
Posts: 19
Thanks: 1
Thanked 0 Times in 0 Posts
geno11x11 is an unknown quantity at this point
For anyone following this post and looking for the answer posed above, the solution turned out to be quite simple. I discovered that displaying output using alert() returns control to the calling program.

Code:
function ajax_post(keyid)
{
	var ajax = window.XMLHttpRequest != null 
			 ? new XMLHttpRequest() 
			 : new ActiveXObject("Microsoft.XMLHTTP");
	ajax.open( "POST", "displayRec.php", true );
	ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
	ajax.onreadystatechange = function( )
	   {
			if (ajax.readyState == 4 && ajax.status == 200)
			{
			
				alert("Answer from AJAX: " + ajax.responseText );
			}
	   }
	ajax.send("keyid=" + keyid );
}

To transfer control to another php script, use document.write() instead. I expect that multiple scripts can be daisy-chained together in this fashion:

Code:
function ajax_post(keyid)
{
	var ajax = window.XMLHttpRequest != null 
			 ? new XMLHttpRequest() 
			 : new ActiveXObject("Microsoft.XMLHTTP");
	ajax.open( "POST", "displayRec.php", true );
	ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
	ajax.onreadystatechange = function( )
	   {
			if (ajax.readyState == 4 && ajax.status == 200)
			{
			
				display=ajax.responseText;
//				alert(display);
				document.write(display);
//				alert("Answer from AJAX: " + ajax.responseText );
			}
	   }
	ajax.send("keyid=" + keyid );
}



Conclusion: Another thanks to all who helped along the way. I have learned a shipload about javascript in this one post alone. In large part due to this forum, my project is now moving along at a regular pace and is taking form nicely. Feel free to comment further, but I am calling this post a wrap!
geno11x11 is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 03:31 AM.


Advertisement
Log in to turn off these ads.