JP_TechGroup
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.
Here is the PHP which tries to get the dbase results and loop the JS function.
This does not work and I don't understand why. Thanks.
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>'
);
}
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;
This does not work and I don't understand why. Thanks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
The best way to learn is to ask - so keep asking - that is what we are here for.
What kicks it off
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
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.
What kicks it off
$(function() {
This is a jQuery document load handler. In plain JavaScript we would do something like thiswindow.addEventListener('load', function() {
// code to run after document load
});
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
});
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.
ASKER
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)
Reload the page and nothing happens. The JQuery does not appear to fire. image.php is not running.
No js errors on the page.
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"}]
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>
No js errors on the page.
ASKER
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.ph p/?id='+<? php echo $elID; ?>;
acceptable for the passing of the elID variable into the JQuery function? It's ugly but it works.
Thanks again.
$(window).on('load', function() {
Caused the event to fire and all acts as expected.
Last question, is
var qr = 'assets/includes/images.ph
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; ?>;
If you are referring how to access eID, here is what I do in such situationssomewhere in my script I do this
echo <<< HTML
<script>var $__eID={$eID};</script>
HTML;
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() {
});
It is a short hand identical way of doing it.
ASKER
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?
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 runNote it is not $function
It is
$(function() {
});
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.
}
);
If that makes it more clear.
ASKER
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.
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
});
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.
ASKER
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
Nothing.
Here. An example that couldn't be simpler.
a button
<a id="myid" href="#"><i class="icon-trash-1"></i><
script
jQuery(function($) {
$(function() {
$('myid').click( function() {
alert('hi');
});
});
};
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
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!');
});
});
ASKER
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.
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.
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.
ASKER
Thanks again for your help. There was a js page loading which I did not catch. All is well now.
ASKER
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!