calling a specific PHP function with AJAX - php

Updated with page titles.
This is on Leaderboard.php. you can see I've currently got the PHP call in the tbody.
<!-- The Leaderboard Table -->
<table id="tblData" class="table table-hover leaderboard-table target">
<thead>
<tr>
<th class="hidden-phone">Rank</th>
<th>Sales Person</th>
<th>Total Points</th>
</tr>
</thead>
<tbody id="leaderboardresults">
<?php $getLeaderboard->getTable($_GET['competitionId']); ?>
</tbody>
</table>
<!-- The Leaderboard Table END -->
This is on API/getLeaderboard.php. This is where the getTable function is.
<?php
class getLeaderboard {
public function getTable($competitionId) {
//I run the SQL query and echo out some PHP
}
This is on Leaderboard.php.
function loadLeaderboard() {
var competitionId = $("body").attr("data-competitionId");
var url = "api/getLeaderboard.php?competitionId=" + competitionId;
$.get(url, function(data) {
//$("#leaderboardresults").html(data);
});
}
This is also on Leaderboard.php. Another AJAX call that does a AJAX get (this works perfectly), and should reload the leaderboard on success.
$(function() {
//this works (/James)
$(".navVisible").click(function() {
var Competition = $("body").attr("data-competitionId");
var Activity = $(this).attr("data-activity");
$.post("registerresults.php", { data: Activity, competitionId: Competition })
.done(function(data) {
loadLeaderboard();
});
});
loadLeaderboard();
});
This is getLeaderboardTable.php
<?php
include "common/common.php";
include "api/getLeaderboard.php";
$competitionId = $_GET['competitionId'];
$getLeaderboard->getTable($competitionId);
?>

From what I understand you need the following -
You have a page (page A) which calls an ajax function at a specific time, and it is supposed to load results.
You have a php function which provides those results when passed a parameter "competitionId".
What you are doing wrong is you have 1 and 2 in the same page without any controller. What you need to do is, move
<?php $getLeaderboard->getTable($_GET['competitionId']); ?>
into a different page, say "getLeaderboardTables.php". Then modify your html page as follows:
<table id="leaderboardresults">
<tbody>
</tbody>
</table>
and then your ajax function as follows, which will insert the data into your data holding table identified by the id leaderboardresults:
function loadLeaderboard() {
var competitionId = $("body").attr("data-competitionId");
var url = "api/getLeaderboardTables.php?competitionId=" + competitionId;
$.get(url, function(data) {
$('#leaderboardresults tr:last').after(data);
});
}
The .after ensures that new rows are appended to the end of the table. if you want to replace them, call $("#leaderboardresults").empty(); first.
Technically speaking though, you do not NEED to move the function to a different PHP page; You can do what DevZero suggested and have a switch case based controller as well so that the same page can be used.
After you have edited the question, I have the following comments -
Your table id has to be leaderboardresults, not tbody id. if you want to keep your table body as tblData, then edit your ajax script as follows
$.get(url, function(data) {
$('#tblData tr:last').after(data);
});
Most important thing, is that you have neither used a controller like DevZero suggested, nor moved the php data fetch to a different page. What you will need to do is:
Option 1 - As I mentioned above, create a new page, called getLeaderboardTables.php, over there put the db connection, include the class, and add this line
<?php $getLeaderboard->getTable($_GET['competitionId']); ?>
so this new page, when called from the browser should ONLY output the rows and NOTHING else. Then call this URL passing the competition id as i mentioned before.
Option 2 - Donot create a new page, but in your existing page, have a controller, like DevZero said, by adding the following to the very top of your html/php after the class includes as follows:
switch ($_GET['action']) {
case 'ajax':
$getLeaderboard->getTable($_GET['competitionId']); //your specific function
break;
default:
?>
Current html/php page content will come here in its entireity
<?php
}
and modify the ajax call as:
var url = "api/getLeaderboard.php?action=ajax&competitionId=" + competitionId;
The basic idea is, AJAX cannot be used to call a PHP function directly. AJAX can be used to call a PHP page, and passing some parameters to it, which in turn calls a PHP function or method to generate some output, and print that output back to the browser window. What AJAX will do is copy that output from the php page, and store it in a javascript variable to do what you want with it. So, the url which you are passing to the ajax function must only load what you want to dynamically update. Think of AJAX here as an invisible man, who takes your url, opens a invisible browser window, pastes that link, waits for page to load, copies the output of the page and stores it in a variable for you.
What you are doing is, you are loading the whole page through AJAX, not just the output which you want to dynamically update.

you can load the results into any html element you want for example if you have a div with id foo you can load the data as follows
$.get(url, function(data) {
$("#foo").html(data);
});
to call a specific function on the file, introduce to a light weight controller to the top of that file.
switch ($_GET['action']) {
case 'foobar':
foobar(); //your specific function
break;
}
So with the controller above pass in the action value of for the function your routing to and then that function will be called.

Related

Best practice for using jquery to interact with php classes?

I have a dropdown selector on a page that allows a user to select a template type (for example, "human" or "dog").
Based on what template is selected, different fields will need to populate below the dropdown (for example, text fields for "parents names" or a dropdown list for "breed") that are unique to each template.
I will have a button that the user will click once the data fields are put in that will output data to an "output div" section of the same page when clicked (no POSTing data as it's not being saved). The output will have different output logic based on the selected template (for example, "I'm a human named X" or "I'm a dog, my breed is Y").
My real program will be more complex and each template will have a php class that stores all of the logic. Since I will be dealing with both php objects and variables gathered by jquery, what's the best way to let them interact?
For 1., I know I can do something easy like -
var selected_template = $('#my-template-dropdown :selected').text();
if (selected_template == 'Human'){
$('#my-fields').html('<?php echo HumanTemplate::render_fields(); ?>');
}
which is easy enough, but for 2. I need to pass variables from jquery to php, then return output back to jquery.
I would like some advice on the easiest way to do this before I start down the wrong path.
HTML
Allow the user to select the template type:
<form>
<select id="my-template-dropdown" name='template'>
<option value="dogs">Dogs</option>
<option value="humans">Humans</option>
</select>
</form>
<div id="my-fields"><div>
<div id="output"><div>
jQuery
Any time the user changes the template selection, request new content to display via AJAX, and insert it on the current page so the page does not have to refresh:
$('#my-template-dropdown').on('change', function() {
var template = $(this).val();
$.ajax({
url: 'http://your-site/path/to/' + template,
success: function(resp) {
$('#my-fields').html(resp);
}
});
});
PHP
http://your-site/path/to/template simply generates the HTML you want to display for that template, eg (just an example, don't know if this is suitable for your app):
if ($template == 'humans') {
echo HumanTemplate::render_fields();
} else if ($template == 'dogs') {
echo DogTemplate::render_fields();
}
For part 2, assuming all the logic you refer to is in the template rendered by PHP, you could then handle it with jQuery. This is pretty crude, you probably need something more sophisticated (eg a full template which you swap variables into?), but you get the idea:
$('#output').on('click', 'button', function(e) {
e.preventDefault();
// fields in your template which the user will fill
var species = $('#species').val(),
title = $('#title').val();
// Probably better to have this text as a template in your source
$('#output').html("I'm a " + species + ' named ' + title);
});
NOTE the gotcha in the event handler. Event handlers will only attach to elements that exist at the time the handler is defined. Since the content is injected after page load, an event handler like $('#button).on('click', function() {... would have no effect when clicking a button inserted via AJAX. The syntax here attaches to the parent #output div, which does exist at page load, and filters for clicks on a button. See the jQuery event delegation docs for more info.
Another option would be to POST the submitted data to some PHP controller, which generates and returns the output. This way all your logic is in the one place. For example, here the user's click will query the same PHP file which generated the initial template, this time including the values the user has entered. It could then generate the required output and return it, to be inserted on the page. You'd need to update the PHP so it can determine which of these cases it is handling (eg hidden field?); alternatively if you wanted to keep those separate you could hit another PHP file all together.
$('#output').on('click', 'button', function(e) {
var template = $('#my-template-dropdown').val(),
$form = $('form'),
data = $form.serialize(); // Values from all fields user has entered
$.ajax({
url: 'http://your-site/path/to/' + template,
data: data,
success: function(resp) {
$('#output').html(resp);
}
});
});
The best way to pass data from jQuery to PHP, is by using AJAX.
Mozilla has an excellent guide on getting started, that i recommend you follow.
An example of how you can achieve what you are requesting, is by trying the following:
var selected_template = $('#my-template-dropdown :selected').text();
var ajaxurl = 'ajax.php',
data = {'select_template': selected_template };
$.post(ajaxurl, data, function (response) {
console.log(response);
});
On the PHP end (Ajax.php in my example) It could look something like this
if(isset($_POST['select_template'])) {
// do something with the input from jQuery
$selected_template = $_POST['select_template'];
// return the result back to the client
echo $seleted_template;
}
?>
$selected_template will be sent back to the client, and response in the AJAX function will be whatever the server returned. So the console.log(response) should display whatever was being sent to the server
You can have a look to the function wp_localize_script.
This function make available PHP datas to JS files on the page load through the wp_enqueue_scripts action.
This will not work like an Ajax request and only populate data for a specific handle on page load. But you can mix this method with ajax in the same script.
Hope it helps even it doesn't seems to fit to your case.
As your class not fires on page load, you can use the action wp_ajax_{custom _action} and wp_ajax_nopriv_{custom_action} . For example, that's usually used to populate multiple dropdown, each time an event is trigger by the user, a php function returns result the js script.

Loading results of PHP function into DIV container

It seems this question has been answered in the past, however, I'm either 1) having a hard time grasping the solutions or 2) not implementing them correctly.
I have a PHP function, that when run, will return results of a database query. Results look similar to this:
Koenji
I can echo this into a page just fine. What I'd like to do is give an end user the option to refresh the link (which can be done by refreshing the page and echoing a new random string returned by the php function) without having to refresh the whole page. I've tried a few different methods, but it seems the function that returns the element is only run when the page reloads - so my URL never changes.
Here is my latest attempt. I figured the url I'm grabbing from the database was only getting set when the paged loaded. I thought setting a function to initialize the url variable would help - no good. It still only works once on page load.
$(document).ready(function() {
updateVariable();
$('#dannychoolink').html(random + url);
$('.danny-choo').attr('target', '_blank');
});
$('#clicky').click(function() {
updateVariable();
$('#dannychoolink').html(random + url);
$('.danny-choo').attr('target', '_blank');
});
function updateVariable() {
url = '<?php echo dannyChoo();?>';
random = 'Random DannyChoo.com article: ';
};
You can see it live at www.dannychoofan.com.
Any help is appreciated =0)
It looks like your looking for an ajax style call.
You should put the contents of the dannyChoo() function into a new file called articleLinkGenerator.php at the same level as your index.php file. This file should have the contents of the dannyChoo() function so that it automatically executes and echos the html you are expecting for the link like
<?php
function dannyChoo(){
// generate random link code
echo $random_link_html // Like Koenji
}
dannyChoo();
Then in your index.php (main web site) update your functions using ajax(http://api.jquery.com/jQuery.get/) to look like:
$(document).ready(function() {
updateVariable();
});
$('#clicky').click(function() {
updateVariable();
});
function updateVariable() {
$.get('articleLinkGenerator.php',function(data){
$('#dannychoolink').html(data);
});
};
It's because PHP runs before the page loads, and JavaScript runs after the page loads, so your variable never changes without another page load.

Load div from another page within an AJAX loaded page

I'm using jQuery address to enable loading specific content from other pages
and to change the URL in the address bar.
I'm working on a little Social Network alike website, so I'm reading out the IDs
of the posts table of my MySQL database via PHP. I want to use the possibilities of jQuery and AJAX to read everything out dynamically.
I found out, that I have to use live() (which turned out to be old), delegate() (which
also turned out to be old in 1.7.1) or on() (which turns out to be the best possibility
to make events work inside of dynamically loaded content via jQuery + AJAX).
I also read somewhere, that I can't use load() or get() to load new content from another
page inside of an already loaded content, because it doesn't "bubble" (I don't even know
what that means).
What do I have to do to load new content within an AJAX loaded page?
Here's a snippet I tried to work with (included on the loaded page):
<?php
if(exist('`posts`')) {
$load = mysql_query('SELECT `id` FROM `posts` ORDER BY `id` DESC LIMIT 10');
while($row = mysql_fetch_object($load)) {
?>
<script type="text/javascript">
$('body').on('body', 'load', function() {
$.get('getpost.php', { pid: <?= $row->id ?> }, function (data) {
$('#posts').html($('#post_<?= $row->id ?>', data).html()).show();
});
$('#posts').off('load');
});
</script>
<?php
}
}
else {
?>
<div align="center">No posts yet.</div>
<?php
}
?>
getpost.php is my file from which I can get the div_$row->id so that it appears on the start page.
PLUS (Just adding for your knowledge) I want the content to load the content without
a mouseover, click or blur event.
Thanks.
You want to use ".live()" if you want a particular event mapping to be applied dynamically to any new DOM elements which match its selector. Alternatively, you can attach the behavior to each chunk of content loaded.
Write and develop your ajax load independently of your DB lookup to make things simpler. The following snippet triggers another ajax call after each element loads.
<?php
$id = 'div'.mt_rand();
$counter = isset($_REQUEST['counter']) ? $_REQUEST['counter'] : 0;
$next = $counter + 1;
echo <<<END
<div id="{$id}">{$counter}
<script>
$(function() {
$.ajax('/url?counter={$next}', function(html) {
$(html).appendTo($('#{$id}').parent()); // or whatever your favorite method is for adding a sibling
});
});
</script>
</div>
END;
?>
Am I the only one who thinks that this approach is completely wrong? You're making an ajax request for each post, this could end up in making way too much requests, heavily slowing down the loading time. I can't see any reason why you don't want to directly write the posts' HTML inside the PHP while loop.

jquery to refresh div content generated by php

How to refresh a div content generated by the same php page using jquery
i have a test.php, that contains a div called refreshdiv, a button called refreshbutton and may other div's that display other contents
the content of refreshdiv div is generated by php
is it possible to reload the contents of the refreshdiv on clicking refreshbutton on the same page ie, test.php
here is my work around
<div id="refreshdiv">
<table>
<?php
$rec=mysql_query("select * from user_master");
for($i=0;$i<mysql_fetch_array($rec);$i++)
{
?>
<tr>
<td>
<?php echo mysql_result($rec,$i,'username');?>
</td>
</tr>
<?php } ?>
</table>
</div>
tried using $.get, but didnt get any result
Take a look at this jsFiddle I put together - it may help.
I'm making an AJAX call (a POST in this case since it's just HTML and that's what jsFiddle supports for HTML requests - but it would be no different for a $.get for you) that gets data and appends it to a table data cell (<td>). The whole page doesn't update - just the section that I'm targeting -- in this case, the <td> cell, which keeps having "hello's" appended into it.
I hope this helps. Let me know if you have add'l questions.
Use ajax
In the test.php use
if($_GET['ajax'] == 1) {
//echo new content;
}
and the jQuery code will be
function refreshClick() {
$("#refreshdiv").load("./test.php?ajax=1");
//OR
//to customize your call more, you could do
$.ajax({
method: "GET",
url: "./test.php?ajax=1",
success: function(data) { $("#refreshdiv").html(data); },
error: function(err){ Some_Error_Div.innerHTML = err; }
});
}
I think you'd need to set up a php page that will return the contents of the div then access this page via ajax and insert the contents generated by the page into your div. So the jQuery would look something like this -
$.ajax({
url: "div.php",
success: function(data){
$('#refreshdiv').html(data);
}
});

PHP post and get value to a jQuery box page, refresh page as `msnbc.com`

Finally, I find some article in http://code.google.com/intl/en/web/ajaxcrawling/docs/getting-started.html msnbc use this method. Thanks for all the friends.
Thanks for your all help. I will study it for myself :-}
Today, I updated my question again, remove all of my code. Maybe my thinking all wrong.
I want make a products show page.
One is index.php, another is search.php (as a jquery box page). index.php has some products catagory lists; each click on product catagory item will pass each value to search.php. search.php will create a mysql query and view products details. It(search.php) also has a search box.(search.php can turn a page to show multiple products; the search result looks similar to a jQuery gallery...).
I need to do any thing in search.php but without refreshing index.php.
I tried many method while I was thinking: Make search.php as an iframe (but can not judge search.php height when it turn page and index.php without refresh); use jquery ajax/json pass value from index.php to search.php, then get back all page's value to index.php. (still met some url rule trouble. php depend on url pass values in search.php, but if the value change, the two page will refresh all. )
so. I think, ask, find, try...
Accidental, I find a site like my request.
in this url, change search word after %3D, only the box page refresh
in this url, change search word after = the page will refresh
I found somthing in its source code, is this the key rules?
<script type="text/javascript">
var fastReplace = function() {
var href = document.location.href;
var siteUrl = window.location.port ? window.location.protocol+'//'+window.location.hostname +':'+window.location.port : window.location.protocol+'//'+window.location.hostname;
var delimiter = href.indexOf('#!') !== -1 ? '#!wallState=' : '#wallState=';
var pieces = href.split(delimiter);
if ( pieces[1] ) {
var pieces2 = pieces[1].split('__');
if ( pieces2[1] && pieces2[1].length > 1) {
window.location.replace( unescape(pieces2[1].replace(/\+/g, " ")));
}
}
}();
</script>
If so. in my condition. one page is index.php. another is search.php.
How to use js make a search url like
index.php#search.php?word=XXX&page=XXX
then how to pass value from one to another and avoid refreshing index.php?
Still waiting for help, waiting for some simple working code, only js, pass value get value.
Thanks to all.
I have read your problem, though I can not write complete code for you (lack of time ) So I can suggest you to what to do for your best practice
use dataType ='json' in jQuery.ajax function and
write json_encode() on B.php
and json_decode() on A.php or $.getJSON()
Alternate:
Read
jQuery.load()
assuming you really want to do something like here: http://powerwall.msnbc.msn.com/
I guess they are using a combination of ajax-requests and something like this: http://tkyk.github.com/jquery-history-plugin/
make shure that the navigation (all links, etc.) in the box works via ajax - check all the links and give them new functionality by js. you can write some function which requests the href url via ajax and then replace the content of your box. ...
function change_box_links(output_area){
output_area.find('a').each(function(){
$(this).bind('click', function(e){
e.preventDefault();
var url = $(this).attr('href');
$.ajax({
url: url,
success: function(data){
output_area.html(data);
//update url in addressbar
change_box_links(output_area);
}
});
});
});
}
it is upgradeable but shell show the main idea...
addendum[2011-05-15]
Get away from thinking you will have two files, that can handle some many "boxes". i mean you can do this but it's worth it.
but to be able to set up your templates like normal html page you could use the above script to parse the ajax requested html pages.
build your html-pages for
viewing the content,
viewing the search result
, etc.
on your main page you have to provide some "box" where you can display what u need. i recommand a div:
<div id="yourbox"></div>
your main page has buttons to display that box with different content, like in the example page you have showed us. if you click one of those a JS will create an ajax call to the desired page:
(here with jquery)
$('#showsearch_button').bind('click', function(){showsearch();});
function show_search() {
$.ajax({
url: 'search.php',
success: function(data){
var output_area = $('#yourbox');
output_area.html(data);
$.address.hash('search');
change_box_links(output_area);
}
});
});
for other buttons you will have similar functions.
the first function (see above) provides that the requested box-content can be written as a normal html page (so you can call it as stand-alone as well). here is the update of it where it also provides the hashtag url changes:
jquery and requireing the history-plugin
function change_box_links(output_area){
output_area.find('a').each(function(){
$(this).bind('click', function(e){
e.preventDefault();
var url = $(this).attr('href');
$.ajax({
url: url,
success: function(data){
output_area.html(data);
var name = url.replace('/\.php/','');
$.address.hash(name);
change_box_links(output_area);
}
});
});
});
}
and you will need some kind of this function, which will bind the back and forward buttons of your browser:
$.address.change(function(event) {
var name = $.address.hash();
switch(name){
case 'search': show_search(); break;
default: alert("page not found: "+name);
}
});
the above code should give an idea of how you can solve your problem. you will have to be very consequnt with filenames if you just copy and past this. again: it is improveable but shell show you the trick ;-)
im not sure that i fully understood what you want, but correct me if i didnt,
i think u need something like a dropdown that once the user select one item some div inside ur page show the result of another page result..
if so u can do it with jquery .load() and here is an example (no need for json)
Step 1:
Index.php
<p>
brand:<select id=jquerybrand>$jquerybrands</select><br />
Model:<select id=jquerycars></select><br />
</p>
<script type=\"text/javascript\">
$(document).ready(function(){
$('#jquerybrand').change(function(){
var value=$(this).value;
var url='api/quick.php?'+this.id+'='+this.value+' option';
$('#jquerycars').load(url);
});
});
</script>
This will simply show 2 dowpdown boxs (can be text or anything u like). and will add a listener to any change in value. once changed it will submit the id of the field and the new value to api/quick.php , then quick.php responce will be loaded into #jquerycars dropdown.
Step 2 quick.php
if(isset($_GET['jquerybrand'])){
$jquerycars="";
require_once("../lib/database.php");
$sql_db = new database();
$l=$sql_db->Item_in_table("car","sheet1","WHERE `brand`='$jquerybrand';");
foreach($l as $l)$jquerycars .="<option>$l</option>";
echo $jquerycars;//response that will replace the old #jquerycars
}
this will confirm that this is a request to get the query result only, then it will do the query and echo the results.
now once the results come back it will replace the old :)
hope it helps :).

Categories