Loading pages into div via ajax navigation - Couple of problems - php

I'm new to this whole programming business and I'm trying to put together a simple website for myself.
At present the website has a header, some navigation links, a makeshift image below the nav(which will be amended later and isn't relevant to the question much), and below that I have 3 content divs. The main content div, and two more to the right of it which I'm intending to be my sidebar widget for maybe a twitter feed, ads, that sort of thing.
I've set up the navigation links so that external pages are loaded inside my left-col div(my main content area). The Ajax works grand, as it is, it does exactly as was said on the tin.
The issue is each nav link reads javascript:ajaxpage('pageaddress.php','left-col');
Couple of things I don't like about that:
When you refresh the page it will naturally load the index.php content
Because the website address remains the same throughout browsing. It doesn't change to, let's say, /About.php.
Also, this doesn't work out well for SEO. Assuming I want individual page addresses, titles, and what not - and I do.
There is no real problem with the script, it works sure enough, it just doesn't work how I want it to work. Here's the Ajax script anyway.
<script type="text/javascript">
/***********************************************
* Dynamic Ajax Content- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/
var bustcachevar=1 //bust potential caching of external pages after initial request? (1=yes, 0=no)
var loadedobjects=""
var rootdomain="http://"+window.location.hostname
var bustcacheparameter=""
function ajaxpage(url, containerid){
var page_request = false
if (window.XMLHttpRequest) // if Mozilla, Safari etc
page_request = new XMLHttpRequest()
else if (window.ActiveXObject){ // if IE
try {
page_request = new ActiveXObject("Msxml2.XMLHTTP")
}
catch (e){
try{
page_request = new ActiveXObject("Microsoft.XMLHTTP")
}
catch (e){}
}
}
else
return false
page_request.onreadystatechange=function(){
loadpage(page_request, containerid)
}
if (bustcachevar) //if bust caching of external page
bustcacheparameter=(url.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime()
page_request.open('GET', url+bustcacheparameter, true)
page_request.send(null)
}
function loadpage(page_request, containerid){
if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1))
document.getElementById(containerid).innerHTML=page_request.responseText
}
function loadobjs(){
if (!document.getElementById)
return
for (i=0; i<arguments.length; i++){
var file=arguments[i]
var fileref=""
if (loadedobjects.indexOf(file)==-1){ //Check to see if this object has not already been added to page before proceeding
if (file.indexOf(".js")!=-1){ //If object is a js file
fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", file);
}
else if (file.indexOf(".css")!=-1){ //If object is a css file
fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", file);
}
}
if (fileref!=""){
document.getElementsByTagName("head").item(0).appendChild(fileref)
loadedobjects+=file+" " //Remember this object as being already added to page
}
}
}
</script>
and here's and example of a navigation link
<ul id="nav">
<li>Design</li>
Is there a way I can alter the Ajax so that each page loads inside the div, while also changing the url, allowing me to have different titles for each page, and also preventing the website from loading the index.php on refresh?
If not, does anyone know of any other scripts of methods of loading pages - and it doesn't necessarily have to be ajax - into a div only while doing what I want it to do(diff urls, titles, etc,)
This is my first time posting so hopefully my question is clear enough - albeit long - and is formatted properly.
Thanks, Chris.

For easy Ajax handling you can use for example jQuery.
But that doesn't change anything about the "changing the url" problem. For that you should use hashes (#). Your urls would look like index.php#about or ../#about. You can check that string after the # and show an individual page.
var hash = "default.html";
if(window.location.hash)
hash = window.location.hash.substring(1);
switch(hash){
case "default":
showPage(1);
break;
case "news":
showPage(2);
break;
// ...
}

Take a look at this question Redirect all website traffic to PHP handler, pitfalls?
In the handler (index.php) you can set title, content (include) base on $_SERVER['REQUEST_URI'].

Related

Insert dynamic content into php page and change the URL

My goal: I have a form that is in parts, 1-4, when the user clicks on the "Next" button I would like the content to animate out then part 2 slides, and so on until the form is complete. The tricky part is I would am trying to use a different php page in a different subfolder to insert as the other 3 parts. This would also change the URL subfolder the user sees.
The working example is actually WordPress. When you click through the multi-part form you will see the content and the URL act as I have described.
I did a bit of digging and it seems like they used React.js on the content but I couldn't really find any documentation on how to do this with React.js so it made me think that maybe it was custom Ajax/jQuery or what.
My Trees of Folders -
Main
Subfolder-1
index.php
Subfolder-2
index.php
And so on. The only thing I could think of would to use jQuery:
$(document).ready(function() {
$('#form-container').on('click', '.insert', function() {
var directory = $(this).attr('name');
$('#form-container').load('../' + directory);
return false;
});
});
I add the class of "insert" on the "Next" button and give it a name="Subfolder-2" $('#form-container').load('../Subfolder-2);' will actually load the content into the div without the page refreshing BUT it does not change the subfolder in the URL.
Am I on the wrong track? Maybe I am just not searching for the right thing?
Ok, so I ended up figuring out how to get the content to act like I wanted with the information John S. provided me. After doing some research and a few hours of trial and error I came up with the JavaScript below:
var data = 'start',
url = '../' + data + '/';
history.pushState(data, null, url);
Above I set the variables and immediately run a history.pushState on page load to capture the first div that is loaded into the content div. This is important because it is the only way I could load the content that happens on initial load back into the page when hitting the browsers back button.
$('body').on('click', '.insert', function(e) {
data = $(this).attr('data-name'),
url = '../' + data + '/';
history.pushState(data, null, url);
request_content(data);
return false;
});
Then I add a click listener to the button with the class .insert reset the variables so instead of grabbing the page that initially loaded it grabs the page that will be loaded, then use history.pushState again to change the url that is determined by the variables.
The request_content function is a simple .load function. So when the button is clicked the variables are set, the url changes and the new content get loaded into the page while the old content disappears.
The final piece to the puzzle which took me the longest to figure out is actually the popstate function. I am still not 100% sure why it works but after hours of messing with it and finally getting it to work I am not going to question it.
window.addEventListener('popstate', function(e){
var data = e.state;
if(data === null) {
} else {
request_content(data);
}
});
This popstate function is what allows the content to come back when hitting the browsers back or forward navigation.
CSSTricks < this article at CSSTricks helped a TON when learning this method.
Thanks again to John S. for pointing me in the right direction!

jQuery mobile: Dynamically add image

I am trying to load a static street view image, where the various parameters are stored in a mysql database. After trying lots of alternatives, I'm now passing the database data to a javascript variable and then trying to build the relevant URL (taking into account the page width along the way).
The page loads as restaurant.php?r=xyz where xyz is looked up on MySQL to return a line of data $r that is passed into a javascript array. Some of the array fields are used to create the URL of a Google Street view static image, which should then be loaded into the page.
This works fine if I enter the get to this page having started elsewhere on the site (or after a page refresh).
But if I start from this page and navigate around all future links to restaurant.php?r=abc do not load the image (it is downloaded and can be seen in the Chrome sources box). The pageinit event fires but the .html() fails to change the content (but reports no error).
I suspect I am breaking several laws of javascript, and jquery mobile....
Declared in header
var resto = {};
function insertSVPhoto() {
console.log("insertSVPhoto: Loaded data for: "+resto['rname']);
if ( Math.round(resto['heading']) != 0) {
var width = Math.round( $(document).width() * .9);
var s= "x250&location="+resto['lat']+",%20"+resto['lng']+"&fov=60&heading="+resto['heading']+"&pitch="+resto['pitch']+"&sensor=false";
var photo = "<img src='http://maps.googleapis.com/maps/api/streetview?size="+width+s+"'>";
console.log("Loading photo: "+photo);
$('#svphoto').html(photo);
} else {
console.log('No photo available');
$('#svphoto').html("<img src=''>");
}
}
And then below I have
<div data-role="page" data-add-back-btn="true">
<script type="text/javascript" >
<?php
echo "resto = ".json_encode($r).";";
?>
$( document ).on("pageinit", insertSVPhoto );
</script>
<div id='svphoto'></div>
I have to confess i'm no expert here but the way you're doing this doesn't seem quite right to me, i'd do the following:
window.onload = function () {
if(! window.device)
deviceReady()
}
document.addEventListener("deviceReady", deviceReady, false);
function deviceReady() {
$(document).delegate('#YOUR_PAGE_ID', 'pageshow', function () {
// Add your stuff here for doing the photo....
}
Again I only started using JQM a while ago but I know this works for an app i've done(and for a phonegap build too!)
EDIT: Also I would seriously consider putting everything all in one HTML document the way you've developed this is going to cause you a massive nose bleed if you try and build this as a mobile app, JQM is not designed to be used in the same way as Jquery, all of your "pages" should exist in one single html document and then use the navigation functions to move between pages.
Thanks
Marc
add data-ajax="false" or rel="external" to your links.. that should make it load properly
hello
OR
hello

Prevent images loading of images for users with javascript enabled

I got myself in some kind of chicken-egg situation here.
I have a page with a lot of images to load and i programmed a load on scroll script, like Facebook or Google images does, so when the user gets to the bottom of the page, the next set of images is loaded.
Because the server side images loading is kinda heavy and would probably slow down the website, i just load and store all images in a cache file, load it into the page and then with javascript, i remove all of them keeping only the first few and then gradually load the rest of them.
Now the first problem i ran into is that the browser keeps loading images even if they have been deleted using javascript. To get around it, i added a css class to the images i don't wan't to load and set them as display none, which i then remove using javascript.
But i still wan't the page to be non-javascript users and crawslers to be able to see the full page. And can't figure out a way to remove this "display none" without javascript.
Thank's in advance.
Why don't you simply use ajax to load the next batch?
That way it gets loaded into segments, load is spread and you don't need to do difficult markups...
My own jquery example of what I use in these kind of cases.
I have a php file that decides what needs to be rendering on basis of the "pagenumber" which gets translated in my mysql select ..... limit $pagenumber,15
<script type="text/javascript">
alreadyloading = false;
nextpage = 1;
$(window).scroll(function()
{
if ($('body').height() <= ($(window).height() + $(window).scrollTop()))
{
if (alreadyloading == false)
{
var url = document.location.href + "/ajaxload/" + (nextpage * 15);
alreadyloading = true;
$.ajax(url).done(function(data)
{
obj = document.getElementById('images');
obj.innerHTML += data;
alreadyloading = false;
nextpage++;
});
}
}
});
</script>

Dynamically change div content, while parts of the page remain static, and also allowing for direct access to whatever content (think bookmarks)?

First off, this site has helped me immensely through some school projects, and I hope my question is specific enough for some answers.
What I'd like to do is change the content of a div on my page (lets call it '#content'), while also somehow allowing for direct access to the various "pages" that would be created by changing the div's content.
For example, lets say that "foo.com/home" is to be the home page. The '#content' div would need to get filled with the code for the home page, while the other elements around it remain static (such as the header, footer, and navigation divs). Likewise, "foo.com/forum" would fill '#content' with the code for the forum, and other pages would do the same.
Currently, I'm simply checking the hash at the end of the URL, and then using jQuery's load() method to load my various code into '#content.' However, in addition to the fact that using the hash for navigation seems finicky on mobile browsers, it also just feels wrong to me.
I was thinking of using PHP, and then just using PHP includes to change what code is loaded into '#content' based on the URL. For example, "foo.com/page=forum" would fetch a page that is the same (layout wise) as the home page (header/footer, navigation, etc.), but would just include a different file for '#content.' However, this will reload the ENTIRE page, and not just '#content' right?
Ideally, I'd like to use some sort of AJAX call to reload just the '#content' div, but, other than editing the URL hash, I'm not sure how to do this while also allowing for bookmarks and such. I'd like users to just be able to go to "foo.com/home" or "foo.com/forum" and end up with the "template page" (header/footer, nav) filled in with the correct content.
Again, sorry if this is a poorly worded question. I've done some research, but can't seem to work out the best way to get this done. Thanks in advance -- any tips are appreciated.
Check this example code:
var xmlhttp;
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("content").innerHTML=xmlhttp.responseText;
}
}
var usernm = document.getElementById("username").value;
var pwd = document.getElementById("password").value;
var params = "username=" + usernm + "&password=" + pwd;
xmlhttp.open("POST","phpfile.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(params);
//xmlhttp.send(); without parameters

How can I change my Ajax to call two files with this code?

I'm new to AJAX, and I think I have a grasp on how it works. I created an edit profile form script using a tutorial and it works fine but I would also like for it to reload a php include file so that changes are automatically reloaded without going to another page.
So right now, when a form is submitted, it calls a php script I wrote named tehloader.php that makes changes to my database.
Everything works fine but I would also like for it to refresh an include file named brain.php that is on every page. This include file has a theme feature. So if a member would change the color of the theme using edit profile, I would like the brain.php to refresh so that the color changes to what tehloader.php changed in the database when they hit save.
Here's my code.
<script language="JavaScript" type="text/javascript">
function ajax_post(){
var hr = new XMLHttpRequest();
var url = "tehloader.php?load=profile";
var nm = document.getElementById("nname").value;
var cr = document.getElementById("color").value;
var pf = document.getElementById("styled").value;
var tk = document.getElementById("token").value;
var acc = document.getElementById("access").value;
var vars = "nnname="+nm+"&nnnprofile="+pf+"&ncolor="+cr+"&acccess="+acc+"&tokken="+tk;
hr.open("POST", url, true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var return_data = hr.responseText;
document.getElementById("status").innerHTML = return_data;
}
}
hr.send(vars);
document.getElementById("status").innerHTML = "<img src=./ajax-loader.gif>";
}
</script>
So is this possible to do? Thanks.
The idea behind AJAX calls is that the server call happens in the background and the current page is not reloaded, which results in faster operation and more dynamic and responsive interfaces.
When you get the return value of an AJAX call, it is the javascript calling code's responsibility to update any UI elements to reflect the changes, since the full page is not going to be reloaded.
In your case, from what I understand, you want to reflect changes in the user's theme preferences. In this specific scenario, you should consider if you really need AJAX behaviour here, since you essentially want to refresh the whole page (with new colours etc). Depending on the amount of theming and how you implement it, you can either update the UI in javascript to the new theme (which could be tedious,possibly loading CSS on the fly and etc) or maybe consider simply refreshing the page with a full POST or GET, which would render the page server-side with the new theme settings (since your brain.php would be executed again and it would pull the most recent data from the database).

Categories