Jump to content
Larry Ullman's Book Forums
Sign in to follow this  
another_noob

Passing Php Variables To A Javascript Function

Recommended Posts

In the past, I relied on inline event handlers to pass PHP variables to my javascript functions. I am trying to get away from that and I want to use the techniques in this book. I am struggling with the following trivial code example that passes a PHP variable that represents the record id of the row in a HTML table. For example, here is my HTML row with the inline handler:

<tr id="part_row" onclick="getPartID(<?php echo $row['part_id'];?>)">

And here is the trivial javascript function that is called:

function getPartID(id){
	alert(id);
}

Pretty simple, click a row  in the HTML table and get an alert with the record id of the corresponding part in the HTML table row. Progressive enhancement aside, how do I do this exact thing with "Modern Javascript"? If I missed something in the book that explains this, point me to the page number so I can digest it that way. If it is not explained (or something similar), could someone explain how this is done. Solving this trivial example will go a long way in me wrapping my brain around this new way of using javascript. Thanks.

Share this post


Link to post
Share on other sites
There are a couple of ways to approach this, and which one is better depends on your implementation.

 

For starters, I'm not sure what an id attribute value of part_row is for, but I suspect that you are using the same ID for multiple HTML elements. If so, you shouldn't, as that's not valid HTML. You might be better to write HTML as follows:

 



<tr id="part_id_<?php echo $row['part_id']; ?>">


 

Assuming $row['part_id'] is always a number, you'll get things like the following:

 



<tr id="part_id_1">
<tr id="part_id_12">
<tr id="part_id_125">
<tr id="part_id_53">
<tr id="part_id_5">
...


 

Then somewhere below that in your document, you'd want the following JS:

 



var trs = document.getElementsByTagName('tr'),
  i,
  len;


for (i = 0, len = trs.length; i < len; i += 1) {
  
  trs[i].onclick = getPartId;
  
}


function getPartId() {
  
  alert(this.id.substr(8));
  
}


 

this refers to the tr DOM object clicked on in the getPartId function, id is obviously the ID of that DOM object, and substr(8) grabs whatevers at the 9th character and after in the string assigned to the ID of the DOM object.

 

The other approach you can take is to make an Ajax request to a PHP script when the page first loads and get all the data you need and store it in a JS object for later use.

 

The choice is yours, and it really depends on how much data there is and what you want to do with it.

 

Does that answer your question?

Share this post


Link to post
Share on other sites

Thank you HartleySan. That gives me something to work with. I will refactor my code and see if I can get a grip on this. I will post back my experience. I appreciate your time and your  thorough explanation.

Share this post


Link to post
Share on other sites

No problem, and good luck.

As an added noted, another thing that is not valid HTML is an ID value that starts with a number. That's why I added the part_id_ part before the number. If you use the same prefix for the ID of similar elements, then you can always split the ID string at the same location and know that you will get the actual number you're looking for.

Share this post


Link to post
Share on other sites

This solution you provided not only helped me solve the problem, but helped me get a better understanding of how to get PHP data from HTML tables which I seem to need to do a lot.

 

I modified this example and now I am putting a button into each table row. When the user clicks the button, the contact_id value is passed to javascript and is used for data in an ajax call. This is all working as expected except I have to click a button twice the first time after the page is loaded. After that, one click is all that is necessary. I know the click event is working because I am getting the console.log('Reply button clicked') string in the Firebug console. The second click I get the string and the second log entry with the contact_id value. It appears that function getContactId() is not getting called on the initial click, but is getting called any click after that. 

 

Here is the relevant HTML button code:

<button id="contact_id_' . $contact_row['contact_id'] . '" class="reply_button">Reply</button>

And here is the relevant javascript:

$(document).ready(function() {
	
	// Watch for the reply button click:
	$('.reply_button').click(function() {
				
		var reply_btn = document.getElementsByClassName('reply_button'),  i, len;
		
		for (i = 0, len = reply_btn.length; i < len; i += 1) {
            		reply_btn[i].onclick = getContactId;
			console.log('Reply button clicked');
		}
		
		function getContactId() {
		    var contact_id = this.id.substr(11);
		    console.log('contact_id = ' + contact_id);
		}
		
		// Prevent the form from submitting:
		return false;

	}); // button click function
	
}); // Document ready.

It is not much different than the original post example...just using a button and jquery. I search SO for answers, but couldn't find a solution that seemed to apply in this case. I wrote the rest of the code for this and all is working except this silly problem. Any suggestions? Thanks.  

Share this post


Link to post
Share on other sites

another_noob, your code is pretty funky, actually.

 

You're setting up onclick event handlers for the reply buttons within the callback function that is called whenever a reply button is clicked on. In other words, your defining the same basic event handler for each button twice, but the second set of event handlers isn't set up until after a button is clicked on once.

 

Furthermore, your getContactId function is being defined within the callback function for the jQuery click method, which is why it's not called the first time you click on a button (because it's not even defined at that point).

 

There are any number of ways you can resolve these issues, but the simplest is to remove the second set of event handlers being set up, and to move the getContactId function definition outside of the callback function for the click method.

 

While not tested, the following code should work:

$(document).ready(function () {
  
  function getContactId() {
    
    console.log('contact_id = ' + this.id.substr(11));
    
    return false;
    
  }
  
  $('.reply_button').click(getContactId);


});

Share this post


Link to post
Share on other sites

Thank you HartleySan for the reply. Yeah, my code was a mess after looking at your solution. Just when I start to get a handle on javascript, I get tossed into a jQuery world and get a little confused. After playing around with the code a bit, this is the entire block of code that gets the contact_id from the corresponding button in the html table row, sends it off as data in an ajax request and fills a div in the html with a reply form. It all seems to work without error or having to click twice. If you see anything you would change, please let me know. i appreciate your time for helping me with this issue.

 

The script:

$(document).ready(function() {
	
		var reply_btn = document.getElementsByClassName('reply_button'),  i, len;
		
		for (i = 0, len = reply_btn.length; i < len; i += 1) {
                 reply_btn[i].onclick = getContactId;
		}
		
		function getContactId() {
			//store our php sent variable in a js variable
		        var contact_id = this.id.substr(11);
			console.log('contact_id = ' + contact_id);
			
			//Send the contact_id variable as data in our ajax call 
			var data = 'contact_id=' + contact_id;
			
			//ajax call with anonymous callback function
			$.post('getReplyForm.php', data, function(contact_reply_form){
				$('#reply_div').html(contact_reply_form);	
			});
			
			// Prevent the form from submitting:
			return false;
		}
		
}); // Document ready.

Share this post


Link to post
Share on other sites

While completely optional, since you're already using jQuery for your Ajax request, you might as well use it for everything else as well (e.g., setting up your event handlers).

 

Other than that, it seems fine. And if it works properly, that's what really matters.

Share this post


Link to post
Share on other sites

I decided to use a jQuery click handler just to keep it all one way or another as opposed to mixing vanilla javascript with jQuery.  I couldn't get a jQuery click function to work on the reply_btn array and using "bind" didn't work either. I could have left it alone, but I am trying to understand all this higher level stuff. I decided to go with an anonymous function here as well. Thanks again for your help, I learned a lot with this seemingly simple script. This is my script now and it is working fine.

$(document).ready(function() {
		
		var reply_btn = $('.reply_button'),  i, len;
		
		for (i = 0, len = reply_btn.length; i < len; i += 1) {
		
			//Add a click event listener and pass our function as an anonymous function
			reply_btn[i].addEventListener('click', function(){
			
			//store our php sent variable in a js variable
			var contact_id = this.id.substr(11);
					
			//Send the contact_id variable as data in our ajax call 
			var data = 'contact_id=' + contact_id;
			
			//ajax call with anonymous callback function. returns a HTML reply form
			$.post('getReplyForm.php', data, function(contact_reply_form){
				$('#reply_div').html(contact_reply_form);	
			});
			
			// Prevent the form from submitting:
			return false;
																	
			},false);
			
		}
}); // Document ready.

Share this post


Link to post
Share on other sites

I don't mean to keep beating this thread to death, but in my studies to understand why "click" or "bind" did not work for me, I found this info at the jQuery site  http://learn.jquery.com/events/handling-events/ I changed my code to use the "on" function and it works as expected. This is the first I have heard of the "on" function. I will post the revised code just in case anyone is following this thread.

 

The button that is in each HTML table row:

<td><button id="contact_id_' . $contact_row['contact_id'] . '" class="reply_button">Reply</button></td>

The javascript turned jQuery:

$(document).ready(function() {
		//This block of code gets the contact_id of the row when a reply button is clicked and makes an ajax call for the reply form
		var reply_btn = $('.reply_button'),  i, len;
		
		for (i = 0, len = reply_btn.length; i < len; i += 1) {
		
			//Add a click event listener and pass our function as an anonymous function
			reply_btn[i].on('click', function(){
			
			//store our php sent variable in a js variable
			var contact_id = this.id.substr(11);
			console.log('contact_id = ' + contact_id);
			
			//Send the contact_id variable as data in our ajax call 
			var data = 'contact_id=' + contact_id;
			
			//ajax call with anonymous callback function. returns a HTML reply form
			$.post('getReplyForm.php', data, function(contact_reply_form){
				$('#reply_div').html(contact_reply_form);	
			});
			
			// Prevent the form from submitting:
			return false;
																	
			});
			
		}
}); // Document ready.
  • Upvote 1

Share this post


Link to post
Share on other sites

Yes the 'on' function is very useful indeed it can bind the events you have to newly formed elements of the page. If you don't use that you will have to add the event handlers again to each of the elements you added events to at your initial page setup.

Share this post


Link to post
Share on other sites

I think "click" is the old jQuery way of handling clicks, and "on" is the new way. "on" seems to offer a more consistent interface for the entire spectrum of JS event handlers.

Similarly, "bind" was used for less common event handlers that didn't have their own custom method call (like "click"), but that's the old way.

 

Edit: And as Edward stated, "on" offers various advantages that "click" and "bind" do not.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...