How to append data from another PHP file - javascript

I am using jQuery waterfall as a responsive grid layout.
I was using masonry, and had a load more button function but I am modifying what I have and trying to understand what the code does.
So for the load more button I have this:
$(document).ready(function(){
var pageIndex = 1;
$('#loadmorebuilds-div').click(function() {
$("#buildcontainer").append('<div class="blogresults"><br><br></div>');
});
});
In theory, this works fine. However I have another page which loads all of the extra content from my database.
This is what have used before:
$(document).ready(function(){
var pageIndex = 1;
$('#loadmorebuilds-div').click(function() {
$('.countvar').detach();
$('#buildcontainer').imagesLoaded( function(){
$.ajax({
url: 'includes/loadmorebuilds.php?type=' + type + '&pageIndex=' + pageIndex,
success: function(html) {
var el = $(html);
$("#buildcontainer").append(el);
$("#loadmorebuilds-div").stop().fadeOut();
pageIndex++;
var rowCount = $(".countvar").html();
if (rowCount < 16) {
$('#loadmorebuilds-div').remove();
$('.countvar').detach();
} else {
$('.countvar').detach();
}
}
});
});
});
});
This also works, and does load the new data but seems to load the data and not fit it into the grid properly. One of the results sit underneath the others, but the other ones overlap in the top left and sit underneath others etc.
I can manually append as many divs using the first example and it works fine.
Also when using the second example the items seem to refresh and appose to just the new data being loaded.
In my eyes, its to do with this:
success: function(html) {
var el = $(html);
Is there a better way to get the content from the requested page and simply append it back to the div.
The page that is called simply run a query on the database and echoes out the divs in a foreach statement. So the div layout would just be e.g.
<div class="blogresults"></div>
Any ideas on this one?

on the ajax success event you should do this:
success: function(data) {
$('blogresults').html(data);
}

Searched arround the examples in the waterfall folder and it seemed to use a 'reflow' feature with works the same (i guess) and the masonry 'reload'.
Tried it as
$("#buildcontainer").append(html).waterfall('reflow');
And it works :)

Related

How to format webpage before it is loaded javascript

Ok. I am making a website on github using html and javascript. Earlier, I was using a template to make simple, formatted webpages. I got it to work, but it has an annoying bug: the unformatted webpage shows up before the formatted one. I am using the latest version of jquery (2.1.4) hosted from google and the javascript below:
var heading = document.getElementById("heading").innerHTML;
var pghead = document.getElementById("pghead").innerHTML;
var pgtext = document.getElementById("pgtext").innerHTML;
var template = function () {
var tmp = null;
$.ajax({
'async': false,
'dataType': 'html',
'url': "https://jediguy13.github.io/template.html",
'success': function (data) {
tmp = data;
}
});
return tmp.split("derp");
}();
document.write(template[0] + heading + template[1] + pghead + template[2] + pgtext + template[3]);
document.getElementById("heading").innerHTML = "";
document.getElementById("pghead").innerHTML = "";
document.getElementById("pgtext").innerHTML = "";
And here's a sample webpage:
<div id="heading">Test</div>
<div id="pghead">Test</div>
<div id="pgtext">This is some text in the main body of the webpage</div>
As you can see from the 'async': false. line, Jquery is requesting the template webpage at the same time as the main thread. However, there is always a slight delay in the formatting. I'm betting it is because the document.write is called near the end. What is a better way to get the browser to display just the formatted page?
Example page: website
Don't use document.write(). Ever. If you have an HTML snippet, just attach it to the desired node like this:
$("body").html(template[0] + ...);
If the page is originally empty and all the content is loaded with AJAX, then you'll see a white page that then is filled with your code.
In your case it will NOT be empty as I can guess, so you have to clear the HTML immediately after you fetch it:
heading = $("#heading").html();
$("#heading").html("");
This will minimize the original exposure of the HTML.
At this point you may want to fade it in slowly, like this:
$("body").hide();
// ... make AJAX call and attach it as shown above
$("body").fadeIn();
The fadeIn() is a touch of class you might as well replace with show().
Make the AJAX call asynchronous and put all of this into the AJAX success() method.
This is all together in a complete rewrite. Just copy+paste and tell me if it's working:
var heading, pghead, pgtext;
$("body").hide();
heading = $("#heading").html();
pghead = $("#pghead").html();
pgtext = $("#pgtext").html();
$("#heading").html("");
$("#pghead").html("");
$("#pgtext").html("");
$.ajax({
'async': true,
'dataType': 'html',
'url': "https://jediguy13.github.io/template.html",
'success': function (data) {
template = data.split("derp");
$("body").html(template[0] + heading + template[1] + pghead + template[2] + pgtext + template[3]);
$("body").fadeIn();
}
});
Okay, so first off I'm going to say you shouldn't rely on JS to format your entire page unless you're hosting a single-page application, and even then... probably not the entire page.
To answer your question, the only way to not show the unformatted page is to hide your content until the page loads. Give your body tag or container style='display:none;' and then when your JS has finished executing, show the content with by calling something like $('body').show().
one of my favourite tricks is to place a loader div and keep the content hidden and the loader visible until all JS based layout changes are completed. provided you have the luxury of using Jquery (or CSS3) you can use an easing effect on the opacity to give it a much better feel.

Only apply jQuery waterfall 'reflow' after the images have loaded

i am using jQuery waterfall for my grid style display.
To stop the common images overlapping issue i have wrapped the waterfall method in a .load() function such as:
$(window).load(function(){
$('#buildcontainer').waterfall({
colMinWidth: 260,
defaultContainerWidth: 1000,
autoresize: true
});
});
The images overlap because the waterfall function is called before the images have fully loaded there for their height cannot be determined. Wrapping the function in the load function prevents this.
The problem is, i have a button which loads more database results via ajax and appends them to the container.
When the items are appended, the images overlap. jQuery waterfall comes with a 'reflow' function which re sorts all of the items inside the container.
In my ajax success i run it like so:
success: function(html) {
$("#buildcontainer").append(html).waterfall('reflow');
}
The issue i see here is that the images are being appended, and then the waterfall function is being called but the images are not yet fully loaded.
Is there a way i can only run the waterfall('reflow') after the items have fully loaded. In the same style as the:
$(window).load(function(){
});
I have tried wrapping the line where the items are appended into this function, i have also tried just appending the items and then applying the reflow inside a .load function but both of these dont append any items.
Any help / ideas on what to try next? Thanks!
Note: The images dont overlap in FF, but do in chrome and safari.
Thanks!
Have a look at the imagesLoaded library / jquery plugin: http://imagesloaded.desandro.com/
Try this in your success function:
success: function(html) {
$("#buildcontainer").append(html);
var loaded = 0,
imgs = $("img"),
totalImgs = imgs.length;
imgs.load(function() {
++loaded;
// Check if all images have loaded
if (loaded === totalImgs) {
// Run waterfall
$('#buildcontainer').waterfall('reflow');
}
});
}
Assuming all the images are being added in here:
success: function(html) {
$("#buildcontainer").append(html).waterfall('reflow');
}
Then, you can do the following to monitor them all after adding them:
success: function(html) {
function checkCnt() {
if (remainingCnt === 0) {
$("#buildcontainer").waterfall('reflow');
}
}
var remainingCnt = $("#buildcontainer").append(html)
.find("img")
.filter(function() { return !this.complete; })
.load(function() {
// one more is loaded now, see if they are all loaded
--remainingCnt;
checkCnt();
}).length;
checkCnt();
}

how do I target a specific id with ajax?

I'm trying ajax (and to a degree a lot of js) for the first time so I'm not sure what I'm doing wrong.
The goal is that a series of thumbnails in a sidebar will change the content of a centrally located div when selected. The link currently looks like this:
<img src="images/thumbs/elon-scissors-logo.jpg" onclick="reloadMiddleWith('about','about','test')"/>
When clicked it runs the below function and changes the background and calls a php source.
function reloadMiddleWith(theme, page, content) {
var new_url = "http://www.chrisjohndesigns.com/" + page + ".php/#" + content;
$('#live-area').addClass(theme);
$.ajax({
url: new_url,
dataType: 'html'
})
.done(function(data) {
// Assuming the request returns HTML, replace content
$('#area-loader').html(data);
});
}
I tested that and it worked fine when it was just the background and the new php page, but rather than making 50 pages to call in (and not even trying arrays or databases at the moment for lack of proper understanding) I thought I would just make 1 or 2 new page that repeat the same container style and just call the one I want to display by id tag. Currently when I try it, it just changes the background but does not change the php content.
The jQuery itself has a handy function jQuery(...).load, using it jQuery would handle all the necessary points:
function reloadMiddleWith(theme, page, content) {
var new_url = "http://www.chrisjohndesigns.com/" + page + ".php/#" + content;
$('#live-area').addClass(theme);
jQuery("#area-loader").load(new_url);
}
for more information check documentation page out.

Help me make a jquery AJAXed divs' links work like an iframe

I want to make a few divs on the same page work similar to iframes. Each will load a URL which contains links. When you click on those links I want an AJAX request to go out and replace the div's html with new html from the page of the clicked link. It will be very similar to surfing a page inside an iframe.
Here is my code to initially load the divs (this code works):
onload:
$.ajax({
url: "http://www.foo.com/videos.php",
cache: false,
success: function(html){
$("#HowToVideos").replaceWith(html);
}
});
$.ajax({
url: "http://www.foo.com/projects.php",
cache: false,
success: function(html){
$("#HowToProjects").replaceWith(html);
}
});
This is a sample of code that I'm not quite sure how to implement but explains the concept. Could I get some help with some selectors(surround in ?'s) and or let me know what is the correct way of doing this? I also want to display a loading icon, which I need to know where the right place to place the function is.
$(".ajaxarea a").click(function(){
var linksURL = this.href; //
var ParentingAjaxArea = $(this).closest(".ajaxarea");;
$.ajax({
url: linksURL,
cache: false,
success: function(html){
$(ParentingAjaxArea).replaceWith(html);
}
});
return false;
});
$(".ajaxarea").ajaxStart(function(){
// show loading icon
});
Assuming you want to listen to click events for all anchor tags inside all elements with class ajaxarea, then your selector works fine:
$(".ajaxarea a").click(function(){ .. });
And this line of code, while not a selector (you're just accessing a property on the DOM element that was clicked), should work fine as well:
var linksUrl = this.href;
As for ParentingAjaxArea, you'll need to use $(this).closest() with a selector to determine which parent you want, but it's hard to give a specific example without knowing your HTML structure. It looks like you want ParentingAjaxArea to be either the element with id #HowToProjects or #HowToVideos, so you could write:
var ParentingAjaxArea = $(this).closest("#HowToProjects, #HowToVideos");
As for the loading dialog, I think this answer explains a good method (using ajaxStart and ajaxStop).
Edit: I also noticed you're using the click event--If you plan on being able to attach event handlers to links that will be inserted into the DOM via AJAX later, look at delegate or live.
$(".ajaxarea a").live('click',function(e){
e.preventDefault(); //*
var URL = $(this).attr('href');
var parentFrame = $(this).parent(".ajaxarea"); //**
$.ajax({
url: URL,
cache: false,
success: function(html){
parentFrame.replaceWith(html); //***
}
});
});
* - added preventDefault to prevent click action (see e in function's arguments)
** - instead of closest, i used parent – like it more for it's descriptive qualities
*** - the var containing parent AJAX frame should be jQuery object, no need to wrap it in $(..)
This should work fine, but beware, it's untested.
edit:
You probably need a live (okay, I'm sure you need it). what click() does it's that it adds to all elements at the time in DOM an onClick event. What live() does, it's that it waits for any change in DOM and runs used selector (.ajaxarea a) again and if it fits for any of new elements, it adds the action. In pseudocode, it does basically this:
DOM.hasChanged{
$('selector').click(..)
}
I used this example for my own web page:
http://www.queness.com/post/328/a-simple-ajax-driven-website-with-jqueryphp
It works quite well and uses hash tags and jQuery.history.js for the history of your browser. It works very nice, because you can let something like a media player just continue playing. Take a look at my own site elsewise, where you can find the javascript file: ajaxpages.js. I haven't used live(), but maybe I should.
Figured it out! The problem was I was using the function ".replacewith()" which was removing my AJAXed div(class="ajaxarea") entirely instead of replacing the content. The proper function to use here was ".html()".
Here is my working code to make an AJAXed div work like an iframe:
//onload to initialize the div
$.ajax({
url: "http://www.foo.com/projects.php",
cache: false,
success: function(html){
$('#HowToProjects').html(html);
}
});
$(".ajaxarea a").live('click',function(e){ // must use live instead of .click()
e.preventDefault();
var URL = $(this).attr('href');
var parentFrame = $(this).closest(".ajaxarea");
$.ajax({
url: URL,
cache: false,
success: function(html){
parentFrame.html(html);
}
});
});

jquery .attr() class switch not working

I'm working on a web service,
when the user requests more data through ajax, I want the div that will contain the data to show a loading circle. I wrote a css class in the style file for when I want the circle:
.ajax_getTeams_loading{
background: url('ajax-loader.gif') no-repeat center center;
}
So my ajax function is like this:
function(profile, divId){
$('#' + divId).attr('class', 'goose');
/*$.get('testGetTeams.php', {username: profile}, function(data) {
$('#' + divId).html(data);
});*/
}
The problem is that the circle never shows up. I tried simplifying the css class to just background-color:blue, but that didn't even work. I also removed the ajax part entirely, and it still doesn't work at all. What am I doing wrong?
At this point I don't see you adding the "ajax_getTeams_loading" class to the div. However, because it's a background you might not see it if there is data in the div. Then it will just be beneath the text or whatever is in the div.
It might be better to replace whatever is in the div with the loading icon, and then replace the loading icon with the newly requested data. Example:
// store your div object in a variable,
// this is faster since you'll be using it multiple times
var div = $('#' + divId);
// replace the div's content with the loader
// you might want to add a width and height to the css
// to make sure the div is large enough to show the entire loading icon
var loader = '<div class="ajax_getTeams_loading"></div>';
div.html(loader);
$.get('testGetTeams.php', {username: profile}, function(data) {
// replace the loader icon with the requested data
div.html(data);
});
Try using
$('#'+divId).removeClass('old_class');
$('#'+divId).addClass('new_class');
It seems you are just setting the wrong class
Your class is ajax_getTeams_loading but you are adding goose. Put the same name and it should be fine.
Also, you might want to look in some jQuery functions:
addClass
removeClass
toggleClass
jQuery has start and stop indicators for AJAX. Since you're using ajax calls, you could try it.
function(profile, divId){
$.ajaxStart(function() {
// add the loading class while ajax is working
$('#loading').addClass("ajax_getTeams_loading");
});
$.ajaxComplete(function() {
// hide the loading div when we're done
$('#loading').hide();
});
// initiate the object sent to the server as a post
var data = {};
data.username = profile;
$.ajax({
url: "testGetTeams.php",
data: data,
type: "POST",
success: function(data){
$('#' + divId).html(data);
}
});
}
Take a note that attr will empty the attribute and replace it with what you pass, so in classes as we can have several of them, if you have, for example:
<div id="ajax_getTeams_loading"
class="classA classB classC">text</div>
and you use
$("#ajax_getTeams_loading").attr("class", "classD");
this will end up having:
text
Which could not be what you want. For this addCLass and removeClass result in a better way to add and remove css classes to the DOM elements in your particular case, you could easily change the way you do thing (not that if does not work, but this is what you find out there the most)
<html>
<head>..</head>
<body>
<div id="ajax-response-wrapper">
<div id="ajax-loading" style="display:none;">
<img src="loading.gif" alt="" /></div>
<ul id="myAjaxPopulatedList"></ul>
</div>
<a id="load" href="javascript:void(0);">Load list from ajax</a>
<script>
$(document).ready( function() {
$("#load").click( function() {
// let's show the loading while we are fetching data
$("#ajax-loading").show();
// get our stuff
$.get('testGetTeams.php', {username: profile}, function(data) {
// we got it, let's hide the loading now
$("#ajax-loading").hide();
// and append the data
$('#myAjaxPopulatedList').append(data);
});
});
});
</script>
</body>
</html>
I hope this helps you get what you want and see how stuff work.

Categories

Resources