Im using the following jQuery, which sets the id of the last item in a UL to 'last_item'.
function oldest() {
j('ul li:last-child').addClass( 'last_item' );
oldestName = j('.last_item').attr('id');
alert('last ID is:'+ oldestName +'.');
}
j(window).scroll(function(){
if (j(window).scrollTop() == j(document).height() - j(window).height()){
j.ajax({
url: "older.php?oldest="+oldestName+"",
cache: false,
success: function(html){
j(".older").html(html);
oldest();
}
})
}
});
oldest(); //Call function on page load
$('.button2').click(function() {
j('.older ul > *').clone().hide().appendTo('.tweets ul').slideDown();
oldest();
});
While scrolling older.php is called which contains:
$oldest = $_GET['oldest'];
$getolder = mysql_query(" SELECT * FROM table where date < $oldest ORDER BY date DESC LIMIT 20");
However what currently happens is the records from the database do get pulled back, stored in a hidden DIV. I then use the jQuery to add these records to the end of the list.
However the next time i scroll to the bottom of the page and press the button, the same records are added to the lists.
Can any help me to find out why this is?
Essentially it seems $oldest isnt being updated with the new last UL item date.
You'll need to remove the original "last_item" class from list item before you add it to the new last item...
j('ul li').removeClass( 'last_item' );
Related
I have finally implemented the load more button and load more data on my page using ajax and the below code works wonderful.
However, since it's an activity feed, it's always being updated, so the start and offset is always inaccurate.
E.g.
On Page Load Table consist of
Item 8
Item 7
Item 6
Item 5
Item 4
Item 3
Item 2
Item 1
By time I click on load more button for 5 more post it could have became like this because of new activities
Item 10
Item 9
Item 8
Item 7
Item 6
Item 5
Item 4
Item 3
Item 2
Item 1
Using above logic of offset 5 and limit 5, when there's no update I will get
Item 3, Item 2, Item 1
But because there's update, I ended up with duplicates display of Item 5 and Item 4 since the offset is now wrong new to new data in the mysql table.
Item Item 5(already displayed), Item 4(already Displayed), item 3, item 2 item 1
Question: I think this could be a common problem for activity feed. Any help is appreciated
$(document).ready(function() {
var a = 5; /*5 items already loaded on page load, so my start count will be 5*/
$("#showMoreActivity").on("click", function(b) {
b.preventDefault(), $.ajax({
url: "/activty/",
type: "POST",
dataType: "JSON",
data: {
start: a
},
success: function(data) {
if (data.length == 0) {
$("#showMoreActivity").addClass("disabled");
$("#showMoreActivity").html("End of Activity List");
} else {
a += 5;
$("#activity-feed").append(data);
}
}
});
});
});
on PHP end I have something like the following (simplified/modified)
public function getAgentActivity($start = 0, $limit = 5) {
$query = $this->db->prepare('SELECT * from activity WHERE ORDER BY created DESC LIMIT :limit OFFSET :offset');
if ($result = $query->execute(array(
':limit' => $limit,
':offset' => $start
))) {
//query success, fetch data and do something
}
}
For this you could use cursor based pagination. For e.g., instead of using limit and offset, use creation time of the record to paginate.
On each request send the last record creation time and send response accordingly. For this approach to work, your record must be sorted on creation time and creation time field should be unique. You could use auto-increment primary key as well.
For more detail See here
Below code may help:
success: function(data) {
a += data.length;
if (data.length > 0) {
$("#activity-feed").append(data);
}
if (data.length < 5) {
$("#showMoreActivity").addClass("disabled");
$("#showMoreActivity").html("End of Activity List");
}
}
So currently I'm searching for 10 new posts and the Ajax searches in the same page from the page and I use $_GET['limits'] in my PHP query to scan the server for all requested data.
So what I'd like to do is if there is no new data to show the 'No More Posts' Div. I tried using t.length===0 with no luck, now I don't know if its because t isn't an array or whether I put it in the wrong place in my success.
var streams_stream_count=10;
function streams_stream_load(targetID){
$('#loadmorestreamoneajaxloadertarget').show();
$.ajax({
method: 'get',
url : 'stream2.php?limits='+streams_stream_count+'&targetID='+targetID,
dataType : 'text',
success: function (t) {
$('#streams_stream_container').fadeIn('slow').html(t);
$(document).scroll(function(){
if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
streams_stream_count+=10;streams_stream_load(targetID);
}
});
},
complete: function(){
$('#loadmorestreamoneajaxloadertarget').hide();
}
});
}
And my hidden div to show if no new data.
<div id='nomoreposts' style='display:none;'>No more Posts</div>
UPDATE
I use $sqlLimit=mysqli_real_escape_string($mysqli,$_GET['limit'])
$call="SELECT * FROM streamdata ORDER BY streamitem_timestamp DESC LIMIT $sqlLimit";
You can also do like this :- Write code in backend (PHP function) and return html if no data found "No more Posts", also send one parameter true/false. On the bases of the parameter show html in your fronted.
I am developing a laravel website, in which there is a product list page (List page) where I show all the products with ajax lazy load. I also have a Product Details page which show details of the individual product. I created a hidden field which saves scroll count I call this field as Page_No field. When I go to list page, Initially I show 6 products from database and also set Page_No to "0", after I scroll down, another 6 products gets added to list by ajax and by determining Page_No field and that time I increment the Page_No field by one. And so on.
When I scroll down for some time (say three times) that means I have 24 products on my list page, and my Page_No count is "3". After that I click on any product and go to product page to see details. After that when I click browser's back button and go to list page, I see first 6 products are there and then if I scroll down I get more products, but it skips some of the products (for ex it shows me 45th product and so on..so what about those product from 24-45?).
My understanding:
When I get back to list page by clicking browser's back button Page_NO field is set to 3, if I scroll down it gets incremented by one i.e. "4", So my ajax query executes and get result from that point skipping some products.
Things I tried:
I understood that I have to control Page_No field in order to get my list work properly after pressing back button. when I go to product details page by clicking any one product that time I creates a session which will have value "0". After that I created SetInterval Ajax function which will continuously check that session and update the Page_No field. But this thing also does not work properly (Only works for first instance).
lazyload.js
onscroll = doLazyLoad;
//global check flag for do lazy load
var ll_check_flag = true;
function doLazyLoad()
{
var productsDiv = document.getElementById('ProductsView');
if(window.scrollY > (productsDiv.scrollHeight - 200))
{
if(ll_check_flag)
{
ll_check_flag = false;
getMoreProducts();
}
}
}
function getMoreProducts()
{
var product_filters = [];
$('input.checkfilter:checkbox:checked').each(function ()
{
product_filters.push($(this).val());
});
var pageno = parseInt($('#pageNo').val())+1;
$('#pageNo').val(pageno);
var range_filter = $('#range').val();
productsLazyLoadAjax(product_filters,range_filter,'',pageno);
}
function productsLazyLoadAjax(product_filters,range_filter,search_term,pageno)
{
weburl = $('#MasterURL').val();
$.ajax({
url: weburl + '/index/get/products',
type: "POST",
data: {pf:product_filters,rf:range_filter,st:search_term,page:pageno},
beforeSend:function()
{
res.container.append(res.loader);
},
success: function(data)
{
if(data != 0)
{
res.container.find(res.loader).remove();
$('#ProductsView').append(data);
ll_check_flag = true;
}
},
complete: function() {
}
});
}
Product Detail Page (After click on list page products we land on product detail page)
jQuery(document).ready(function()
{
$('#pageNo').val(0);
}
i am trying to add / remove rows dynamically in / from a table using JQuery and the DataTables plugin, at a specific index.
$('#jt').dataTable();
The rows i try to add is some additional info, which i get by clicking on a row (ajax). Each row has a unique id that i pass as an argument.
$('#jt').on('click','.togetinfo',function() {....
$.get(functions, { id: id }).done(function(data) {
....
For each result i add the content to a var and add it after the row i want.
$.each(jsonresult, function(i,item){
subentries = subentries + ....... /* the info */
});
$('#jt > tbody > tr').eq(id).after(subentries);
This works perfectly on the first page, but on the second page of the entries (paging) it does not insert the new data.
The fnAddData() of the "DataTables" API inserts the data on the end of the entire table.
Does anyone has an idea of how to make it work on all the pages?
The false was found in the indexes of each row after the first page.
Each index (on click) must be recalculated.
var rowIndex = oTable.fnGetPosition( $(this).closest('tr')[0] );
rowIndex = rowIndex - oSettings._iDisplayStart;
I have a function that loads images within a gallery.
Throughout the site it loads the last 20 images, then when a user scrolls down it loads another 20 and works with an infinite scroll code.
However, on one page this does not work and I'm baffled as to why not.
I've narrowed down the problem code to this:
function getEachBoardPins($id,$limit=false)
{
$sql = "SELECT
*
FROM
pins
WHERE
board_id = $id
ORDER BY time DESC";
if($limit)
$sql .=" LIMIT $limit" ;
$query = $this->db->query($sql);
return $query->result();
}
This will load EVERY image within the gallery. Some galleries have in excess of 1000 images so it takes an eternity to load.
By changing the "$limit=false" value to true in the first line only renders the last uploaded image.
Can anyone help me or point me in a kind direction so I can solve it?
thanks.
EDIT:
Infinite scroll code:
$(function(){
// alert($('.pin_item').length);
var $alpha = $('#alpha');
$alpha.imagesLoaded( function(){
$alpha.masonry({
itemSelector: '.pin_item',
isFitWidth: true,
isAnimatedFromBottom: true
//isAnimated: true
});
});
$alpha.infinitescroll({
navSelector : '#page-nav', // selector for the paged navigation
nextSelector : '#page-nav a', // selector for the NEXT link (to page 2)
itemSelector : '.pin_item', // selector for all items you'll retrieve
loading: {
finishedMsg: 'No more pages to load.',
img: '<?php echo site_url(); ?>/application/assets/images/ajax_loader_blue.gif'
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$alpha.masonry( 'appended', $newElems, true );
$("a.act_uncomment").hide();
$(".enter_comm").hide();
//Examples of how to assign the ColorBox event to elements
$(".group1").colorbox({rel:'group1'});
$(".group2").colorbox({rel:'group2', transition:"fade"});
$(".group3").colorbox({rel:'group3', transition:"none", width:"75%", height:"75%"});
$(".group4").colorbox({rel:'group4', slideshow:true});
$(".ajax").colorbox({scrolling:false,transition:"elastic"});
$(".youtube").colorbox({iframe:true, innerWidth:425, innerHeight:344});
$(".iframe").colorbox({iframe:true, width:"80%", height:"80%"});
$(".inline").colorbox({inline:true, width:"50%"});
$(".callbacks").colorbox({
onOpen:function(){ alert('onOpen: colorbox is about to open'); },
onLoad:function(){ alert('onLoad: colorbox has started to load the targeted content'); },
onComplete:function(){ alert('onComplete: colorbox has displayed the loaded content'); },
onCleanup:function(){ alert('onCleanup: colorbox has begun the close process'); },
onClosed:function(){ alert('onClosed: colorbox has completely closed'); }
});
//Example of preserving a JavaScript event for inline calls.
$("#click").click(function(){
$('#click').css({"background-color":"#f00", "color":"#fff", "cursor":"inherit"}).text("Open this window again and this message will still be here.");
return false;
});
});
}
);
});
from all of mysql experience limit should be set to an integer and thus will only return a maximum of that many results. try that out with adding a numeric limit to that query
The way you're doing it, whatever number you pass in will only return the last $limit number of records. If you're querying for more images, you're going to return all the records you already retrieved PLUS the additional records (if you're just increasing that number, for example).
Also, instead of passing $limit in as a boolean / integer (mixing data types isn't good practice), maybe you should pass it as a number. For example:
function getEachBoardPins($id, $start=0, $numrows=20)
{
$sql = "SELECT *
FROM pins
WHERE board_id = {$id}
ORDER BY time DESC
LIMIT {$start},{$numrows}
";
$query = $this->db->query($sql);
return $query->result();
}
I'm making the assumption you're sanitizing your variables before passing them to your function.
Another way to do it would be to pass in the ID of the last record retrieved. That way, you can pick up exactly where you left off in case new images have been added since the last time the data was refreshed.