I am doing infinite ajax scrolling with php and api but my data is repeating. i don't want to load data when user is end of page(run perfectly) . What i want when user reach at certain div(check_onload) then load the data but in this case data is repeating.Here is below my code how i stop repeating data.
<div id="post-data"></div>
<div style="display:none;" class="ajax-load"></div>
<div class="check_onload"></div>
<script type="text/javascript">
///this run Perfectly
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() >= $(document).height()) {
var token = $(".tokenId").val();
GetMoreData(token);
}
});
///Repeating or duplication the data
$(window).on('scroll',function() {
if (checkVisible($('#check_onload'))) {
var token = $(".tokenId").val();
GetMoreData(token);
} else {
}
});
function checkVisible( elm, eval ) {
eval = eval || "object visible";
var viewportHeight = $(window).height(), // Viewport Height
scrolltop = $(window).scrollTop(), // Scroll Top
y = $(elm).offset().top,
elementHeight = $(elm).height();
if (eval == "object visible") return ((y < (viewportHeight + scrolltop)) && (y > (scrolltop - elementHeight)));
if (eval == "above") return ((y < (viewportHeight + scrolltop)));
}
function GetMoreData(token){
$.ajax(
{
url: '/loadMoreData.php?token=' + token,
type: "get",
beforeSend: function()
{
$('.ajax-load').show();
}
})
.done(function(data)
{
$('.ajax-load').hide();
$("#post-data").append(data.html);
$("#tokenId").val(data.token);
})
.fail(function(jqXHR, ajaxOptions, thrownError)
{
alert('server not responding...');
});
}
</script>
You have 2 window scroll events being triggered, causing duplicates because you are requesting data from the server with the same token twice, each time the user scrolls the page. I will have to assume that removing 1 of them will fix your problem.
Without seeing your server code, this is the only solution.
Related
I'm using scrolling instead of pagination but my problem is that it still loading even the data already there and no more data found, so the scrolling down will never stop, and I think because I can't set the condition that if reached to the last page then stop loading
to check if the json html is empty is difficult because it contains html divs
I hope you can help me to reach to the end of content then stop scrolling
var page = 1;
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() >= $(document).height()) {
page++;
loadMoreData(page);
}
});
function loadMoreData(page) {
$.ajax({
url: '?page=' + page,
type: "get",
beforeSend: function() {
$('.ajax-load').show();
}
}).done(function(data) {
if(page == " ") {
$('.ajax-load').html("No more records found");
return;
}
$('.ajax-load').hide();
$("#load_data").append(data.html);
}).fail(function(jqXHR, ajaxOptions, thrownError) {
alert('server not responding...');
});
}
/*Show Hide Cousines*/
$('#showcuisine').on('click', function (event) {
event.preventDefault();
$(".cuisines").show();
$("#showcuisine").hide();
$("#hidecuisine").show();
});
$('#hidecuisine').on('click', function (event) {
event.preventDefault();
var allcuisines = jQuery('.cuisines');
for (var i = 5; i < allcuisines.length; i++) {
$('#cuisine' + i).hide();
}
$("#showcuisine").show();
$("#hidecuisine").hide();
});
Controller
if ($request->ajax()) {
$view = view('store-search.listing', compact(
'stores','storedays','cuisines'
))->render();
return response()->json(['html'=>$view]);
}
When there is no more data to receive you can return null or false instead of view.
Then replace
if(page == " ") {
$('.ajax-load').html("No more records found");
return;
}
with:
if(!data) {
$('.ajax-load').html("No more records found");
return;
}
You should also include a variable isLastPageLoaded = false and set it to true wen last page is reached. Before making new AJAX request you should check if this is still false. If it's true then you don't need to load new records.
Do I understand correctly that already existing records get duplicated?
check with if condition on api side if zero record fetching then return null.
and then put this on your ajax done function
if(data == null) {
$('.ajax-load').html("No more records found");
return;
}
Solved,
I have to put the foreach in a div with no other html up to the foreach
I have some code that iterates through some database results and displays them, as such...
Note: article item.php just echoes the results with some formatting.
<ul class="post-column">
<?php
foreach ($data as $lineitem):
$type = $lineitem['type'];
if($type == "article"){
require('php/articleitem.php');
}
endforeach;
?>
</ul>
When I get to the bottom of the page, I want to do an AJAX DB call to get further results...
if ($(window).scrollTop() >= $(document).height() - $(window).height() - 700) {
startpoint = startpoint + 10;
processing = true;
$.ajax({
url: "AJAX/moritems.php",
type: "post",
async: false,
//this is where we define the data that we will send
data: {
startpoint: startpoint,
},
success: function (data) {
},
});
processing = false;
}
I want to then use the DB results to display more data below the data I've already displayed on the screen, but because I've displayed the result thus far in PHP, how would I do that? Would I have to use AJAX to load a new php page with results, then use javascript to add it to the existing page at the bottom of the results?
The answer is yes. Example:
function load() {
var xmlhttp;
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
if(xmlhttp.status == 200){
document.getElementById("myDiv").innerHTML += xmlhttp.responseText;
}
else if(xmlhttp.status == 400) {
alert('There was an error 400')
}
else {
alert('something else other than 200 was returned')
}
}
}
xmlhttp.open("GET", yoururl, true);
xmlhttp.send();
}
You need to define yoururl and link the function to the click event of your paging button or run it when you scroll.
I have a site that uses ajax to load a post directly to the page when clicked.
But... I also have an ajax contact-form at the same page. But if I click a post first, then want to send a message later, it fails. But if I refresh the page and go straight to the contact-form and send a message it doesn't fail at sending. Is there any way that I can maybe "reload" ajax without refreshing the page so that you can do multiple things at my site with ajax?
$(document).ready(function() {
function yournewfunction() {
var requestCallback = new MyRequestsCompleted({
numRequest: 3,
singleCallback: function() {
alert("I'm the callback");
}
});
var width = 711;
var animationSpeed = 800;
var pause = 3000;
var currentSlide = 1;
var $slider = $("#slider");
var $slideContainer = $(".slides");
var $slides = $(".slide");
var $toggleRight = $("#right");
var $toggleLeft = $("#left");
$toggleRight.click(function() {
$slideContainer.animate({
'margin-left': '-=' + width
}, animationSpeed, function() {
currentSlide++;
if (currentSlide === $slides.length) {
currentSlide = 1;
$slideContainer.css('margin-left', 0);
}
});
});
$toggleLeft.click(function() {
if (currentSlide === 1) {
currentSlide = $slides.length;
$slideContainer.css({
'margin-left': '-' + width * ($slides.length - 1) + 'px'
});
$slideContainer.animate({
'margin-left': '+=' + width
}, animationSpeed, function() {
currentSlide--;
});
} else {
$slideContainer.animate({
'margin-left': '+=' + width
}, animationSpeed, function() {
currentSlide--;
});
}
});
if ($(".slide img").css('width') == '400px' && $(".slide img").css('height') == '400px') {
$(".options").css("width", "400px");
$(".slide").css("width", "400px");
$("#slider").css("width", "400px");
$(".video-frame").css("width", "400px");
var width = 400;
};
if ($("#slider img").length < 2) {
$("#right, #left").css("display", "none");
};
if ($("iframe").length > 0 && $("iframe").length < 2) {
$(".options").css("width", "711px");
$(".slide").css("width", "711px");
$("#slider").css("width", "711px");
$(".video-frame").css("width", "711px");
$('.slide').hide();
var width = 711;
};
if ($(".slide img").css('width') > '400px' && $(".slide img").css('width') < '711px') {
$(".options").css("width", "600px");
$(".slide").css("width", "600px");
$("#slider").css("width", "600px");
$(".video-frame").css("width", "600px");
var width = 600;
};
}
$.ajaxSetup({
cache: false
});
$(".post-link").click(function(e) {
e.preventDefault()
var post_link = $(this).attr("href");
$("#single-post-container").html('<img id="loads" src="http://martinfjeld.com/wp-content/uploads/2015/09/Unknown.gif">');
$("#single-post-container").load(post_link, function(response, status, xhr) {
if (status == "error") {
var msg = "Sorry but there was an error: ";
$("#error").html(msg + xhr.status + " " + xhr.statusText);
} else {
$("#main-content").fadeIn(500);
$("body").addClass("opens");
yournewfunction();
}
});
requestCallback.requestComplete(true);
return false;
});
});
$(function() {
var form = $('#ajax-contact');
var formMessages = $('#form-messages');
$(form).submit(function(event) {
event.preventDefault();
var formData = $(form).serialize();
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData
}).done(function(response) {
// Make sure that the formMessages div has the 'success' class.
$(formMessages).removeClass('error');
$(formMessages).addClass('success');
// Set the message text.
$(formMessages).text(response);
// Clear the form.
$('#name').val('');
$('#email').val('');
$('#message').val('');
}).fail(function(data) {
// Make sure that the formMessages div has the 'error' class.
$(formMessages).removeClass('success');
$(formMessages).addClass('error');
// Set the message text.
if (data.responseText !== '') {
$(formMessages).text(data.responseText);
} else {
$(formMessages).text('Oops! An error occured and your message could not be sent.');
}
});
});
});
Though it's hard to follow exactly what is going on without being able to see the context of your HTML and without you giving us a more concrete description of exactly which line of code fails to execute, this is likely because one Ajax call is replacing a bunch of HTML which clobbers all your event handlers. So, when you then try to do the second Ajax operation, it's click handler is no longer in force so nothing happens.
Replacing a DOM element loses all event handlers that were attached to the original DOM element. Using .html() or assigning to .innerHTML replaces all the DOM elements within that element, thus losing all their event handlers.
The typical solution to this is to either reinstall the event handlers after replacing the content that you want event handlers on or use delegated event handling from a parent element that is not replaced.
Here are some references on delegated event handling:
JQuery Event Handlers - What's the "Best" method
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Does jQuery.on() work for elements that are added after the event handler is created?
Should all jquery events be bound to $(document)?
I use the code below for sending ajax request to get more products on scroll down event. However it also sends ajax request when I scroll up, which is not intended. How can I modify it so that it will send a request only when I scroll it to the bottom?
_debug = true;
function dbg(msg) {
if (_debug) console.log(msg);
}
$(document).ready(function () {
$(".item-block img.lazy").lazyload({
effect: "fadeIn"
});
doMouseWheel = 1;
$("#result").append("<p id='last'></p>");
dbg("Document Ready");
var scrollFunction = function () {
dbg("Window Scroll Start");
/* if (!doMouseWheel) return;*/
var mostOfTheWayDown = ($('#last').offset().top - $('#result').height()) * 2 / 3;
dbg('mostOfTheWayDown html: ' + mostOfTheWayDown);
dbg('doMouseWheel html: ' + doMouseWheel);
if ($(window).scrollTop() >= mostOfTheWayDown) {
$(window).unbind("scroll");
dbg("Window distanceTop to scrollTop Start");
$('div#loadMoreComments').show();
doMouseWheel = 1;
dbg("Another window to the end !!!! " + $(".item-block:last").attr('id'));
$.ajax({
dataType: "html",
url: "search_load_more.php?lastComment=" + $(".item-block:last").attr('id') + "&" + window.location.search.substring(1),
success: function (html) {
doMouseWheel = 0;
if (html) {
$("#result").append(html);
dbg('Append html: ' + $(".item-block:first").attr('id'));
dbg('Append html: ' + $(".item-block:last").attr('id'));
$("#last").remove();
$("#result").append("<p id='last'></p>");
$('div#loadMoreComments').hide();
$("img.lazy").lazyload({
effect: "fadeIn"
});
$(window).scroll(scrollFunction);
} else {
//Disable Ajax when result from PHP-script is empty (no more DB-results )
$('div#loadMoreComments').replaceWith("<center><h1 style='color:red'>No more styles</h1></center>");
doMouseWheel = 0;
}
}
});
}
};
$(window).scroll(scrollFunction);
});
You'll need to detect the direction of the scroll and add that as a boolean check. This post covers it.
The snippet they provide:
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
} else {
// upscroll code
}
lastScrollTop = st;
});
So you'll probably do something like:
$(window).scrollTop() >= mostOfTheWayDown && st > lastScrollTop
I have changed the below line
if ($(window).scrollTop() >= mostOfTheWayDown)
to
if( $(window).height() + $(window).scrollTop() == $(document).height())
this worked for me. Hope this can help others too. Thanks
I have a pinterest style site and made a jquery script that spaces the cubes evenly no matter how big the browser is. For some reason on page load it has some overlapping cubes which didn't exist before. I talked with the guy that helped me make it and he said it's probly because of the code before the code that creates the blocks and positions them. It crashes the javascript.
I think it's because of the $(window).scroll ajax loading code but I can't seem to pinpoint the problem. I tried moving positionBlocks(); around and nothing changes. If you load the page in your browser and then change your browser size then it positions them correctly but obviously I want it to look right when the user first gets there.
function setupBlocks() {
windowWidth = $(window).width();
blocks = [];
// Calculate the margin so the blocks are evenly spaced within the window
colCount = Math.floor(windowWidth/(colWidth+margin*2));
spaceLeft = (windowWidth - ((colWidth*colCount)+margin*2)) / 2;
spaceLeft -= margin;
for(var i=0;i<colCount;i++){
blocks.push(margin);
}
positionBlocks();
}
function positionBlocks() {
$('.block').each(function(i){
var min = Array.min(blocks);
var index = $.inArray(min, blocks);
var leftPos = margin+(index*(colWidth+margin));
$(this).css({
'left':(leftPos+spaceLeft)+'px',
'top':min+'px'
});
blocks[index] = min+$(this).outerHeight()+margin;
});
}
// Function to get the Min value in Array
Array.min = function(array) {
return Math.min.apply(Math, array);
};
var curlimit=<?php echo $curlimit; ?>;
var totalnum=<?php echo $num_rws; ?>;
var perpage=<?Php echo $perpage ?>;
var working_already=false;
$(document).ready(function() {
//($(window).scrollTop() + $(window).height() )> $(document).height()*0.8
// old ($(window).scrollTop() + $(window).height() == $(document).height())
$(window).resize(setupBlocks);
$(window).scroll(function() {
if(($(window).scrollTop() + $(window).height() )> $(document).height()*0.90 && totalnum>0 && working_already==false ) {
} else return false;
working_already=true;
$("div#loading_bar").fadeIn("slow");
curlimit=curlimit+perpage;
$("div#loading_data_location").html("");
$.get('get_cubes.php?page=<?php echo $_GET['page'] ?>&curlimit='+curlimit, function(response) {
$("div#loading_data_location").html(response);
$("div#ColumnContainer").append($("div#loading_data_location").html());
$("a#bigpic").fancybox({
'onComplete' : imageLoadComplete,
'onClosed' : imageClosed,
'type': 'ajax' });
if ($("div#loading_data_location").text()=="")
totalnum=0;
else
totalnum=<?php echo $num_rws; ?>;
$('.like:not(.liked)').click(like_box);
$('.save:not(.saved)').click(save_box);
$('.follow:not(.following)').click(follow);
$("div#loading_bar").fadeOut("fast");
$("div#loading_data_location").html('');
setupBlocks();
working_already=false;
});
});
I had to add this to the end of my script:
<script language="javascript">
$(window).bind("load", function() {
setupBlocks();
});
</script>
and then this to the end of the on scroll ajax load. Sometimes jquery just needs a little kick in the face haha:
setTimeout(function(){setupBlocks();},100);