Dynamically replace data inside a div container - javascript

What is the best way to load data dynamically inside a DIV container?
Let's say I have a number of pictures on a page. Clicking a picture opens a DIV container on the screen (no page refresh) which contains all comments for that image.
At the moment I am sending an AJAX request to load comments from the DB and echo them out in another page. I am then appending that data, with jQuery, inside the DIV container. Clicking on another image clears the container and new data is loaded vie new AJAX request.
It just seems to me that this might not be the most efficient way of doing it, because if the user is going back and forth clicking on images on the page, then data has to be reloaded every single time.
I see that facebook changes the URL every time when a new image is selected. So may be they use an ID from the URL to load the data without sending an AJAX request?
May be once data is loaded and another image is selected, it will be better to just hide the old image comments on the page rather than discard them ? So that if the image is clicked again, it will not be required to reload its data?

Here is an idea as to how you may avoid making frequent/duplicate ajax requests for the same image.
Say you've a function to draw comments in your div that acepts the reponse from the server, such as:
function displayComments(resp) {
//Do stuff
}
And let's assume an ajax call on image click looks like the following.
//We're probably better of using the wrapper (class/ID) of images to
//delegate events since setting/unsetting data may cause problems
//if we'd used bind on images directly
$("imagesContainerSelector").on("click", "img", function() {
var $this = $(this);
//See if comments have already been fetched previously.
//If yes, we'd have stored them as that image's data and
//we'd now simply use that data to display the comments.
if ( $this.data("comments") ) {
displayComments($this.data("comments"));
} else {
//We've not fetched comments for this image yet, so, fetch it
$.ajax({
url: '...',
data: '...'
//more options
}).done(function(data) {
//When done, display comments
displayComments(data);
//Set the resp as data for later use
$this.data("comments", data);
});
}
});

If you respecify the < img >-Tag inside some div so the pictures get loaded after you do that. If you specify the same picture twice or more times, the image is already in the cache of most browsers. Thatwhy you can just do something like
$('#divid').html(' < img src="..." > ');
If you want to preload your pictures, I would put some images into some very small div aside somewhere. If you put pictures into a hidden container some browsers wont preload them.
In case you stored your pictures into some database or memcache, use caching-headers. You might program some outputpicture.php?id=12345.
In that case something like
header('Content-Type: '.get_img_type($data));
header('Content-Length: '.strlen($data));
header("Pragma: public");
$expires = 60*60*24*14;
header("Cache-Control: maxage=".$expires);
header("Last-Modified: Mon, 26 Jul 1984 05:00:00 GMT");
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
could help alot.

you can add your get address in javascript object , and map the content loaded to it, every time you make ajax request.
then when user clicks on the image, instead of sending an ajax request, first check if you have that request in the object to load it from there, if you haven't the address in the object then you can proceed and send an ajax request and save its result to the object I mentioned.

Related

How to delay the pdf scan until page loads completely pdfcrowd api in php?

I am using pdfcrowd API for generating PDF from my dynamic PHP webpage, in which I am getting some data from DB and also running some jQuery functions with setTimeout function having 2 to 3 seconds delay at the bottom of page inside document ready function of jQuery.
This jQuery functions I am using to set page layout height dynamically based on content using Lightweight Responsive jQuery - Waterfall plugin, which takes some time to do that.
So, when I try to download PDF, it downloads page without running my JavaScript/jQuery function, which delay approx 2 to 3 second in it.
Code detail that I am using:
MyWebPage Code looks something like this:
//HTML + PHP code here at top of page
//jQuery code to set page height dynamically
function setContainerHeight(containerDiv) {
//function code here..
}
$(document).ready(function() {
setTimeout(
function() {
$(containerDiv).waterfall({gridWidth:[0,500,1000,1500,2000],gap:10});
setTimeout(function() {setContainerHeight(containerDiv);},2000);
},1000
);
});
Download Page
$client->setPageLayout(Pdfcrowd::CONTINUOUS);
$pdf = $client->convertURI($myWebPageUrl);
// Set HTTP response headers
header("Content-Type: application/pdf");
header("Cache-Control: no-cache");
header("Accept-Ranges: none");
header("Content-Disposition: attachment; filename=\"Resume.pdf\"");
// send the generated PDF
echo $pdf;
Please help me in this, how I can delay the PDF scan until my page loads completely.
Thanks in advance.
Since you can't hold webpage to render, as your JavaScript function is running after page load as usingsetTimeout, you should do whatever is required with page load only.
So, You should try calling your function setContainerHeight() after plugin work completion, means you should try call back function of plugin.
And remember to remove setTimeout as they will not be required, after using callback function. Moreover, if your plugin doesn't have callback, so you should mind calling your function from plugin file, though this is not correct way, but it should do the trick.
In your case, you should search for function named sorting in your waterfall API and add your function call in last of it.
Hopefully, this helps you..!!!
Your question does not clarify what the problem really is, may be a problem of the javascript not knowing when the PDF file has loaded fully, can you call it by an ajax call?
If you are loading the PDF to an IFrame you could try this:
$("#iFrameId").on("load", function () {
$(containerDiv).waterfall({gridWidth:[0,500,1000,1500,2000],gap:10});
});
If the problem is in php, may be the output of the PDF beeing slowed by the api you could stop the output buffer until the process is done by:
ob_start(); //at the begining
//Your code until echo
ob_end_flush(); //at the end

jQuery: Reload a DIV which was already loaded by AJAX (without url)?

I load a div by a simple
$('#thediv').load("theurl/param1/param2/param3");
The params differ - and I grab them from different points - depends on where the user clicks. (Different filter options..)
Now I'm searching for a simple way to reload this content with the url it was actually loaded - to avoid searching for the right filter params at this place. It is possible?
jQuery will not "save" the source of information on its own, but it is possible to specify it manually using the .data() method alongside the initial .ajax()
This means during the initial load, you can associate a URL with a div by saying something like .data("source-url","MY URL GOES HERE")
After that, you can look up that information the next time you want to reload it by using .data("source-url")
For Example:
function reloadDivs() {
// Look up all of the divs that we might want to reload
$("div.reloadable").each(function(i,el) {
// For each div, check to see if the source-url was set
// If it was set, re-run the ajax call
var $el = $(el);
if($el.data("source-url")
$el.load($el.data("source-url"));
});
}
$(function() {
// Set the initial source, change mypage.html to your actual source
$("#example-div").data("source-url","mypage.html");
$("#refreshbutton").click(reloadDivs);
});
Hope this helps!

Certain parts not loading on ajax requested page

I build this website: http://newslist.ca/
Recently, I changed it so when you chose something different from the drop down menu, the page updated immediately with the new feed. But I noticed that everything that should load based off of that new content doesn't load. Mainly: the sharing buttons, and the number of comments on each article?
What am I doing wrong, and how can I fix it?
$('.ajax').change(function() {
var url = "/?cat=" + $("select option:selected")[0].label + "&loc=" + $("select option:selected")[1].label + "&sort=" + $("select option:selected")[2].label;
console.log(url);
$.get(url, function (data) {
$('body').empty();
$('body').append(data);
})
});
The social media icons do not load when you refresh the page content entirely as they are inserted via JavaScript that is waiting for the document body to finish loading and fire an event. My thought is that your comment count method is using a similar method. Xymostech's comment above regarding using Ajax to load small bits of data into the page rather than the entire page contents is correct; you'll most likely want to load the comment counts as data with each item and leave the share tools in place (ie don't reload them) should you decide to revisit the Ajax method.

How can I regain program control after <cfheader> opens a PDF file?

This is a ColdFusion 8 question.
I have a cfm page that has a button that onClick calls the following Javascript function located in the page header:
function confirm_expiration_letters() {
var resultOfConfirm = confirm("Would you like to send expiration and reminder letters?");
if (resultOfConfirm == true) {
document.body.style.cursor = "wait";
window.location="_expiration_letters.cfm";
}
}
On the page that is called, a series of emails are generated, then a PDF report file is generated and displayed using these two lines:
<cfheader name="Content-disposition" value="attachment;filename=#fileName#">
<cfcontent type="application/pdf" file="#docPath#/#fileName#" deletefile="true">
Notice in the JS function that the cursor is changed to "wait". But the program control appears to get lost after the above cfheader call and so I can't find anywhere that I can reset the cursor back to:
document.body.style.cursor = "default";
Do you have ideas on where I can place this to turn off the cursor animation? I tried multiple places and it doesn't work. Once the cfheader and cfcontent calls happen, control of previous window and cursor are lost it appears.
You might try something like this above the cfheader.
<script>
document.body.style.cursor = "default";
</script>
<cfflush/>
The problem is that doing so might (probably will) screw up the cfheaders since cfflush is designed to flush partial results and will include the headers. But it's the only thing I can think of.
If I understand you correctly, you want to have a "wait" cursor whilst the PDF is prepped, and then return to a standard cursor after that.
Don't web browsers do this automatically when you're waiting for a requested document? IE: as soon as you do your window.location, whilst the document is loading, the cursors automatically changes to a "wait", and then once the doc is served, returns to an "auto".
This is what I see (when running code similar to yours). Is this not what you see?
Instead of changing the cursor, display a loading message using HTML/animated gif. When the PDF loads, it will replace the loading screen.
I would suggest having a hidden div containing your loading message, then use JavaScript to make it appear when needed.
Here's some JavaScript. This is how it would be done with jQuery.
function confirm_expiration_letters() {
var resultOfConfirm = confirm("Would you like to send expiration and reminder letters?");
if (resultOfConfirm == true) {
$('#Loading').fadeIn(); //SHOW THE LOADING INDICATOR
$.post('PDFGenerator.cfm', function(returnData){ // AJAX POST, CALLBACK
//RETURN THE FILENAME OR LOCATION OF THE PDF
var FileName = $.trim(returnData); // TRIM THE RETURNED DATA
window.open("path_to_file/" + FileName,"_blank"); // NEW WINDOW
$('#Loading').fadeOut(); // HIDE THE LOADING INDICATOR
});
}
}

Preloader for dynamic content

I have dynamic page which takes about 8 seconds to load searched data.
Problem is, all browsers remain on old page for those 8 secs & show dynamic page only after it
loads completely.
What I want is preloder image to be shown to the customers until second page gets load.
How can I achieve this?
Thanks
I assume you are loading the second page through AJAX. If so, you'll only be able to display the results after the asynchronous call returns.
However, nothing prevents you from making changes to the page before sending off the AJAX request. The basic structure will be:
var preload = $('<div></div>').text('I am preloading!').insertAfter('somewhere');
$.get(..., function() {
preload.remove();
// insert your real content, received from this AJAX request
});
$('<div id="busy">Loading...</div>')
.ajaxStart(function() {$(this).show();})
.ajaxStop(function() {$(this).hide();})
.appendTo('body');
That's all!
You may want to add some style to #busy tag, but this you can do with CSS.

Categories