I have a div
<div id="loading"></div>
I then have some jQuery that loads in a page which is query heavy and therefore displays a spinner
<script>
$('#page1').click(function () {
// add loading image to div
$('#loading').html('<img src="loading.gif"> loading...');
// run ajax request
$.ajax({
type: "POST",
dataType: "html",
url: "client_reporting_01_data.php",
success: function (d) {
// replace div's content with returned data
$('#loading').html(d);
}
});
});
</script>
My trigger for this is a menu item:
<li id="page1" class = "<?php if($current_pgname == "client_reporting_01") echo 'active'; ?>">
C01: Summary Report
</li>
QUESTION:
I have multiple pages and multiple menu items
I'd like to be able to REuse the code I have here to pull the required pages back when the appropriate menu item is clicked.
So I would have another menu item
<li id="page2" class = "<?php if($current_pgname == "client_reporting_02") echo 'active'; ?>">
C02: Summary Report
</li>
and another page to call: client_reporting_02
I am just struggling with how to do the jquery to make this work
Somehow the jquery has to be able to read a page requested ie client_reporting_02_data.php
A further complication is how to actually move to that page and have it work. If say I am on pagexyz and i click the menu item for client_reporting_01 - it of course doesn not move there at present as a href="#"
One way to do it is bind to a class, rather than an id -
<script>
$('.reportLink').click(function () {
...
});
</script>
add the class, and a data attribute that holds the url (ie. data-url="client_reporting_01_data.php" and your li would now be
<li id="page1" class = "reportLink <?php if($current_pgname == "client_reporting_01") echo 'active'; ?>" data-url="client_reporting_01_data.php">
C01: Summary Report
</li>
now your script can be something like -
<script>
$('.reportLink').click(function () {
// add loading image to div
$('#loading').html('<img src="loading.gif"> loading...');
linkurl = $(this).data('url');//Probably want to sanitize and/or whitelist to prevent injection
// run ajax request
$.ajax({
type: "POST",
dataType: "html",
url: linkurl,
success: function (d) {
// replace div's content with returned data
$('#loading').html(d);
}
});
});
</script>
I am changing your already existing code slightly. If I understand what you want, the following will work. Instead of using the ID to call the function, add a generic class to all list items that are effected. I called it mypage here. Then there are a couple of ways to do it.
One way is: Instead of storing the url as is as a class, let the id tell you what url you are to look for. See the changes below for explanation:
// Generic class
$('.mypage').click(function () {
// add loading image to div
$('#loading').html('<img src="loading.gif"> loading...');
// if you need to include the 0 with child page numbers less than 10, you should change your ids accordingly.
var page=this.id.replace('page',''),
url= 'client_reporting_' + page + '_data.php';
// run ajax request
$.ajax({
type: "POST",
dataType: "html",
url: url,
success: function (d) {
// replace div's content with returned data
$('#loading').html(d);
}
});
});
Why not just delegate an event listener to the <ul> elements with an <a> anchor and put the url to load in the href? Like so;
HTML
<ul id="pages">
<li class = "reportLink <?php if($current_pgname == "client_reporting_01") echo 'active'; ?>">
C01: Summary Report
</li>
<li class = "reportLink <?php if($current_pgname == "client_reporting_02") echo 'active'; ?>">
Another Summary Report
</li>
</li>
Javascript
var $target = $('#loading');
$('#pages').on('click', 'a', function(event) {
event.preventDefault();
// add loading image to div
$target.html('<img src="loading.gif"> loading...');
$.ajax({
type: "POST",
dataType: "html",
url: this.href,
success: function (d) {
// replace div's content with returned data
$target.html(d);
}
});
});
You could even simplify your code by using .load like so:
Javascript - Simplifed version
var $target = $('#loading');
$('#pages').on('click', 'a', function(event) {
event.preventDefault();
$target
.html('<img src="loading.gif"> loading...')
.load(this.href);
});
Related
I want to show a comments section always. Now a user has to click, to start the javascript code to display the content (onclick). a simple change to "onload" is not working. I tried it.
//Show reviews
function reviews_show(value) {
jQuery.ajax({
type:'POST',
url:'<?php echo site_root?>/members/reviews_content.php',
data:'id=' + value,
success:function(data){
if(document.getElementById('comments_content'))
{
document.getElementById('comments_content').innerHTML = data;
}
}
});
}
html code on .tpl page:
<li>Comments</li>
</ul>
<div class="tab-content">
<div class="tab-pane" id="comments_content"></div> </div>
If you mean with always -> on page load -> then this is the answer:
document.addEventListener("DOMContentLoaded", function(event) {
var value='{ID}'; // use value variable for your ID here
jQuery.ajax({
type:'POST',
url:'<?php echo site_root?>/members/reviews_content.php',
data:'id=' + value, // or replace to => data:'id={ID}',
success:function(data){
if(document.getElementById('comments_content'))
{
document.getElementById('comments_content').innerHTML = data;
}
}
});
});
Edit: Of course this was just an example how to make the browser to execute the jQuery.ajax on Page Loaded Completed. I edited the code and put the var value='{ID}' for your example. Make sure that there is your ID inserted (as it was inserted before in your onclick="reviews_show({ID});".
Right now I have this code loading only 1 page (load.php?cid=1 but I want to load 5-8 (cid=1,cid=2,cid=3,cid=4,cid=5,cid=6,cid=10 ...etc )in different div(s).
how will I achieve it ?
$(document).ready(function() {
function loading_show() {
$('#loading_Paging').html("<img src='images/loading.gif'/>").fadeIn('fast');
}
function loading_hide() {
$('#loading_Paging').fadeOut 'fast');
}
function loadData(page) {
loading_show();
$.ajax({
type: "POST",
url: "load.php?cid=1",
data: "page=" + page,
success: function(msg) {
$("#container_Paging").ajaxComplete(function(event, request, settings) {
loading_hide();
$("#container_Paging").html(msg);
});
}
});
}
As JimL alluded to, I would give each element on your page a common class, give each element a unique data attribute like data-cid="1", iterate through each element grabbing the cids and calling the ajax function for each.
Id go a step further by using a promise to get all of the ajax responses then load all the data when the promise has been resolved (when all the ajax requests have been completed).
Here is a working example
The HTML:
<div id="loading_Paging"></div>
<div class="myElements" data-cid="1"></div>
<div class="myElements" data-cid="2" ></div>
<div class="myElements" data-cid="3" ></div>
<div class="myElements" data-cid="4" ></div>
<div class="myElements" data-cid="5" ></div>
<div class="myElements" data-cid="6" ></div>
<div class="myElements" data-cid="7"></div>
<div class="myElements" data-cid="8" ></div>
The jQuery:
$(function() {
var page = 'some string...'
loadData(page);
function loadData(){
$('#loading_Paging').html("<img src='images/loading.gif'/>").fadeIn('fast');
// loop through each image element
// calling the ajax function for each and storing the reponses in a `promise`
var promises = $('.myElements').map(function(index, element) {
var cid = '&&cid=' + $(this).data('cid'); // get the cid attribute
return $.ajax({
type: "POST",
url: 'load.php',
data: "page=" + page +cid, //add the cid info to the post data
success: function(msg) {
}
});
});
// once all of the ajax calls have returned, te promise is resolved
// and the below function is called
$.when.apply($, promises).then(function() {
// arguments[0][0] is first result
// arguments[1][0] is second result and so on
for (var i = 0; i < arguments.length; i++) {
$('.myElements').eq(i).html( arguments[i][0] );
}
$('#loading_Paging').fadeOut('fast');
});
}
});
The PHP I used for my example:
<?php
if (isset($_POST['cid']) ){
// this is just a contrived example
// in your code youd use the cid to
// get whatever data you need for the current div
echo 'This is returned message '.$_POST['cid'];
}
?>
I have a problem concerning my code which should change content in a div onclick "More News articles" as the change will happen only once. I see in Chrome Developer mode that it fires every click a request. What goes wrong?
Output.php
<?php
require_once('../pe13f/SSI.php');
require_once ('../PE13/smf_2_api.php');
?>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function MakeRequest(id)
{
$.ajax({
url : 'display.php',
data:{"id":id},
type: 'GET',
success: function(data){
$('#streaminnern').html(data);
}
});
}
</script>
<div id="stream" class="bg4 roundedcrop shadow">
<div class="ph25 pv20">
<h1>News</h1>
<input id="streamcnt" name="streamcnt" type="hidden" value="" />
</div>
<div id="streamadd"></div>
<div id="streaminnern">
<?php
$num_recent = 5;
echo $num_recent;
?>
</div>
<div onclick="MakeRequest(<?php echo $num_recent; ?>);" id="streammore">More News articles</div>
</div>
backend php display.php
<?php
$num_recent = $_GET['id']+5;
echo $num_recent;
?>
Greetings Emil
Check the source that is produced by output.php. You'll find there onclick="MakeRequest(5);". Basically - on every click you call MakeRequest(5) which always fires call display.php?id=5 (you probably see that in your dev console).
Try something like this:
<script>
var lastId = 0; // var that stores last fetched ID
function MakeRequest(id)
{
if(!lastId) // if there is no last ID use the one from initial onclick
lastId = id;
$.ajax({
url : 'display.php',
data:{"id":lastId}, // note that we are using the lastId var
type: 'GET',
success: function(data){
$('#streaminnern').html(data);
lastId = data; // save fetched ID in our global var
}
});
}
</script>
The request is always the same. Suppose $num_recent is initially set to 5.
Then as per your code MakeRequest(5) will be executed. And your ajax call updates a div with class streaminnern. So the new id has no impact on the next ajax call. For the ajax request to be sent updated value you may set
$.ajax({
url : 'display.php',
data:{"id":$('#streaminnern').html()},
.................
});
I'm working with AJAX on a website and I'm currently making some pages to load on a certain div: "pageContent". Now I have another content I want to be opened on another div: "reproductor". I want to open 'page' in 'pageContent' div and 'play' in 'reproductor' div. I don't know how to modify my script.js and load_page.php files in order to make it work. Here's what I got:
HTML:
<script type="text/javascript" src="js/script.js"></script>
PAGE
PLAY
<div id ="pageContent"></div>
<div id="reproductor"></div>
script.js:
var default_content="";
$(document).ready(function(){
checkURL();
$('ul li a').click(function (e){
checkURL(this.hash);
});
default_content = $('#pageContent').html();
setInterval("checkURL()",250);
});
var lasturl="";
function checkURL(hash)
{
if(!hash) hash=window.location.hash;
if(hash != lasturl)
{
lasturl=hash;
if(hash=="")
$('#pageContent').html(default_content);
else
loadPage(hash);
}
}
function loadPage(url)
{
url=url.replace('#page','');
$('#loading').css('visibility','visible');
$.ajax({
type: "POST",
url: "load_page.php",
data: 'page='+url,
dataType: "html",
success: function(msg){
if(parseInt(msg)!=0)
{
$('#pageContent').html(msg);
$('#loading').css('visibility','hidden');
}
}
});
}
load_page.php:
<?php
if(!$_POST['page']) die("0");
$page = (int)$_POST['page'];
if(file_exists('pages/page_'.$page.'.html'))
echo file_get_contents('pages/page_'.$page.'.html');
else
echo 'There is no such page!';
?>
I forgot to mention: I have my 'pages' content in a folder named 'pages' and my 'play' content in another named 'plays'.
Thanks for your help!
The easiest way to load content from a resource that serves HTML into an element is to use load:
$('#reproductor').load('public_html/plays/play_1.html', function(){
//stuff to do after load goes here
});
You could also apply this technique to the other div you are trying to load content into.
If I understand, your have two groups of links (for pages and a play list) each one to be loaded in a different container. Here is something you can try: mainly I eliminated the global variables and put the current hash inside each containter's data, and separated the management of the two groups of links.
In this code I supposed you have a separate load_play.php file. If not, then you can use the same page for both kind of links, but you'll have to merge loadPlay with loadPage, change loadPage(newHash) to loadPage(newHash, linkType) and change the ajax parameter from 'page='+newHash to 'number='+newHash+'&type='+linkType, and do the corresponding changes server side in your PHP page. I would recommend you to create two separate PHP files in order to manage the two types of content.
I remember you where doing something with the hash of the current page's url, you can still set it in the ajax's success, inside the loadPage function.
Here is a working sfiddle example with some console calls (open browser's console) but without the ajax call.
UPDATE:
I updated the code, so your can manage the dynamically added links (new content loaded via AJAX) and fixed the management of urls with hashes, which was broken because of the new code.
<div id="#page">
PAGE 1
PAGE 2
PLAY 1
PLAY 2
PLAY 3
<div id ="pageContent"></div>
<div id="reproductor"></div>
</div>
And this is the javascript:
$(document).ready(function(){
$('#pageContent').data('currentPage', '');
$('#reproductor').data('currentPlay', '');
//This will allow it to work even on dynamically created links
$('#page').on('click', '.pageLink', function (e){
loadPage(this.hash);
});
$('#page').on('click', '.playLink', function (e){
loadPlay(this.hash);
});
//And this is for managing the urls with hashes (for markers)
var urlLocation = location.hash;
if(urlLocation.indexOf("#page") > -1){
$('.pageLink[href='+ urlLocation +']').trigger('click')
}
});
function loadPage(newHash)
{
//This is the current Page
var curHash = $('#pageContent').data('currentPage');
//and this is the new one
newHash = newHash.replace('#page', '');
if(curHash===newHash){
//If already loaded: do nothing
return
}
$('#loading').css('visibility','visible');
$.ajax({
type: "POST",
url: "load_page.php",
data: 'page='+newHash,
dataType: "html",
success: function(msg){
if(parseInt(msg)!=0)
{
$('#pageContent').html(msg).data('currentPage',newHash);
$('#loading').css('visibility','hidden');
}
}
});
}
function loadPlay(newHash)
{//Similar to loadPage...
var curHash = $('#reproductor').data('currentPlay');
newHash = newHash.replace('#play', '');
if(curHash===newHash){return}
$('#loading').css('visibility','visible');
$.ajax({
type: "POST",
url: "load_play.php",
data: 'play='+newHash,
dataType: "html",
success: function(msg){
if(parseInt(msg)!=0)
{
$('#reproductor').html(msg).data('currentPlay',newHash);
$('#loading').css('visibility','hidden');
}
}
});
}
Check this and comment if this is what you need, or I got something wrong :)
There are a number of reasons why the following is not an ideal solution. The most glaring would be security - by modifying the href attribute of the link before clicking it, the user can certainly get your server to serve up any html on your server.
EDIT I've removed my original answer, because I can't recommend it's usage.
As Asad suggested, you can also use jQuery load and pass it the relevant url using some of the code above
function loadPage(url)
{
// remove the hash in url
url=url.replace('#','');
// extract page or play - only works for four letter words
var contentType=url.substr(0,4);
// extract the number
var contentId=url.substr(4);
if ( $contentType == "page") {
$("#pageContent #loading").css('visibility','visible');
$("#pageContent").load($contentType+'s/'+$contentType+'_'+$contentId+'.html');
$("#pageContent #loading").css('visibility','hidden');
} else if ( $contentType == "play") {
$("#reporductor #loading").css('visibility','visible');
$("#reproductor").load($contentType+'s/'+$contentType+'_'+$contentId+'.html');
$("#reporductor #loading").css('visibility','hidden');
}
}
I have a link that looks like this:
<p class="half_text">
<?php echo $upvotes; ?>
<strong><a class="vote_up" style="color: #295B7B; font-weight:bold;" href="#">Vote Up</a></strong> |
<?php echo $downvotes; ?>
<strong><a class="vote_down" style="color: #295B7B; font-weight:bold;" href="#">Vote Down</a></strong>
</p>
and I have the jQuery code that looks like this:
<script type="text/javascript">
$(document).ready(function()
{
$('.vote_up').click(function()
{
alert("up");
alert ( "test: " + $(this).attr("problem_id") );
// $(this).attr("data-problemID").
$.ajax({
type: "POST",
url: "/problems/vote.php",
dataType: "json",
data: dataString,
success: function(json)
{
// ? :)
}
});
//Return false to prevent page navigation
return false;
});
$('.vote_down').click(function()
{
alert("down");
//Return false to prevent page navigation
return false;
});
});
</script>
How can I get the parameter value which is problem_id ? If I add a url in the href parameter, I think the browser will just go to the url, no? Otherwise - how can I pack parameter values into the jQuery?
Thanks!
Because your $.ajax is defined in the same scope of the variable, you can use problem_id to obtain the variable value.
An overview of your current code:
var problem_id = "something"; //Defining problem_id
...
$.ajax(
...
success: function(){
...
//problem_id can also be accessed from here, because it has previously been
// defined in the same scope
...
}, ...)
....
If what you're trying to figure out is how to embed the problem ID in the link from your PHP so that you can fetch it when the link it clicked on, then you can put it a couple different places. You can put an href on the link and fetch the problem ID from the href. If you just do a return(false) from your click handler, then the link will not be followed upon click.
You can also put it as a custom attribute on the link tag like this:
<a class="vote_up" data-problemID="12" style="color: #295B7B; font-weight:bold;" href="#">Vote Up</a>
And, then in your jQuery click handler, you can retrieve it with this:
$(this).attr("data-problemID").
do you mean, getting variables from the php page posted?
or to post?
anyway here's a snippet to replace the $.ajax
$.post('/problems/vote.php', {problem_id: problem_id, action: 'up'}, function(data) {
// data here is json, from the php page try logging or..
// console.log(data);
// alert(data.title);
}, 'json');
{problem_id: problem_id, action: 'up'} are the variables posted... use $_POST['problem_id'] and $_POST['action'] to process..
use simple variables names with jQuery.data and make sure you have latest jQuery..
let me try to round it up..
up
down
<script type="text/javascript">
$('.votelink').click(function() {
$.post('/problems/vote.php', {problem_id: $(this).data('problemid'), action: $(this).data('action')}, function(data) {
// data here is json, from the php page try logging or..
// console.log(data);
// alert(data.title);
}, 'json');
});
</script>