Lazy Load - Browser Back Button Issue - Hidden Field Does Not Change - php

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);
}

Related

Creating different functions on odd click and even click on link

I have 3 links which are the names of students.On clicking a link first time or odd number time,another div which contains the details of that student appears.On clicking the same link on second time or even number time, I need to hide the student div.Its working perfectly for me using data() event of jquery.
My requirement is if I click first student link,div with the details of first student will come.If I click the second student link,details of second student will come.If I again click on first link,the student div will hide since data() is associated with it(I think so). But I want to make it displayed because,previous click was on the second link.
My html is like this
George
Leo
Kelm
My jquery:
$("#sections ").on('click','.student_link',function(){
var clicks = $(this).data('clicks');
//alert(clicks);
if (clicks) {
$("#div_students").hide();
//alert(1);
}
else
{
$("#div_students").show();
//alert(2);
}
$(this).data("clicks", !clicks);
return false;
});
That is if I click George for first time, the corresponding div of student will appear,If I click Leo without clicking George to hide the div,I need div of Leo should come.If I click George again,I need div with details of George should come.But for me the div is hiding since the variable click is already true for George.I need the div to be displayed if previous click was not on the current link.
You can use the following code:
$("#sections").on('click', '.student_link', function () {
var prevClickedId = $('#sections').data('prevId');
if (prevClickedId != $(this).attr('id')) {
// This was not the previous clicked element
} else {
// This was the previous clicked element
}
$('#sections').data('prevId', $(this).attr('id'));
return false;
});
You can so something similar to this:
$("#sections").on('click', '.student_link', function(){
if( $("#div_students").data('viewing') == $(this).attr('id') ) {
$("#div_students").hide().data('viewing', '');
}
else {
$("#div_students").show().text($(this).attr('id'));
$("#div_students").data('viewing', $(this).attr('id'));
}
return false;
});
Here's a working example: https://jsfiddle.net/7qwsguoq/
Why don't just use jquery toggle() method? it hides element when it's visible, and shows when it's hidden.

Just can't get this to work

I have been trying to figure out this problem I've been having all day. I will give you a simplified run down of what I have been trying to do. The user enters a number, and however much the number is, is the number of categories there are going to be on the following page. Within each category, there is an input text button, along with an "Add Textbox" button that adds additional input textboxes dynamically. However, the problem here is that each category has this same setup on the same page. For example, if the user enters the number "3", then the page will vertically load three categories looking something like the following:
Category #1
(Initial user input textbox for category #1)
("Add Textbox" button to allow user to fill out another option)
Category #2
(Initial user input textbox for category #2)
("Add Textbox" button to allow user to fill out another option)
Category #3
(Initial user input textbox for category #3)
("Add Textbox" button to allow user to fill out another option)
The struggle I have been encountering is that each category button will need to have its own function, to tell the button where to place the textbox. This coupled with the fact that the number of categories changes depending on the user's input, has made things difficult. I started with the following:
var categoryCount = <?php echo $categoryCount; ?>;
var click = {};
for (var num=1;num<=categoryCount;num++) {
var newClick = "click_" + num;
click[newClick] = function() {
// some contents when this button is clicked
};
}
This JS creates an object of functions, which in JS would be able to be accessed by doing something like the following:
click['click_' + someID]();
However, the problem is that I cannot do this using the "onclick" attribute in my HTML/PHP button. I cannot access this object of functions, and cannot call any of the individual functions, obviously. I think I am going to need to rethink all of this and start again. I just can't think of another way to get this to work. Please share your ideas with me! Your help would be greatly appreciated.
For something like this, I'd write a constructor I could use like this
var cat1 = new Category(document.body);
Luckily for you, I also wrote one as an example. See the DEMO HERE. I haven't styled it at all for the new lines etc, though.
var Category = (function () {
var categoryCount = 0;
function elem(tag) { // shortcut
return document.createElement(tag);
}
function text(str) { // shortcut
return document.createTextNode(str);
}
function Category(node) {
var self = this; // this should have been var'd, oops!!
this.categoryId = ++categoryCount;
// make add button
this.addButton = elem('button');
this.addButton.appendChild(text('Add Textbox'));
this.addButton.addEventListener('click', function () {
self.addTextbox();
});
// make wrapper
this.wrapper = elem('section');
this.wrapper.setAttribute('id', 'cat'+this.categoryId);
this.wrapper.appendChild(this.addButton);
// make textboxes
this.textboxes = [];
this.addTextbox();
// append to document
if (node) {
this.append(node);
}
}
Category.prototype.addTextbox = function () {
var e = elem('textarea');
e.setAttribute('name', 'cat-'+this.categoryId+'-textbox[]');
this.textboxes.push(e);
this.wrapper.insertBefore(e, this.addButton);
};
Category.prototype.append = function (node) {
return node.appendChild(this.wrapper);
};
return Category;
}());

Hiding in foreach loop

I am getting json in "data" and passing it in for loop. Onclick of buy button, it goes to the App function. On success I need to hide the buy button and display the download label.
My problem is onclick of 1st buy button, download link for both the buttons appear.
Ideally oneclick of first buy button, buy button should be hidden and download label should appear. similarly oneclick of second buy button, buy button should be hidden and download label should appear.
How do I get particular id of each button so that I can hide one at a time?
Please help me out
function (data)
{
var Class ='';
for (var i=0; i <data.length;i++)
{
Class += '<div name="buy\''+data[i].id+'\'" class="btn btn-primary btn-small" onclick="buy(\''+data[i].identifier+'\',\''+data[i].id+'\',\''+data[i].url +'\'); return false;" href=""></div><div class="download\''+data[i].id+'\'" id="download">D<span style="font-size:15px"></span></div>';
}
return Class;
}
App = function(identifier, app_id, url) {
$.ajaxSetup({
data : {
csrf_test_name : $.cookie('csrf_cookie_name')
}
});
var jqxhr = $.post(SITE_URL + 'admin/appstore/purchaseApp', {
identifier : identifier,
ap_id : ap_id
}).done(function(data1) {
obj = JSON.parse(data1);
bootbox.alert(obj.status, obj.label);
$("#download").html('<a href='+download_url+app_id+'>Download!</a>');
});
};
it is for loop am using.. am passing '; now how do I hide buy id? $("#buys"+"'"+data[i].id+"'").hide(); is this the right way? It gives me error
if you look at the actual markup generated in Class, you will see that your buy buttons don't have an id at all. perhaps something like
Class += '<div id="buy-button-'+data[i].id+'" name="...
Now you have a unique id on each button. The next part of your problem is knowing which button to remove after a successful Ajax call. You will need to include that in the data1, returned from the server. For the sake of argument, let's say the server returns the value in your data1 object as app_id. Then all you need to do is
jQuery('#buy-button-'+data1.app_id).hide();
Slightly off-topic, I'm not too keen on the way you're using single quotes in the buttons' name attributes, either, but I don't think that's relevant here.

Disable popup on add to cart button of virtuemart component in JOOMLA 1.7

I am using Virtuemart 2.0.0 shopping cart component for JOOMLA 1.7. On flypage (product detail page) there a button "Add to Cart" for add product in cart.
When click on that button a popup box is open, popup box contains some option and details like product name, continue shopping button and go to checkout.
I want disable that popup box on add to cart button when i click that button page is redirect to checkout page.
So, anybody give me any idea to disable the popup and where i got that option in configuration of virtuemart on admin side
One way is to modify the function that is in the vmprices.js file, and comment out the lines that show the popup, if you want you can add some other behavior right there, the function is sendtocart. For example to remove the popup should do this.
(function($) {
$.fn.product = function(options) {
this.each(function(){
var cart = $(this),
addtocart = cart.find('input.addtocart-button'),
plus = cart.find('.quantity-plus'),
minus = cart.find('.quantity-minus'),
select = cart.find('select'),
radio = cart.find('input:radio'),
virtuemart_product_id = cart.find('input[name="virtuemart_product_id[]"]').val(),
quantity = cart.find('.quantity-input');
**//addtocart.click(function(e) {
//sendtocart(cart);
//return false;
//});**
plus.click(function() {
var Qtt = parseInt(quantity.val());
if (Qtt != NaN) {
quantity.val(Qtt + 1);
}
});
minus.click(function() {
var Qtt = parseInt(quantity.val());
if (Qtt != NaN && Qtt>0) {
quantity.val(Qtt - 1);
}
});
select.change(function() {
$.setproducttype(cart,virtuemart_product_id);
});
radio.change(function() {
$.setproducttype(cart,virtuemart_product_id);
});
});
Not sure if those settings still exists in 1.7 but it used to be under:
Components->VirtueMart->Admin-> Configuration->Site
Click on the Configuration link underneath the "Select theme" for your Shop drop-down menu. There set the following values:
Customer Checkout in a popup (GreyBox)? No
Use Ajax to add, update or delete products from the cart? No
VM 2.0 no longer uses themes so there is not changing any setting for the theme any more. If you want to change how any of the pages looks or works, you use a simple template override like you do for other Joomla extensions.
Copy this file -
components/com_virtuemart/views/productdetails/tmpl/default.php
Place the copy here -
YOUR_TEMPLATE/html/com_virtuemart/productdetails/default.php
Make any changes you want then.
One way is to modify the function that is in the vmprices.js file, and comment out the lines that show the popup, if you want you can add some other behavior right there, the function is sendtocart. For example to remove the popup should do this.
function sendtocart(form){
$.ajaxSetup({ cache: false })
var datas = form.serialize();
$.getJSON(siteurl+'index.php?option=com_virtuemart&nosef=1&view=cart&task=addJS&format=json',encodeURIComponent(datas),
function(datas, textStatus) {
if(datas.stat ==1){
//var value = form.find('.quantity-input').val() ;
var txt = form.find(".pname").val()+' '+vmCartText;
$.facebox.settings.closeImage = closeImage;
$.facebox.settings.loadingImage = loadingImage;
$.facebox.settings.faceboxHtml = faceboxHtml;
//$.facebox({ text: datas.msg +"<H4>"+txt+"</H4>" }, 'my-groovy-style');
} else if(datas.stat ==2){
var value = form.find('.quantity-input').val() ;
var txt = form.find(".pname").val();
$.facebox.settings.closeImage = closeImage;
$.facebox.settings.loadingImage = loadingImage;
$.facebox.settings.faceboxHtml = faceboxHtml;
//$.facebox({ text: datas.msg +"<H4>"+txt+"</H4>" }, 'my-groovy-style');
} else {
$.facebox.settings.closeImage = closeImage;
$.facebox.settings.loadingImage = loadingImage;
$.facebox.settings.faceboxHtml = faceboxHtml;
//$.facebox({ text: "<H4>"+vmCartError+"</H4>"+datas.msg }, 'my-groovy-style');
}
if ($(".vmCartModule")[0]) {
$(".vmCartModule").productUpdate();
}
});
$.ajaxSetup({ cache: true });
};
Most simple way is to uncheck the 'use product script' box in Configuration > Templates.
Then in your product detail template change:
<noscript><input type="hidden" name="task" value="add" /></noscript>
to:
<input type="hidden" name="task" value="add" />
removing the noscript tags
go to virtuemart components and look left side bar select second last configuration tab and open configuration tab and look at upper some tab their select checkout tab look in that tab some option their first option disable popup for the go to cart.

Reloading new content while scrolling

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' );

Categories