Jump to content

Multiple Content Div Loading With Ajax/json


thrtst

Recommended Posts

I have implemented external content loading using Ajax. And now I would like to add multiple container loading functionality using a Json object code I have. Could you please help me incorporate the json object code into the Ajax code. My knowledge in coding is very limited :) Here is the detailed info: Here is the json object: var json = [{'id': 'content', 'wrapper': '__content-wrapper'},{'id': 'content', 'wrapper': '__content-wrapper'}] $.each(json, function(i, itm) {$('#'+itm.id).wrap('<div id="' + itm.wrapper + '"></div>');pageload(itm.id, itm.wrapper);}function pageload (id, wrapper) {} Here is the Ajax code: $(document).ready(function() { var contentWrapID = '___content-wrapper'; $('#content').wrap('<div id="' + contentWrapID + '"></div>'); function showNewContent() { $("#" + contentWrapID).slideDown(); $('#load').fadeOut(); } function pageload(hash) { if(hash) { $("#" + contentWrapID).load(hash + " #content",'',function(){ if($('img:last',this).get(0)) { $('img:last',this).load(function(){ showNewContent(); }); } else { showNewContent(); } }); } else { $("#" + contentWrapID).load("index.html #content"); } } $.historyInit(pageload); $('#topnav li a').click(function(){ var hash = $(this).attr('href'); hash = hash.replace(/^.*#/, ''); $("#" + contentWrapID).slideUp(300,function(){ $.historyLoad(hash); }); if(!$('#load').get(0)) { $('#container').append('<span id="load">LOADING...</span>'); } $('#load').fadeIn('normal'); $('#topnav li a').removeClass('current'); $(this).addClass('current'); return false; }); }); ........................ As far as I understand I have to replace this line:var contentWrapID = '___content-wrapper';with the json object:var json = [{'id': 'content', 'wrapper': '__content-wrapper'},{'id': 'content2', 'wrapper': '__content-wrapper2'}]; But I also have to change the pageload function so that it works with the new variables that are passed:function pageload (id, wrapper) {} I'd be very grateful for any help Best regardsPaul

Link to comment
Share on other sites

Start by using different IDs in the JSON object. This part loops through the JSON object and sets up the wrapper for each item, so make the IDs and wrapper IDs different for each item in the JSON object:

var json = [{'id': 'content', 'wrapper': '__content-wrapper'},{'id': 'content', 'wrapper': '__content-wrapper'}] $.each(json, function(i, itm) {  $('#'+itm.id).wrap('<div id="' + itm.wrapper + '"></div>');  pageload(itm.id, itm.wrapper);}

I'm not sure how most of jQuery works, so I'm not sure what most of the code does. I don't know what historyInit and historyLoad do, for example, so I don't know if you can use historyLoad to pass more than one parameter to pageload. It looks like pageload gets passed to historyInit, and then the hash parameter (the part of the URL after #) gets passed to historyLoad, which I assume passes the value to pageload (since pageload seems to be looking for that). You could try replacing this:

$("#" + contentWrapID).slideUp(300,function(){  $.historyLoad(hash);});

With this:

$.each(json, function(i, itm) {  $("#" + itm.wrapper).slideUp(300,function(){	$.historyLoad(hash, itm.id, itm.wrapper);  });});

Then to see if that works you could just have pageload print everything:

function pageload (hash, id, wrapper) {  alert(hash);  alert(id);  alert(wrapper);}

If that works as expected, then you can modify the existing pageload function to use the passed wrapper ID instead of the global one.

Link to comment
Share on other sites

Start by using different IDs in the JSON object. This part loops through the JSON object and sets up the wrapper for each item, so make the IDs and wrapper IDs different for each item in the JSON object:
var json = [{'id': 'content', 'wrapper': '__content-wrapper'},{'id': 'content', 'wrapper': '__content-wrapper'}] $.each(json, function(i, itm) {  $('#'+itm.id).wrap('<div id="' + itm.wrapper + '"></div>');  pageload(itm.id, itm.wrapper);}

I'm not sure how most of jQuery works, so I'm not sure what most of the code does. I don't know what historyInit and historyLoad do, for example, so I don't know if you can use historyLoad to pass more than one parameter to pageload. It looks like pageload gets passed to historyInit, and then the hash parameter (the part of the URL after #) gets passed to historyLoad, which I assume passes the value to pageload (since pageload seems to be looking for that). You could try replacing this:

$("#" + contentWrapID).slideUp(300,function(){  $.historyLoad(hash);});

With this:

$.each(json, function(i, itm) {  $("#" + itm.wrapper).slideUp(300,function(){	$.historyLoad(hash, itm.id, itm.wrapper);  });});

Then to see if that works you could just have pageload print everything:

function pageload (hash, id, wrapper) {  alert(hash);  alert(id);  alert(wrapper);}

If that works as expected, then you can modify the existing pageload function to use the passed wrapper ID instead of the global one.

@ Justsomeguy Thanks a ton for the reply:I have begun editing, and was wondering- Is this what you meant :Replacing:
var contentWrapID = '___content-wrapper';		$('#content').wrap('<div id="' + contentWrapID + '"></div>');

With:

var json = [{'id': 'content1', 'wrapper1': '__content-wrapper'},{'id': 'content2', 'wrapper2': '__content-wrapper'}] $.each(json, function(i, itm) {  $('#'+itm.id).wrap('<div id="' + itm.wrapper + '"></div>');  pageload(itm.id, itm.wrapper);}

???

Link to comment
Share on other sites

You would probably leave out the call to pageload there, it's not in the code you're replacing. If you remove the contentWrapId variable you'll need to replace anywhere which uses that or looks for the #content element with a loop to go through the JSON object and do the same thing using each id and wrapper there.

Link to comment
Share on other sites

You would probably leave out the call to pageload there, it's not in the code you're replacing. If you remove the contentWrapId variable you'll need to replace anywhere which uses that or looks for the #content element with a loop to go through the JSON object and do the same thing using each id and wrapper there.
@justsomeguy - Thanks sir,I'm not quite sure where to add this code ?! Please advise...
function pageload (hash, id, wrapper) {  alert(hash);  alert(id);  alert(wrapper);}

I also get a syntax error at line 9, I think I might have a parenthesis somewhere its not supposed to be, Here is what the code looks like right now! Please advise ...

$(document).ready(function() {   var json = [{'id': 'content1', 'wrapper1': '__content-wrapper'},{'id': 'content2', 'wrapper2': '__content-wrapper'}] $.each(json, function(i, itm) {  $('#'+itm.id).wrap('<div id="' + itm.wrapper + '"></div>'); }	function showNewContent() {		$("#" + contentWrapID).slideDown();		$('#load').fadeOut();   	}		function pageload(hash) {		if(hash) {			$("#" + contentWrapID).load(hash + " #content",'',function(){				if($('img:last',this).get(0)) {					$('img:last',this).load(function(){						showNewContent();					});				} else {					showNewContent();				}			});		} else {			$("#" + contentWrapID).load("index.html #content");		}	}	$.historyInit(pageload);		$('#topnav li a').click(function(){				var hash = $(this).attr('href');		hash = hash.replace(/^.*#/, '');		$.each(json, function(i, itm) {  $("#" + itm.wrapper).slideUp(300,function(){	$.historyLoad(hash, itm.id, itm.wrapper);  });});		if(!$('#load').get(0)) {			$('#container').append('<span id="load">LOADING...</span>');		}		$('#load').fadeIn('normal');		$('#topnav li a').removeClass('current'); 		$(this).addClass('current'); 		return false;					});});

Link to comment
Share on other sites

I'm not quite sure where to add this code ?! Please advise...
That's a replacement for the pageload function to just print what you send it to verify that it's being called with the correct arguments.
I also get a syntax error at line 9
The $.each function is missing a closing paren.
Link to comment
Share on other sites

That's a replacement for the pageload function to just print what you send it to verify that it's being called with the correct arguments.The $.each function is missing a closing paren.
Hmm... Sir, I'm not sure how to implement this:
If you remove the contentWrapId variable you'll need to replace anywhere which uses that or looks for the #content element with a loop to go through the JSON object and do the same thing using each id and wrapper there.
In other words how would the replacement code that loops back to the json object look like ??
Link to comment
Share on other sites

@justsomeguy - Thank you sir:A. So basically what I have done is replaced this:

$("#" + contentWrapID)
with this:
$.each(json, function(i, itm) { $("#" + itm.wrapper)
Please advise....B. Likewise what would be the replacement for (#content) part in the new modified code ??!
Link to comment
Share on other sites

Oh sorry I used quotes instead of code wrap tags:For clarity reasons I re-post:I have replaced:

$("#" + contentWrapID)

with this:

$.each(json, function(i, itm) {$("#" + itm.wrapper)

Please advise....What would be the replacement for this:

#content

Link to comment
Share on other sites

Hmm Sorry for the slow catch-up:I just observed that this:

 $('#content')

in the original code has been replaced by this:

$.each(json, function(i, itm) {  $('#'+itm.id)

Whereas this:

('<div id="' + contentWrapID + '"></div>')

in the original code has ben replaced by this:

('<div id="' + itm.wrapper + '"></div>')

But somewhere down the line this:

$("#" + contentWrapID)

has vise versa been replaced by this:

$.each(json, function(i, itm) {  $("#" + itm.wrapper)

Please advise....

Link to comment
Share on other sites

Your original code has something like this:

$("#" + contentWrapID).load(hash + " #content",'',function(){...});

That gets an element with an ID that matches the contentWrapID variable, and loads it with the value of the hash variable plus "#content", which idenfities an element with an ID of "content". I'm not sure specifically what jQuery's load method does, but it's being passed the ID of an element. So the wrapper ID is in a variable, and the ID of the element to load the content is hard-coded, they just wrote "content" for the ID. Instead of writing the ID of the element to load content into, you need to loop through the JSON array and run the code for each content and wrapper ID. So instead of code like what's above where it uses a global variable and then has the other ID hardcoded, you need to use $.each to loop through the array and use the IDs from that. So that would change the code above to something like this:

$.each(json, function(i, itm) {  $("#" + itm.wrapper).load(hash + " #" + itm.id,'',function(){  ...  });});

Notice how the IDs are replaced by the values from the array. Compare the two pieces of code together to see the differences:

$("#" + contentWrapID).load(hash + " #content",'',function(){...});

$.each(json, function(i, itm) {  $("#" + itm.wrapper).load(hash + " #" + itm.id,'',function(){  ...  });});

So that's what you need to do where the code is trying to access the content or wrapper elements.

Link to comment
Share on other sites

Thank yet again sir:I'm almost done with the pre-testing phase... Atleast I hope so :)I am geting a syntax error on line 15 here:

function pageload(hash) {

Here is the entire code at the moment:

$(document).ready(function() {   var json = [{'id': 'content1', 'wrapper1': '__content-wrapper'},{'id': 'content2', 'wrapper2': '__content-wrapper'}] $.each(json, function(i, itm) {  $('#'+itm.id).wrap('<div id="' + itm.wrapper + '"></div>'); });	function showNewContent() {		$.each(json, function(i, itm) {  $("#" + itm.wrapper).slideDown();		$('#load').fadeOut();   	}		function pageload(hash) {		if(hash) {			$.each(json, function(i, itm) {  $("#" + itm.wrapper).load(hash + " #" + itm.id,'',function(){				if($('img:last',this).get(0)) {					$('img:last',this).load(function(){						showNewContent();					});				} else {					showNewContent();				}			});		} else {			$.each(json, function(i, itm) {  $("#" + itm.wrapper).load("index.html " #" + itm.id");		}	}	$.historyInit(pageload);		$('#topnav li a').click(function(){				var hash = $(this).attr('href');		hash = hash.replace(/^.*#/, '');		$.each(json, function(i, itm) {  $("#" + itm.wrapper).slideUp(300,function(){	$.historyLoad(hash, itm.id, itm.wrapper);  });});		if(!$('#load').get(0)) {			$('#container').append('<span id="load">LOADING...</span>');		}		$('#load').fadeIn('normal');		$('#topnav li a').removeClass('current'); 		$(this).addClass('current'); 		return false;					});});

Link to comment
Share on other sites

Almost there, But I'm not getting this part right:What am I supposed to do with this :

else {			$("#" + contentWrapID).load("index.html #content");		}

Should I do replace with this:

else {			$.each(json, function(i, itm) {  $("#" + itm.wrapper).load("index.html + itm.id");		});		}

Please advise..

Link to comment
Share on other sites

@justsomeguy Hmm...! Think I've fallen inte a small trap as I went on to test the script.As I mentioned earlier I have to sets av navigation menus marked up, layout in css. That means I have two different unordered list elements. But only one of these two is defined in the java script:

$('#topnav li a').click(function(){

How do I go about including the other set of navigation menu ?!Source code:Top navigation menu:

<ul id="topnav"><!--BEGIN TOP NAVIGATION BAR-->					<li id="topnav-home"><a href="index.html" title="Home" class="current"><span>Home</span></a></li>					<li id="topnav-featured"><a href="featured.html" title="Featured"><span>Featured</span></a></li>					<li id="topnav-contact"><a href="contact.html" title="Contact"><span>Contact</span></a></li>					</ul>

vertical navigation menu:

<ul id="vert-navbar"><!--BEGIN NAVIGATION BAR-->				<li id="vert-navbar-1"><a href="news.html" title="News" class="current"><span>News</span></a></li>				<li id="vert-navbar-2"><a href="videos.html" title="Videos"><span>Videos</span></a></li>				<li id="vert-navbar-3"><a href="comments.html" title="Comments"><span>Comments</span></a></li>				<li id="vert-navbar-4"><a href="downloads.html" title="Downloads"><span>Downloads</span></a></li>				<li id="vert-navbar-5"><a href="photo-gallery.html" title="Photo Gallery"><span>Photo Gallery</span></a></li>			</ul><!--END NAVIGATION BAR-->

Link to comment
Share on other sites

You're really going to need to rewrite most of the code, this isn't a line-by-line replace. The code started where it's loading content into a specific element with a variable wrapper. You want it to load content in many variable elements with many variable wrappers. So large parts of the code need to go inside loops where you loop through the IDs of everything and perform the actions on each one. Some parts, like this near the top:

$(document).ready(function() {  var contentWrapID = '___content-wrapper';  $('#content').wrap('<div id="' + contentWrapID + '"></div>');...

For that last line, that's only a single line doing something specific for the one element, so you can replace that with a loop that does the same thing to all of the elements.The next line which gets executed is this line:$.historyInit(pageload);Like I said, I'm not real familiar with jQuery so I have to be a little abstract, but I assume that line passes the pageload function to the historyInit method, and later in the code it looks like pageload gets executed by the historyLoad function. So there's probably nothing that needs to be changed about that line.The next part which gets executed is this code which assigns click events to the various links in the topnav element:

$('#topnav li a').click(function(){  var hash = $(this).attr('href');  hash = hash.replace(/^.*#/, '');  $("#" + contentWrapID).slideUp(300,function(){	$.historyLoad(hash);  });  if(!$('#load').get(0)) {	$('#container').append('<span id="load">LOADING...</span>');  }  $('#load').fadeIn('normal');  $('#topnav li a').removeClass('current');   $(this).addClass('current');   return false;});

So, you need to understand what that does if you want to change it.These two lines:var hash = $(this).attr('href');hash = hash.replace(/^.*#/, '');get the hash portion of the URL. So if the url of the page is this:http://domain.com/dir/page.html#targetthen those lines would set the hash variable to "target". The next lines are these lines:

  $("#" + contentWrapID).slideUp(300,function(){	$.historyLoad(hash);  });

So that targets the wrapper element and runs the slideUp method on it, and it passes a function to slideUp which calls the historyLoad method and passes it the hash variable. I assume the function that gets passed to slideUp probably executes when the animation finishes, so basically what that code does is slide the wrapper element and then run historyLoad once that finishes.So, you need to think about what that means with what you want to do. If you want everything to happen on your page at once, then you would wrap those entire lines into one the $.each loops which go through the JSON array, and replace the contentWrapID variable with the value for the wrapper ID from the array.But, here's a problem. If historyLoad ends up running the pageload function, and passing the hash variable to it, then we need to look at what pageload does. So, look at pageload:

function pageload(hash) {  if(hash) {	$("#" + contentWrapID).load(hash + " #content",'',function(){	  if($('img:last',this).get(0)) {		$('img:last',this).load(function(){		  showNewContent();		});	  } else {		showNewContent();	  }	});  } else {	$("#" + contentWrapID).load("index.html #content");  }}

pageload takes a parameter called hash (presumably the same hash value which was calculated earlier). This line:if(hash) {checks if hash is empty. If the URL looks like this:http://domain.com/dir/page.htmlthen hash will be empty. It will only have a value if the URL looks like this:http://domain.com/dir/page.html#targetSo, if hash is empty then it goes to the else part and only runs this line:$("#" + contentWrapID).load("index.html #content");So, that line looks for the wrapper element and the content element. The IDs for those elements are here:$("#" + contentWrapID).load("index.html #content");So, those two IDs need to get replaced with the values from the JSON array. So, how to do that? Look back at how pageload got executed in the first place:

  $("#" + contentWrapID).slideUp(300,function(){	$.historyLoad(hash);  });

...So, you need to think about what that means with what you want to do. If you want everything to happen on your page at once, then you would wrap those entire lines into one the $.each loops which go through the JSON array, and replace the contentWrapID variable with the value for the wrapper ID from the array.

(yeah, I just quoted myself from the same post. I think that's a new one)So if you wrap those lines in a loop to do that for each element, which ends up calling pageload through historyLoad for every element in your JSON array, then that means pageload gets executed once every time any element finishes the slide animation.So, pageload needs to know which elements to target. You can't have a loop in pageload which loops through every element, because pageload gets called every time an element finishes. If every time pageload gets called it loops through every element, then that's a lot of looping. If you have 10 elements on the page which animate, you would end up running the code in pageload 100 times instead of 10 times (once after each element finishes).That means that pageload needs to only work on one element, and it needs to know which one it's supposed to work on.That's why I suggested replacing those lines above with this:
$.each(json, function(i, itm) {  $("#" + itm.wrapper).slideUp(300,function(){	$.historyLoad(hash, itm.id, itm.wrapper);  });});

That loops through the array, and for each item in the array it passes the hash value, plus the IDs of the elements to work on. Then I suggested temporarily replacing pageload with this:

function pageload (hash, id, wrapper) {  alert(hash);  alert(id);  alert(wrapper);}

just to verify that historyLoad does pass the extra values to pageload and that pageload has the two IDs it needs to work on.Once we know if that's true, then you can look at the code for pageload and showNewContent, which pageload executes, and figure out how you to set those up so that they both only work on the IDs that were sent to them.

Link to comment
Share on other sites

And also... Also... I need that it be defined that clicking #topnav tabs loads to content1 and that clicking the #vertnav-bar tabs loads to content2Have we defined this somewhere ?!

I haven't defined that anywhere, that's the first I'm hearing of this. That's basically an entirely different setup than what you have now.

Link to comment
Share on other sites

Oh .. Incredibly educational ... thank you sirAfter reading through your last tutorial, I realized I absolutely should have given you that last piece of information first and foremost...! I apologize !But basically that was my entire intention i.e,1. To be able to load content into, (lets call it #div 1) extracted from a corresponding #div in a html page, (lets call it featured.html) with a click on any of the tabs in the 1st navigation menu, (lets call it #topnav).2. To be able to load content into, (lets call it #div 2) extracted from a corresponding #div in another html page, (lets call it news.html) with a click on any of the tabs in the second navigation menu, (lets call it #vertnav-bar). P.S Only one div gets loaded for every click. (From what you explained I think this particular detail is important that i mention with regards to the pageload calling function. In other words at no one given point in time will a click be loading data to more than one #div As regards to historyIntit part, it has to do with the fact that this particular ajax script kills the back and forward functionalities of the browser. So this is corrected with the help av a jquery history library javscript file aka history plugin and I think this is what is being refered to. I link to history.js in the <head> of the source file.Please advise..I apologize for the luck of clarity on this part!

Link to comment
Share on other sites

There's really only so much I can do to help, in the end you're going to need to do this yourself. It's important to understand how the code works, if you don't understand how it works then that would be your first step. The general Javascript tutorials on this site are a good resource for learning the very basics of how Javascript works, and I'm sure that jQuery has tutorials or references available to explain to Javascript programmers how jQuery works. Hopefully my previous explanation of the code will be helpful, but it's going to be your responsibility to write the code that you need to do what you're trying to do. I'm willing to help answer questions you may have, but I can't write all of the code for you, that's not going to help you.

Link to comment
Share on other sites

@justsomeguy Sir! I understand Sir. Iam understanding more and more of the basics of how javascript works. But studying a working example helps alot in my learning process. Also being able to compare and contrast helps alot.I know now that I was heading the wrong direction. Please get me started alteast into the right direction. What the current script does of now is loading all the content divs defined in the array whenever I click on a #topnav tab.But my quest different and I apologize for this. What I need right now is if you could be so kind to point me in the right direction to begin with. But be certain that I've read through your tutorial over and over again and I'm getting better at explaining what things mean.I've been sitting here all day hoping for some help so please give me a little push greatly appreciate your time!

Link to comment
Share on other sites

You'll just need to think about specifically want you want to do, and then how to do it. The first thing to do is to attach click events to your links, so that when you click the link it runs some code. That code can just start as an alert box so that you can verify that clicking the link actually ran the code. Once you have the click events hooked up to your links, the next thing to figure out is how to determine which link you clicked on. I'm sure that jQuery's click event will send the clicked element to the event handler, so the event handler can check various attributes of the element to figure out which element it was. e.g., if you have a link like this:<a rel="link1">Then you can get the "rel" attribute to see that it was "link1", and then you know which link was clicked on. Once you know which link you clicked on, you can go from there to figure out what you want to do based on which link they clicked. So you could store the ID of a certain piece of content you want to load in an attribute, or you can store the ID of the div that you want to load the content into, etc.jQuery has several tutorials to help. You'll need to know how events, event handlers, selectors, and ajax work. The effects part will also tell you how to do things like the animations. You'll definitely need to understand what a callback or handler is. When you have code like this:

function handler(){  alert(this.id);}var el = document.getElementById('div1');el.addEventListener('click',handler,false);

That gets an element and attaches a handler to handle the click event, so when you click on that element it will execute the handler. Javascript and jQuery in particular use handlers or callbacks a lot, that's how jQuery does most of what it does. Handlers and callbacks are both names for the same thing. If you don't understand functions or events in Javascript in general, that's where the tutorials on w3schools will come into play.

Link to comment
Share on other sites

Earlier on before integrating the json object, I did try to have one different javascript file for every #ul element. My reasoning here was that this was possible since the content loading functionality was coupled to and defined to only take effect on one specific #ul element as defined here:

$('#topnav li a').click(function(){

and replacing it with:

$('#vertnav-bar li a').click(function(){

in the new file so that the click function is applied on the 2nd navigation menu.In the same manner I think that the content loading functinality is applied to one specifc #div element as defined here:

var contentWrapID = '___content-wrapper';		$('#content').wrap('<div id="' + contentWrapID + '"></div>');

so replacing it with:

var contentWrapID = '___content-wrapper2';		$('#content2').wrap('<div id="' + contentWrapID + '"></div>');

in the new javascript file would apply the click funciton to the 2nd #div.Would this be the way to go ?! I have a feeling it is much more complicated than this... Please advise...

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...