I am using a $_GET function to load content into the website,
what I want to do is add a Loading image into all that mess.
Right now it looks like it opens a whole new page.
Code:
<?php
if (isset($_GET['page']) || isset($_POST['page'])) {
$page = trim(isset($_POST['page']) ? $_POST['page'] : $_GET['page']);
if (preg_match("/a-z/", $page)) {
}
} else {
$page = "index";
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body>
<div id="navigation">
<ul class="nav-items">
<li>Home</li>
<li>Test</li>
<li>Beta</li>
</ul>
</div>
<div id="content">
<?
if ($page != '')
include('pages/'.$page . '.php');
else
{
include('pages/error.php');
}
?>
</div>
</body>
</html>
Now, it works perfectly but I'd want it to show a Loading... image while loading the content , and instead of reloading whole page would be great to load the content div ONLY.
I did not try javascript solution since I didn't find anything that would work correctly and would keep the links working (for example http://example.com/index.php?page=test with already loaded the text.php file from pages folder). Plus I'm a real newbie in javascript so I have no idea what to start with.
The only solution to this problem is with JavaScript because PHP will only execute on the server and will only present HTML on the client side.
If you understand the HTTP request/response system, you will know that a request is sent to the server and then the server responds back with the page content, which will be the HTML (and CSS and any client-side scripts such as JavaScript). This method normally means having to reload the page but if you use AJAX (Asynchronous JavaScript and XML), this acts as a layer between the client and the server, allowing the user to request content without having to reload the page.
The most simple way of doing this is with jQuery. Be sure to include the jQuery library and put your code inside the $(document).ready(); function so that it executes when the page has finished loading.
Fortunately, this particular task is fairly simple, although it will require restructuring your website/application slightly. You will need to have the content echoed or printed onto a different page with PHP.
On your main page that will be used and seen by the users, you would simply write $("#container").load("page.html"); where container is the id of the container you want to load the content into.
If you want different content to be loaded with different buttons, you could do this (as long as you give your links the correct ids:
$(document).ready(function() {
$("#alpha").onclick(function() {
$("#container").load('page.html?page=alpha');
});
$("#beta").onclick(function() {
$("#container").load('page.html?page=beta');
});
});
Edit: I'm so sorry, I missed out the important part about the loading image, but the other answer demonstrates this well, so there is no point in repeating it.
It looks like it is opening a whole new page because it is. Your only option would be javascript. If I were wanting to do this, I would always only load the index page with nothing in your content div except the loading icon. Then once the page is loaded have jquery read the get variable and make an ajax request for the content of the page and load it into the div.
<div id="content">
<div id='page'></div>
</div>
Then, to make it easier on you since you are unfamiliar with javascript I would include the following jquery plugin: https://github.com/allmarkedup/purl
then in .js file:
$( document ).ready(function() {
var loading_annimation = "<div class='loading'></div>";
var page = $.url().param("page");
if(page){
$('#page').load(loading_annimation ).load('/special_php_file_that_includes_JUST_content.php?page='+page);
} else {
$('#page').load(loading_annimation ).load('/special_php_file_that_includes_JUST_content.php?page=index');
}
$(document).on('click','.link', function(e){
e.preventDefault();
var page = $(this).attr("data-link");
$('#page').load(loading_annimation ).load('/special_php_file_that_includes_JUST_content.php?page='+page);
});
});
Then you will need to change your links to do something like this:
<a class='link' data-link='beta' href="/index.php?page=beta">Beta</a>
Related
I’m including one HTML file in another, as a way to reuse my header and navigation generation logic.
The trouble is that when I browse to pages on my site, I can see the HTML that isn’t included in the include files load first. Only then you can see the menus and banners load afterwards. I’d like everything to appear to load at the same time.
Here's the rendered HTML.
And here’s a code snippet showing you how I generate these pages:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
<script>
$(function(){
$("#includeHeader").load("includes/templates/header.html");
$("#includeNavigation").load("includes/templates/navigation.html");
});
</script>
<div id="includeHeader"></div>
</head>
<body>
<div id="wrapper">
<!-- Navigation -->
<div id="includeNavigation"></div>
I’m currently working with the code to try to move any external libraries / CSS to the bottom of the page vs. in the header. But so far, that hasn’t really changed or improved anything.
You should use one of the templating languages.
If your includes are simple HTML files then you could use Handlebars or Dust - you could just copy your code and that's it, then in Javascript you would need just render these templates - see the documentation.
You could use Jade/Pug instead, but its syntax is different from the HTML, so that's not just question of copy-paste.
You are using $(handler) to load them, which is a form for $.ready(). So it waits for the document to load everything before loading your header.html and navigation.html.
Try
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
</head>
<body>
<div id="includeHeader"></div>
<script>
$("#includeHeader").load("includes/templates/header.html");
$("#includeNavigation").load("includes/templates/navigation.html");
</script>
</body>
Your problem is that the load function does not run until the document.ready event has fired. Which is probably after your page has started rendering. To get everything to appear at the same time you could use the callback from .load to show everything. So everything is hidden,
$( "#result" ).load( "ajax/test.html", function() {
/// show your stuff
});
You will of course need to know both has loaded.
I would recommend not using javascript to render HTML from a static path and would use a server side lang instead for speed.
I think it make some level fast its not waiting for load all dom element, I am considering #includeNavigation element is under #includeHeader element
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
</head>
<body>
<div id="includeHeader"></div>
<script>
$("#includeHeader").load("includes/templates/header.html", function(data){
console.log("header loaded");
$("#includeNavigation").load("includes/templates/navigation.html", function(data){
console.log("navigation loaded");
});
});
</script>
</body>
My aim is to get an element <div id="calender"> and all what is in the element shown in a browser. The point is that normal get-html-source won't do the thing. The element what I am looking for does not exists in the html output of php-function file_get_contents.
I have tried to get the source by php with xpath byt the help of http://us3.php.net/manual/en/class.domxpath.php which inludes a nice tool to get what is in any tag in the html page. But the problem here might be that the element (a calender) is formed to the loaded page by javascript and cannot be caught by server side php. So, is there a way I can catch such element (div) by javascript instead.
There are script examples of javascript for this kind of problem (if I have understood them correctly) but currently I cannot get a simple javascript to work. An example below shows how I have tried to built up a code. $ajax thing here is just one path I have tried to solve the problem but don't know how to use it. More here I cannot figure out why the simple javascript functions do not work (just test purposes).
<!doctype html>
<html lang="fi">
<head>
<meta charset="utf-8">
<title>load demo</title>
<style>
body {
font-size: 12px;
font-family: Arial;
}
</style>
<script type="text/javascript">
function ok {
alert "OK";
}
function get_html (my_html){
alert "OK";
var l = document.getElementById('my_link').value;
alert l;
alert my_html;
var url = my_html;
$.ajax({
url: url,
dataType: 'html'
success: function(data){
//do something with data, which is the page 1.html
var f = fs.open("testi_kalenteri.html", "w");
f.write(data);
f.close();
alert "data saved";
}
});
}
</script>
</head>
<body>
<p id ='my_link' onclick='get_html("lomarengas.fi/en/cottages/kuusamo-rukasaukko-9192")'>html-link</p>
<p id ='ok' onclick='ok()'>show ok</p>
</body>
</html>
Briefly, I have a link to a web page, which shows up a (booking) calendar in it but this calendar is missing in the "normal" source code, by file_get_contents (php). If I browse the html source with Chromes tools (F12) I can find the calendar there. T want that information get by javascript or by php or such.
If you read the source code of the page you point to (http://www.yllaksenonkalot.fi/booking/varaukset_akas.php), you notice that the calendar is loaded via an iframe.
And that iframe points to that location :
http://www.nettimokki.com/bookingCalendar.php?id_cottage=3629&utm_source=widget&utm_medium=widget&utm_campaign=widget
Which is in fact the real source of the calendar...
EDIT following your comment on this answer
Considering the real link : http://www.lomarengas.fi/en/cottages/kuusamo-rukasaukko-9192
If the calendar is not part of the generated html, it is surely asynchronously generated (in javascript, client side).
From this asumption, I inspected the source code (again).
In the developper tools of my browser, in the Network section, where you can monitor what files are loaded, I looked for
calls to server (everything but calls to resources : images, stylesheets...).
I then noticed calls to several urls with json file extensions like http://www.lomarengas.fi/api-ib/search/availability_data.json?serviceNumber=9192¤tMonthFirstDate=&duration=7.
I felt I was on the right track (asynchronous javscript calls to generate html with json datas), I looked for javascript code or files that was not the usual libraries files (jquery, bootstrap and such).
I stumbled upon that file : http://www.lomarengas.fi/resources_responsive/js/destination.js.
It contains the code that generates asynchronously the calendar.
tl;dr
The calendar is indeed generated asynchronously.
You can't get the full html with a curl or file_get_content in PHP and
you can't access it with ajax code (due to Same-origin policy).
By the way, you should contact the site to see if you can access their api via PHP with their consent.
Hope it helped you understand the whole thing...
To get <div id="calender"> you can use next code (jquery):
<div id="calender"></div>
<script>
$("#calendar").click(function(){
alert('calendar was clicked');
});
</script>
If I understand you correctly. I think you need appropriate php respond with some correct code inside php file:
// json_handler.php
<?php
if (is_ajax()) {
$return = $_POST;
$return["ok"]="ok";
$return["json"] = json_encode($return);
echo json_encode($return);
}
function is_ajax()
{
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
}
and this is script wich is inside html:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
<a id="click">click</a>
<script>
$("document").ready(function(){
$("#click").click(function(){
var data = {
"request": "request"
};
data=$.param(data);
// alert(data);
$.ajax({
type: "POST",
dataType: "json",
url: "json_handler.php",
data: data,
success: function(data) {
// here you will see echo respond from your php json_handler.php
// also you can add here more javascript (jquery code) to change your page after respond
alert();
}
});
return false;
});
});
</script>
<body>
<html>
http://www.w3schools.com/jquery/jquery_ajax_intro.asp
I've been running into some problems that seem to arise from making my questionnaire a .PHP file rather than an .HTML. The reason I had to do this is because I'm using a PHP script for working with an SQL database and I had to include them into the Questionnaire, which won't work as an HTML.
In the HTML version everything runs perfectly the way I coded it. When I saved it as a .php file my javascript stopped working properly and I tried linking the javascript at the bottom of the body tag instead of the head and that still didn't help.
After a lot of going back and forth trying to see what's different I decided to save the .php file as an html just for grins and giggles to see if I still got the same problems. Oddly enough, it runs just as smooth as the other HTML file.
here's links to all 3 versions so you can see what I mean.
HTML v1
PHP
HTML v2
In the JS Console I got this error
Uncaught TypeError: Cannot set property 'onClick' of null
which referred me to line 163 of my .js file which is referencing the "next" button of the first page of the Questionnaire (not intro page that loads up but the next page where you actually input data).
The way I have the Questionnaire structured in the .PHP file is
<?php ini_set('display_errors','on'); ?><?php include('extlib/vdaemon/vdaemon.php'); ?><!doctype html>
<html>
<head>
//links to files etc.//
</head>
<header>
</header>
<body>
<form action="core/process.php" method="post" id="CorpID" runat="vdaemon">
<input type="hidden" name="formID" value="Questionnaire" />
<input type="hidden" name="redirect_to" value="http://optiqvision.x10host.com/Corp_ID_&_Branding_Questionnaire.html" />
//all form inputs//
</form>
<?php VDEnd(); ?>
</body>
<footer>
</footer>
</html>
The entire Questionnaire has well over 100 individual inputs so I didn't want to put all of them in this snippet. I just wanted to show the over all structure, plus I figured you could get more details in the browser from clicking on them and looking at the debugger to see more of what's going on. Can anyone identify what I'm doing wrong with the PHP? I really don't understand why it's messing up the way it is.
In your html the code for the textarea is like this:
<textarea id="my_comp" class="tex_inp01" style="width:88%; height:100px; font-size:14pt;"></textarea>
In your php the
The textarea closing tag is misplaced; coming after a lot of div's including the element with the id=p1_next. SO the divs just become part of the textarea value instead of being part of the HTML page
Edit: Looks like the real problem is that the DOM is broken. In your PHP file, you have a self-closed textarea tag. textarea tags need a closing tag.
<!-- you have this, it's not syntactically correct -->
<textarea id="my_comp" class="tex_inp01" style="width:88%; height:100px; font-size:14pt;" />
<!-- the following is correct -->
<textarea id="my_comp" class="tex_inp01" style="width:88%; height:100px; font-size:14pt;"></textarea>
Put Corp_ID_&_Branding_Questionnaire.js right before the body tag and it will work. The reason the PHP file is throwing a javascript error is because the node "p1_next" doesn't exist at runtime since your JS is in the head tag.
The reason it's working in the HTML file is mainly thanks to luck. The static HTML is loading fast enough that the DOM is ready by the time your JS code is running. As a thumb of rule, generally include all your JS right before the body tag. There are of course some exceptions.
If you really need to include your script in the head, you can wait until the DOM is ready by wrapping all your code with this:
$(document).ready(function() {
console.log( "ready!" );
// your JS code here
});
Last, if you're going to be using jQuery as a library, then it is recommended to use jQuery syntax instead of native JS. Just make sure to include the jQuery JS before your code.
var p1a = document.getElementById("p1_next");
// becomes:
var p1a = $('#p1_next'); // jQuery node by CSS selector
Before the end of the body tag like this:
<html>
<head>
..your code ..
</head>
<body>
..your code ..
<script type="text/javascript" src="http://www.optiqvision.x10host.com/Files/Javascript/Corp_ID_&_Branding_Questionnaire.js"></script>
</body>
</html>
I'm developing a web application that because of performance concerns is heavily reliant on Ajax functionality. I'm attempting to make parts of each page available while longer running modules load.
The issue is that I want to kick off the Ajax requests as soon as possible (in the head of the document). This part works fine; the issue is on rare occasion, the Ajax call will come back before the area that I want to load the Ajax data into is present on the page. This causes the data to not be loaded.
To get around the issue I started using script tags below each of my containers that resolve a JQuery promise to let the code know that the area is available.
EDIT: I want to load the data into the area as soon as it becomes available (before full document load).
The current pseudo code looks like this:
<head>
<script>
var areaAvailablePromise = new $.Deferred();
$.when(areaAvailablePromise, myAjaxFunction()).then(function(){
// load data into the element.
});
</script>
</head>
<!-- much later in the document -->
<div class="divIWantToLoadAjaxContentInto"></div>
<script>
areaAvailablePromise.resolve();
</script>
My question is: is there ANY better way to handle this situation? Every one knows that inline scripts are blocking and are bad for performance. Also, I feel that this is going to lead to cluttered code with micro-script tags all over the place.
Put your (whole) <script> tag just after the element.
HTML is parsed from top to bottom, so the element will be loaded already.
No. There really is no better way to my knowledge.
<!doctype html>
<html>
<head>
<script src="jquery.min.js"></script>
<script src="q.min.js"></script>
<script>
var elD = Q.defer();
var dataP = Q($.ajax(…));
Q.spread([elD.promise, dataP], function (el, data) {
…
}).done();
</script>
</head>
<body>
…
<div id="foo"></div>
<script>elD.resolve($("#foo"));</script>
…
</body>
</html>
you can use:
$(document).ready( handler )
(recommended)and also has contracted form:
$(handler)
exemple:
$(function(){
alert("OK");
})
read more: http://api.jquery.com/ready/
I have been puzzling with this for quite a while and can't get it to work. Here is the situation. I want a SOCIAL MEDIA bar to ONLY appear if people click some DIV. It should not be loaded unless people click the div. For Social Media I have ADD THIS, and the GOOGLE+1 icon. But I can not get them to load by such an external call. Here is the code so far:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=ISO-8859-1" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#socialmedia").live('click',function(){
$("#loadhere").load('html-part.html');
$.getScript('js-part.js');
});
});
</script>
</head>
<body>
<div id="socialmedia">
Show the Social Media
</div>
<div id="loadhere">
</div>
</body>
</html>
In the HTML part I have the HTML info that needs to be loaded:
html-part.html:
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<!-- AddThis Button END -->
<g:plusone size="medium" id="gg"></g:plusone>
</div>
For the JS part I am struggling. Here is what needs to be loaded:
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#pubid=ID"></script>
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
I have tried to call them one by one:
$.getScript('http://s7.addthis.com/js/250/addthis_widget.js#pubid=ID');
$.getScript('https://apis.google.com/js/plusone.js');
But I guess this is a crossdomain problem...?
If I use PHP to obtain the content, and load a local PHP file, it still does not work. Before spending one more day on this... is this possible to achieve?
The problem here is that addthis code fires on dom ready event. When you load it with jQuery the dom has already been loaded so the code is not executed. The fix is to use addthis.init() method to force the code execution after you load the code. There is no cross domain problem or anything.
Note that according to addthis documentation it should be possible by just passing a get variable through the widget url like this http://s7.addthis.com/js/250/addthis_widget.js#pubid=[PROFILE ID]&domready=1 but it didn't work for me.
I would also recommend you store the html in a string variable, that way you don't have to do unnecesary requests for a little static html.
See working demo here: http://jsfiddle.net/z7zrK/3/
$("#socialmedia").click(function(){
var add_this_html =
'<div class="addthis_toolbox addthis_default_style ">'+
'<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>'+
'<a class="addthis_button_tweet"></a>'+
'<a class="addthis_counter addthis_pill_style">'+
'</a>'+
'</div>'+
'<g:plusone size="medium" id="gg"></g:plusone>';
$("#loadhere").html(add_this_html);
$.getScript('http://s7.addthis.com/js/250/addthis_widget.js#pubid=xxx',
function(){
addthis.init(); //callback function for script loading
});
$.getScript('https://apis.google.com/js/plusone.js');
});
Just used amosrivera's answer (huge kiss to you btw :) and ran into another issue :
Addthis object can only be loaded once, so when you have multiple addthis toolboxes on the same page it may only work for the first clicked toolbox.
The workaround is to do :
if (window.addthis){ window.addthis = null; }
before calling
addthis.init();
Here's what I've just done to start loading the buttons only when an article is hovered long enough :
HTML:
<article data-url="someUrl" data-title="someTitle" data-description="someDesc">
.....
<div class="sharing">
<div class="spinner"></div>
<div class="content"></div>
</div>
</article>
JS :
// Only throw AJAX call if user hovered on article for more than 800ms
// Then show the spinner while loading buttons in a hidden div
// Then replace the spinner with the loaded buttons
$(function() {
var t;
$("article").hover(function() {
var that = this;
window.clearTimeout(t);
t = window.setTimeout(function () {
sharing_div = $('.sharing', that);
add_this_html =
'<div class="addthis_toolbox addthis_default_style "> \
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a> \
<a class="addthis_button_google_plusone" g:plusone:size="medium"></a> \
</div>';
if (sharing_div.find('.content div').length == 0) {
sharing_div.find('.spinner').show();
sharing_div.find('.content').html(add_this_html);
sharing_div.find('addthis_toolbox').attr({
'addthis:url': $(that).attr('data-url'),
'addthis:title': $(that).attr('data-title'),
'addthis:description': $(that).attr('data-description'),
})
if (window.addthis){ window.addthis = null; } // Forces addthis to reload
$.getScript('http://s7.addthis.com/js/250/addthis_widget.js#pubid=xxx&async=1',
function(){
addthis.init();
setTimeout(function() {
sharing_div.find('.spinner').hide();
sharing_div.find('.content').show();
}, 2500);
});
}
}, 800);
});
});
To answer your official question, yes, I believe this is possible to achieve.
But, to further elaborate on this, I believe what you may want to try working with is the order in which your external scripts and external markup are loaded. An interesting situation we find when dealing with asynchronous actions such as these, is that they don't always complete, load, or execute in the order you would like unless you specifically say so. jQuery lets you do this through some callbacks you can pass to the getScript and load methods.
There also should not be a "cross-domain" problem with javascript files on other domains, though there certainly is when loading HTML.
I'm not sure if this will exactly solve the problem you're having, but it certainly feels like this is worth a try. You could try making sure the markup loads before the scripts do:
$(function(){
$("#socialmedia").live('click',function(){
$("#loadhere").load('html-part.html', function() {
// this waits until the "html-part.html" has finished loading...
$.getScript('js-part.js');
});
});
});
Now, we should also ask about how you are building your "js-part.js" file. (You only showed what you wanted, not what you've built.) If this is truly a JS file, you can't just use some HTML <script> tags to load other JS files. (You would instead want to continue calling getScript in this file, or use one of several other approaches to get your other JS stuff loaded, such as manually appending script elements to the document's head, or using another library, etc...)
Good luck!