Link to home
Start Free TrialLog in
Avatar of vinceq
vinceq

asked on

Want to click link and populate a div with an include?

I'm trying to set up an events page. It has a calendar with an empty div next to it for the event info... when the user clicks a  link on the calendar, the div fills with the event info.

I'm very much a newb, and have seen this done, i'm just trying to figure how it works so i can implement myself. i've attached a crude graphic of what i'm talking about.
filldiv.gif
Avatar of shawnlehner
shawnlehner
Flag of United States of America image

Well there are some things you need to consider frst... how are you storing the "events"? Are they in a database? If they are in a database then you must already be using PHP or ASP.NET to load them in which case you now need to decide if you want to deal with a page refresh or not; and the answer is most likely no. So the technology you are looking for is called Ajax; what this does is use javascript to interface with a backend which in turn adds dynamic content to your website without the need for page refreshes. There are numerous links and tutorials on the web for this...

Here is a quick run down on what Ajax is...
http://en.wikipedia.org/wiki/AJAX

If I know more about what technologies you are using I should be able to provide more help.
Avatar of hielo
I suggest you use ajax for this task. The idea is to click on the calendar cell/event, and NOT refresh the page. Instead send  a request to the server (on the background), requesting for the event details for the selected date and then update your div with the event details returned by the server request. If you have not programmed any ajax pages, refer to this:
http://w3schools.com/ajax/ajax_intro.asp

Specifically, the portion o the tutorial that you are most interested in is this:
http://w3schools.com/ajax/ajax_database.asp
Avatar of vinceq
vinceq

ASKER

Thanks shawnlehner will check the link.

Thanks hielo will research your links as well.

This might sound noobish. But if the events are minimal could i just have say april1.php, april2.php, april6.php etc. in the root folder, or is that so 2006!

I will do some more research.
My preference for this would be to use the prototype library.

If you put the links in a div ...

<div id="links">
<a href="http://www.site.com/eventinfo.php?id=1">Event 1</a><br />
<a href="http://www.site.com/eventinfo.php?id=2">Event 2</a><br />
<a href="http://www.site.com/eventinfo.php?id=2">Event 2</a><br />
</div>

sort of thing.

Make the div for the results have an ID ...

<div id="eventDetails">
Now add the following code to your <head> tag.

<script type="text/javascript" src="./prototype.js"></script>
<script type="text/javascript">
document.observe('dom:loaded', function(e1) {
  $$('.links a').invoke('observe', 'click', function(e2){
    Event.stop(e2);
    new Ajax.Updater('eventDetails', e2.element().href);
  });
});
</script>

You could also make the div containing the event details an iframe with a name and then use a target on the links to that iframe.

See https://www.experts-exchange.com/questions/23207188/window-open-keeping-original-page.html for a similar question.
Avatar of vinceq

ASKER

RQualdlin - Thanks, i will check out your solution as well.
I love this place! you guys/gals all rock!
You can have those files anywhere. The important thing is that when you do the AJAX request, you request the correct file. As a matter of fact, if all your events are in php files like what you showed, all you need is the code below. You just need to incorporate the links for the other events.
<html>
<head>
<script type="text/javascript">
var xmlHttp=null;
 
function showEvent(url)
{ 
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
  {
  alert ("Your browser does not support AJAX!");
  return;
  } 
url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
 
function stateChanged() 
{ 
	if (xmlHttp.readyState==4)
	{ 
		document.getElementById("eventDetails").innerHTML=xmlHttp.responseText;
	}
	xmlHttp=null;
}
 
function GetXmlHttpObject()
{
var xmlHttp=null;
try
  {
  // Firefox, Opera 8.0+, Safari
  xmlHttp=new XMLHttpRequest();
  }
catch (e)
  {
  // Internet Explorer
  try
    {
    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
  catch (e)
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
return xmlHttp;
}
</script>
</head>
 
<body>
<table border="1">
	<tr>
		<td><a href="april1.php" onclick="showEvent(this.href); return false;">April 1</a></td>
		<td><a href="april6.php" onclick="showEvent(this.href); return false;">April 6</a></td>
	</tr>
</table>
 
<div id="eventDetails"></div>
 
 
</body>
</html>

Open in new window

Heilo, nothing wrong with your answer, but having a third party library assists in keeping things cross platform/os compatibility.

As you can see, the actual amount of code I had to write is minimal.

On the other side to this point, if all that is required is an ajax request and non of the other niceties of the library, then you may not want/need a library.
Avatar of vinceq

ASKER

RQuadling: you have
"<div id="links">
<a href="http://www.site.com/eventinfo.php?id=1">Event 1</a><br />
<a href="http://www.site.com/eventinfo.php?id=2">Event 2</a><br />
<a href="http://www.site.com/eventinfo.php?id=2">Event 2</a><br />
</div>
Again being new at this...how do is set the events(april1.php etc) with the id=1, id=2, and id=3?
@RQuadling: I agree 100%, but if you take into consideration this "I'm very much a newb, and have seen this done, i'm just trying to figure how it works so i can implement myself. " and think back on YOUR newb days, can you honestly tell me that this construct:
document.observe('dom:loaded', function(e1) {
  $$('.links a').invoke('observe', 'click', function(e2){
    Event.stop(e2);
    new Ajax.Updater('eventDetails', e2.element().href);
  });
});

is trivial to understand? The way I see it is, this boils down to "minimal typing" vs "easy to understand and maintain". My post is lengthier but I has a decent tutorial to go with it. Granted I basically implemented the whole thing for him already, but even if I had not done so, I think the tutorial is good enough that he might be able to put it together relatively fast. No offense to the poster but if he is truly a newb, I believe the second argument to document.observe will throw him off. I've seen it time and again.

BTW: its Hielo :)
Avatar of vinceq

ASKER

Heilo -

I tried yours and it definitely works but it opened the (april01.php) a new window, unless i goofed somehere. i would like to keep it all on the same page.
Don't bother. If you already have april1.php, april2.php, then use those as the URLs.

<a href="http://www.site.com/april1.php">Event 1</a><br />
<a href="http://www.site.com/april2.php">Event 2</a><br />
<a href="http://www.site.com/april3.php">Event 2</a><br />


Whilst there is nothing wrong with this method, it does mean you need a physical PHP script for every event, or you need to use your web server to map the url to a file with an id.

The advantage of passing a parameter to a PHP script in the way I used previously, is that you only need 1 script. Only 1 place can accept the request. Only 1 file to edit/maintain.

Now in that file, how you get the data is upto you. I would expect a DB for complicated/large event lists.

You COULD use a simple XML file. It all depends upon the requirement.



Say you went with the eventinfo.php?id=x method, then your eventinfo.php script could look something like this ...

<?php
// Validate requested ID
if (isset($_GET['id']) && ($i_ID = intval($_GET['id']))) {
  // Declare an empty event.
  $a_Event = array
        (
        'eDate' => '',
        'eTitle' => '',
        'eBody' => '',
        );

  // Load event data for ID.
  // This will load all the data into an array maybe - see examples...
  include_once "./event_{$i_ID}.inc";
 
  // Now echo the results required.
  echo <<<END_HTML_FRAGMENT
<div>
      <h1>{$a_Event['eDate']}<br />{$a_Event['eTitle']}</h1>
      <div>{$a_Event['eBody']}</div>
</div>
END_HTML_FRAGMENT;
}


sort of thing.

the files event_1.inc, event_2.inc, etc look like ...

<?php
$a_Event = array
        (
        'eDate' => 'Sunday, 1st October 2008',
        'eTitle' => 'Richard\'s birthday',
        'eBody' => 'Come and have a beer or three and celebrate another year in the life of Richard.',
        );

sort of thing.


NOTE: All untested for syntax errors (sorry - on a crappy laptop).
Hielo, agree. For a newbie, event observation is probably not the first thing to learn.



VinceQ. The basic idea of nearly all "update part of a page and not the whole page" is to take a normal process (clicking on an anchor/link) and overriding its behaviour.

With prototype, you can use the Event.stop() method.

Different browsers deal with it in different ways. Cross platform compatibility is probably THE main reason to use a library.
Avatar of vinceq

ASKER

Hielo and RQuadling: thank you both for your time and effort. It looks like i should really do a little more research and get comfortable with the subject. I have a very basic understanding of PHP and Javascript, so what your saying is making some sense and i can slowly read thru and follow what's happening.
Just trying to improve my skill set and learn from the experts here.
thanks really
prototype is available at http://www.prototypejs.org
Also read the perfection kills blog at http://thinkweb2.com/projects/prototype/
I found that Kangax there offers a LOT of really useful tips on using Prototype well.

http://thinkweb2.com/projects/prototype/common-mistakes-and-how-to-avoid-them/

The first one there "1) Preventing default event behaviour:" is exactly what we are talking about.
Avatar of vinceq

ASKER

RQuadling-
Good deal, will check it out and read till my eyes bleed and click thru till I can my fingers tire! =)
Ha! And so you should. I remember when I first started out. Going from procedural to OOP was very very hard. Couldn't see the reason.

Now. Oh my god. How did I manage without it?

Its all about getting the right tools for the job.

And playing with them.

There are other script libraries out there. I came to prototype and it did all the things I wanted in a way I understood. You may find that mootools, or the Yahoo one is better for you.

Or you may find that you can roll your own (just make sure you test it on everything you can get your hands on IE6+, FF1+, Opera, Safari, Win/Mac/etc.)

>>Heilo -
It's Hielo

>>I tried yours and it definitely works but it opened the (april01.php) a new window, unless i goofed somehere.
Actually if it is opening in a new window, its really not working. I tested what I posted and it works. This leads me to believe that you probably missed the "; return false;" part on the links:
<a href="april1.php" onclick="showEvent(this.href); return false;">April 1</a>

If your <a> tag has only the href and the onclick event handler like I posted, it should work.
vinceq, did you get this working? read my previous post if you are still having problems.
Avatar of vinceq

ASKER

hielo - i copied the code you have...the link to april1.php and april6.php do not appear on the same page in the "eventDetails" div. Is that what's supposed to happen because that is my end goal. To have links on page and have a div fill with the php page contents. like when you include a header or footer using
<?php require_once('header.php'); ?>. That's what started me down this path...If i can include the heaeder and footer why cant i include events, when you click on a link.

But i know it's a little more complicated than that! =}

Please let me know if your example was intending to the the contents of april1.php or april6.php appear in the "eventsDetails" div.

thanks again
vinceq
Three scripts which hopefully show you a fully working example.

event.html - this is the main html page with the list of events.
april01.html - this is the HTML fragment for april 01
april02.html - this is the HTML fragment for april 02


event.txt
april01.txt
april02.txt
>>...s that what's supposed to happen because that is my end goal.
Yes. You must have missed something. Save the attached code as vinceq.html and run it EXACTLY as is (except you need to provide the correct links to april1.php and april6.php).

>>...If i can include the heaeder and footer why cant i include events, when you click on a link.
Because the #include is taking place on the server BEFORE the browser gets all the code. By the time you click on a link the browser already has ALL the data that the server was meant to give it. If you look at the source code in the browser you will not find server code.

>>Please let me know if your example was intending to the the contents of april1.php or april6.php appear in the "eventsDetails" div.
Again, YES. If you continue to have problems, it may be worth asking what does your april1.php file contain. Could it be possible that it contains inline javascript and that is what may be giving you problems?

At any rate, try saving the file below as vinceq.html and run it.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
 "http://www.w3.org/TR/REC-html40/loose.dtd">
 
<html>
<head>
<script type="text/javascript">
var xmlHttp=null;
 
function showEvent(url)
{ 
	window.xmlHttp=GetXmlHttpObject();
	if (window.xmlHttp==null)
	{
		alert ("Your browser does not support AJAX!");
	return null;
	}
 
	url=url+"&sid="+Math.random();
	try{
		window.xmlHttp.onreadystatechange=stateChanged;
		window.xmlHttp.open("GET",url,true);
		window.xmlHttp.send(null);
	}
	catch(e)
	{
		//alert(e.number + " " + e.description);
	}
return false;
}
 
function stateChanged() 
{ 
	if (window.xmlHttp.readyState==4)
	{ 
		document.getElementById("eventDetails").innerHTML=window.xmlHttp.responseText;
	}
	window.xmlHttp=null;
}
 
function GetXmlHttpObject()
{
	var xml_Http=null;
	try
	{
		// Firefox, Opera 8.0+, Safari
		xml_Http=new XMLHttpRequest();
	}
	catch (e)
	{
		// Internet Explorer
		try
		{
			xml_Http=new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e)
		{
			xml_Http=new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
return xml_Http;
}
</script>
</head>
 
<body>
<table border="1">
	<tr>
		<td><a href="april1.php" onclick="return showEvent(this.href);">April 1</a></td>
		<td><a href="april6.php" onclick="return showEvent(this.href);">April 6</a></td>
	</tr>
</table>
 
<div id="eventDetails">The events will replace this text</div>
 
 
</body>
</html>

Open in new window

Avatar of vinceq

ASKER

RQuadling - Thanks! yours does exactly what i need and want it to do. (but you knew that!)
Now if I can just figure out HOW it does it, i'll be golden. I appreciate it.
Avatar of vinceq

ASKER

hielo - i've tried and the "eventDetails" div still does not fill with the content. I stripped the april1 and april6 pages to just text on the page. BUT i'm on dreamhost and they have apparently been down for quite some time. I will be busily rushing to save my sites and try your solution again later.
ASKER CERTIFIED SOLUTION
Avatar of Richard Quadling
Richard Quadling
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of vinceq

ASKER

RQuadling -

Thanks! I see you added a little commentary, that's very nice of you. I will accept your solution.  

hielo, although yours works, i believe RQuadling has addressed my question and i am able to produce the correct results with his solution. If I could get yours to work i would split the points.
Avatar of vinceq

ASKER

RQuadling, I very much appreciate the time and effort you took to help me with my question. It is people like you who make this a great place. You could've stopped at directing me to the prototype site, but you went above and beyond by showing code and adding the comments about what each step is doing.  Thanks again, I hope i can be as proficient as you and help someone else down the line.

Cheers
Vince Q