Link to home
Start Free TrialLog in
Avatar of JP_TechGroup
JP_TechGroupFlag for United States of America

asked on

JS function to run with PHP query results

Let's say I have a webpage with a photo gallery.
Now let's say that photo gallery has its image file names and locations stored in a database.
Now lets say that I want to run a query in PHP against that database using the gallery id to get the pictures which should show up.
Further suppose I have JS function which writes the elements to html to hold the images based upon the results of the query.

How do we take the php query results, cycle them and run the js to insert them in HTML?

JS function here. Writes the elements under the a div named Gallery wrap.

function thumbnailAdd(dname, elid) {
			var	pth = "http://somedomain.com/"+elid+"/"+dname;
			var tnpath = "http://somedomain.com/"+elid+"/tn/tn_"+dname;
				  $("#tgal").append(
				  '<div class="column">'+
			'<div class="inner">'+
					'<a class="zooming" href='+pth+' title='+dname+'>'+
					'<div class="img-wrap">'+
						'<img src='+tnpath+' alt="Image gallery" title='+dname+' class="mfp-fade>'+
					'</div>' +
					'</a>'+
			'<select class="form-control selectpicker" name="x" data-live-search="true" style="position:relative; top:1px;"><option>test</option></select>'+						
			'</div>'+			
		'</div>'
				  );
				}				

Open in new window


Here is the PHP which tries to get the dbase results and loop the JS function.
		$r = getGallery($elID);
			while ($rw = $r->fetch(PDO::FETCH_ASSOC)) { 
	echo '<script type="text/javascript"> call thumbnailAdd('.$rw["ARTIFACT_NAME"].', '.$elID.')</script>';
											}
		$r = NULL;

Open in new window


This does not work and I don't understand why. Thanks.
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of JP_TechGroup

ASKER

Thank you for your response. I am afraid you are assuming a level of JS expertise I simply do not have. I am a client side app developer that got landed with this project. As such there are holes in my knowledge which become extremely frustrating. I frequently encounter an an answer which assumes knowledge pieces I lack... such is this case!

I think I understand your code, but what calls the script in HTML and set the ball in motion?

I should add, no frustration with you, sir! Count it to a day of bad answers on Google, before I finally asked here. Thanks again!
The best way to learn is to ask - so keep asking - that is what we are here for.

What kicks it off

$(function() {

Open in new window

This is a jQuery document load handler. In plain JavaScript we would do something like this
window.addEventListener('load', function() {
   // code to run after document load
});

Open in new window

The loading of a web page involves many asynchronous operations. The browser is rendering HTML. When it finds a script tag with a src (that is not set to load async) it downloads the script and immediately runs the script in the file. For in page script it executes that immediately and then continues with loading the page. At the same time it has background processes fetching images and other resources.
If a <script> tag is encountered that tries to call a JS function that has not loaded yet OR tries to operate on an element that has not been rendered - an error will be thrown and whatever that script was meant to do will not happen. This is most likely what was happening with your script.

If we try to do things with the page before the page is ready we are going to get unpredictable results. That is what the 'load' event is for. It is fired when the document has finished being processed and all the resources are in place.

In jQuery (which is just some JavaScript functions that make working with the DOM a bit easier) we wrap the code that we want to run after page load in the following
$(function() {
   // code here
});

Open in new window

Anything inside that block will only be executed once the document has loaded.
The next bit of the code is also jQuery - $.get() this makes an AJAX (get) call to the specified URL.
An AJAX call is mostly the same as typing a URL into your browser and executing it (or posting a form) except it is done by script in the background without affecting your page.
When the $(function() fires -  the $.get() inside will call the images.php script.
It will wait (asynchronously) for the script to complete and when it does it calls the callback passed in as the second parameter with the results of the call as the parameter. The 'JSON' parameter is just to tell jQuery we are expecting a JSON return. jQuery will then do a JSON.parse() on the data for you so  that what is passed to the callback is a JavaScript object (not a string).

From there the rest is easy and analogous to what you were trying to do. Instead of writing out a function call for each image on the PHP side, in the callback we loop over the results from the images.php and for each item found call the function.

All that images.php has to do is output an array of objects with a dname and elID property - the rest will be done in the browser.

The code is pretty much good to go as is - all you need to add is the jQuery library.
That is a superb explanation and very comprehensible, thank you. With HTML being somewhat procedural, I catch myself falling out of object oriented thinking.

I have modified as you suggested. JQuery is added and under the declaration, I have my function, followed by your JQuery script.
I created the php file and forced the elID variable (it is called by an action on the page and populated in PHP with $_GET near the top of the body tag to 2 as there are records which match this ID and will produce a valid query result. I have updated the images.php file location to my includes folder in the script. images.php responds as expected when called via url. (see below)
[{"dname":"324f08c1b3b5b707de04ce0ab7645a95.jpg","elid":"2"},{"dname":"02b14573546a5f21226869bdc48a24c0.jpg","elid":"2"},{"dname":"b0dadc49f7ca0b2198446e17ab184da8.jpg","elid":"2"},{"dname":"031f837312676885117b5f122a176239.jpg","elid":"2"},{"dname":"1dcd8c2c208e596b2afb49f4d1f70fb3.jpg","elid":"2"}]

Open in new window


Reload the page and nothing happens. The JQuery does not appear to fire. image.php is not running.

<script src="assets/libs/jquery/jquery-1.11.1.min.js"></script> /verified accessible at this location

<script>

		function thumbnailAdd(dname, elid) {
			var	pth = "http://somedomain.com/"+elid+"/"+dname;
			var tnpath = "http://somedomain.com/"+elid+"/tn/tn_"+dname;
				  $("#tgal").append(
				  '<div class="column">'+
			'<div class="inner">'+
					'<a class="zooming" href='+pth+' title='+dname+'>'+
					'<div class="img-wrap">'+
						'<img src='+tnpath+' alt="Image gallery" title='+dname+' class="mfp-fade>'+
					'</div>' +
					'</a>'+
			'<select class="form-control selectpicker" name="x" data-live-search="true" style="position:relative; top:1px;"><option>test</option></select>'+						
			'</div>'+			
		'</div>'
				  );
				}	
				
				$(function() {
		  $.get('assets/includes/images.php', function(resp) {
			resp.forEach(function(i) {
			  thumbnailAdd(i.dname, i.elid);
			});
		  }, 'JSON');
		});
</script>

Open in new window


No js errors on the page.
Just realized I have an old version of JQuery.

$(window).on('load', function() {
Caused the event to fire and all acts as expected.
Last question, is
var qr = 'assets/includes/images.php/?id='+<?php echo $elID; ?>;
acceptable for the passing of the elID variable into the JQuery function? It's ugly but it works.
Thanks again.
You are welcome.
var qr = 'assets/includes/images.php/?id='+<?php echo $elID; ?>;

Open in new window

If you are referring how to access eID, here is what I do in such situations

somewhere in my script I do this
echo <<< HTML
   <script>var $__eID={$eID};</script>
HTML;

Open in new window

Now in my JavaScript $__eID is defined at the global level and can be used wherever it is needed.

With jQuery your document load can also be this
$(function() {
});

Open in new window

It is a short hand identical way of doing it.
Thank you, I will do php vars that way when I need them in a script for some reason.

As I mentioned, $funtion() does not run, but adding the .on parameter does. I presume it is the old JQuery library I am using?
$funtion() does not run
Note it is not $function
It is
$(function() {
});

Open in new window

In other words the function name is $. To this you are passing a function that jQuery will run on document load.
$ is a shorthand for jQuery - so you could do this
jQuery(  
  function() {
    // Anything inside here will run on document load.
  }
);

Open in new window

If that makes it more clear.
Typo on my part. Your suggestion does not run.

In digging deeper it appears the NoConflict is set in numerous places in multiple libraries. I believe this would cause the issue I am having?
All I know is, the only call that works is $(window).on('load', function() {});

It is playing hell with what I am trying to do and I have been banging my head for days thinking I was missing something.

Listening for events does not work either, at least not in the way I know how to do it. What could be going on here?
Do I need to scrap this whole project I was left to complete and start over? It is based on a template.
if no conflict is set then do this
jQuery(function($) {
   // now you can use the $ to refer to any jQuery function inside this code block. The reason is 
   // when jQuery calls the onload function it passes itself to it. So by naming the parameter 
   // $ - you can use the standard jQuery syntax withing the function ready block
});

Open in new window

The code is good (I know this for a fact) - if it is not working then that is an implementation problem. Try the above and if it does not work post back with how you implemented and we can go from there.
That does not work either.
Here. An example that couldn't be simpler.
a button
<a id="myid" href="#"><i class="icon-trash-1"></i></a>
script
	jQuery(function($) {
 $(function() {
		$('myid').click( function() {
				alert('hi');
		});
 });
	};

Open in new window


Nothing.
Ok many things wrong
1. You have a document ready INSIDE a document ready
2. Your selector for your id is missing a # prefix (indicating an ID - as opposed to a '.' which indicates a class)
3. You are binding to an <a> which has a default action that is not desirable - you will end up with a '#' in your URL string. You  will need to prevent that either by returning false from the event handler or calling preventDefault() on the event object.
Here is what your code should look like
// This is how you define a document ready function in jQuery with no-conflict enabled (refer earlier posts above)
jQuery(function($) {
   // ID selectors are prefixed by a '#'
   $('#myid').click(function(e) {
      // prevent default <a> behaviour
      e.preventDefault();
      alert('Hi There!');
   });
});

Open in new window

Wow, I am working off some bad examples, it seems. Thank you for bearing with me. By the way I marked this as answered... all the rest is secondary and just me taking the chance to pick an experts brains!

SO, your example does not fire either, that is until I remove the ref to jquery 1.11.1 and ref 3.4.1 instead.
I read this (and at least some of my other issues) as improved functions in the new library.
$(function() ({}): now behaves as expected. The console shows a number of errors, but they don't appear to affect the site.
1.11 is old 1.12 is the latest in version 1 but is rejected by some security testers due to a cross site scripting issue.

Just for fun I put this sample together using jQuery 1.11.1
http://www.marcorpsa.com/ee/t3749.html
Works fine (tested it back to 1.2.3 of jQuery - works perfectly)
The sample has code listings in the tabs at the bottom if you want to take a look.
Thanks again for your help. There was a js page loading which I did not catch. All is well now.