Bigcommerce Infinite scroll not working after faceted search is made - infinite-scroll

Infinite scroll to our Custom PLP page is only working for page load alone. After selecting the faceted search, the infinite scroll feature is not working after the faceted response is appended. Please someone help us to have the Infinite scroll feature working after the faceted search result is appended.
Thanks in Advance

BigCommerce does not offer an Infinite Scroll feature by default, so I'm going to assume you followed this guide: https://medium.com/bigcommerce-developer-blog/how-to-add-infinite-scroll-to-category-pages-6c991750a8d5
The thing to keep in mind is that the category page gets reloaded via AJAX when a filter is applied. The fix for this should be as simple as duplicating the infiniteScroll function inside the this.facetedSearch function.
Look for the following code in your category.js file:
this.facetedSearch = new FacetedSearch(requestOptions, (content) => {
$productListingContainer.html(content.productListing);
$facetedSearchContainer.html(content.sidebar);
$('html, body').animate({
scrollTop: 0,
}, 100);
});
And add the infinite scroll function here as well:
this.facetedSearch = new FacetedSearch(requestOptions, (content) => {
$productListingContainer.html(content.productListing);
$facetedSearchContainer.html(content.sidebar);
function infiniteScroll() {
const elem = document.querySelector('.productGrid');
const infScroll = new InfiniteScroll(elem, {
// options
path: '.pagination-item--next .pagination-link',
append: '.product',
history: false,
});
return infScroll;
}
infiniteScroll();
$('html, body').animate({
scrollTop: 0,
}, 100);
});

Related

startEditingCell in ag-grid does not work when Item has just been added

I am trying to have my ag-grid start editing as soon as a new item is added. It works when grid has data already but if it's the first item in the grid it does not work.
var a = $scope.gridOptions.api.updateRowData({add: [newItem]});
$scope.gridOptions.api.refreshCells({force:true}); // does not help
$scope.gridOptions.api.startEditingCell({
rowIndex: a.add[0].rowIndex,
colKey: 'Note'
});
using ag-grid version 12.0.2. Console shows nothing.
It seems like updateRowData does not automatically start a $digest loop. Adding $scope.$apply or $timeout or anything similar alleviates the problem.
The question showed AngularJS code.
Here's an example what you'd need to do, using regular Angular.
getContextMenuItems(params) {
var result = [
{
name: 'Add new row',
action: function() {
// Add a new row at the start of our agGrid's data array
params.context.rowData.unshift({});
params.api.setRowData(params.context.rowData);
params.api.refreshCells();
// Get the name of the first column in our grid
let columnField = params.column.userProvidedColDef.field;
// Highlight the left-hand cell in our new row, and start editing it
params.api.setFocusedCell(0, columnField, null);
params.api.startEditingCell({
rowIndex: 0,
colKey: columnField,
rowPinned: null
});
},
icon: '<img src="../../assets/images/icnAdd.png" width="14"/>'
}
];
return result;
}
Hope this helps.

Protractor locator issues

My goal is to pull the css width of a particular element.
The actual jQuery command I use in Chrome console works well :
$('div-grid-directive[grid-name="SAT"] .qMinus1_resize_expand').first().css('width');
"0px"
However, running Protractor in a Win 7 cmd prompt, I'm getting the following error:
Message:
Failed: element(...).first is not a function
The error points to my objects page topNav.icons.page.js, in this.getQMinus1Column :
module.exports = function(){
this.clickExpandRowsIcon = function(){
$('.resize-btns > .glyphicon.glyphicon-resize-horizontal').click();
browser.driver.sleep(2000);
};
this.getQMinus1Column = function(){
return element(by.css('div-grid-directive[grid-name="SAT"] .qMinus1_resize_expand')).first();
};
};
and my SAT.spec.js file :
var IndexPage = require('./pageObjects/index.page.js');
var TopNavBar = require('./pageObjects/topNav.icons.page.js');
describe('Testing the Sales & Trading Top Nav grid icons', function(){
var indexPage = new IndexPage();
var topNavBar = new TopNavBar();
beforeEach(function () {
indexPage.get(); // Launches app !!
});
describe('Clicking on the Expand Rows icon', function () {
it('Should horizontally expand previous quarters qMinus1 thru qMinus6', function () {
topNavBar.clickExpandRowsIcon();
var elem = topNavBar.getQMinus1Column();
expect(elem).getCssValue().indexOf('width: 5px;').not.toBe('-1');
});
});
});
So before I even try to get the css width attribute, I'm struggling to return first(), using this format:
return element(by.css('MY-CSS')).first();
Do I have too much going on in this line, or perhaps the wrong syntax for Protractor ?
return element(by.css('div-grid-directive[grid-name="SAT"] .qMinus1_resize_expand')).first();
Again, the same syntax works using jQuery in console tools, so the CSS select is correct.
Advice is greatly appreciated here...
regards,
Bob
As per this , element does not return a collection of objects to call first method in it.
Probably you might want to use element.all(locator)

how to trigger/reload Masonry plugin on click

Because i have different tabs, masonry is not loading the hidden items, so when i click on a new tab the images stack onto each other, i know this question has been asked before and answered with trigger masonry by clicking the tab, but how would i go about doing this without messing up the first tab.
Currently calling masonry with
$(function(){
$('#container').masonry({
// options
itemSelector : '.item',
columnWidth : 260
});
});`
$(window).load(function(){ $('#container').masonry(); });
and the same for tab 2 but with a different ID - #container2
the tab one works perfectly but tab two stacks the images, until you resize the browser which fixes it and works as normal
Do it like this:
$(function(){
$('#container').masonry({
// options
itemSelector : '.item',
columnWidth : 260
});
});
var masonryUpdate = function() {
setTimeout(function() {
$('#container').masonry();
}, 500);
}
$(document).on('click', masonryUpdate);
$(document).ajaxComplete(masonryUpdate);
Never worry about it again! Or, you may call it again after other animations, like:
$('#something').slideDown(600, masonryUpdate);
Even if you don't, just click anywhere in the page and masonry will update.
Yes, you can reload masonry view on onclick event as following :-
Use $container.masonry('reload'); if it is work for you. In my case It was not work. I have done using setTimeout(function(){ $container.masonry() }, 400); . call masonry in setTimeout function.
$(document).ready(function($) {
var $container = $('#youContainerId');
$("#TabId").live("click",function(){
//$container.masonry('reload');
setTimeout(function(){ $container.masonry() }, 400);
});
});

applying jScrollPane to a div appended with ajax

I have a tabbed widget that shows three separate loops. Under the third tabbed section which is hidden by default, I show a search that gives ajax results. My problem is that I can't figure how to apply jScrollPane to the container div of the results. Everytime the search is entered, the container div is emptied and new results are appended so I need to reapply it each time. Here is the code I'm using to trigger the search.
jQuery( function( $ ) {
// search filed
var $s = $( '#s' );
// the search form
var $sForm = $s.closest( 'form' );
console.log( $sForm );
$sForm.on( 'submit', function( event) {
event.preventDefault();
$.post(
T5Ajax.ajaxurl,
{
action: T6Ajax.action,
search_term: $s.val()
},
function( response ) {
$("#music-results").empty();
$("#music-results").append( response );
},
);
});
});
Now I have the basic call to setup jscrollpane for the other loops but that doesn't get applied to the div in question because it is hidden by default I guess.
$(document).ready(function(){
$('#music-results').jScrollPane({showArrows: true,autoReinitialise: false});
});
So how can I apply jscroll to the div each time it's emptied and new results are added?
You're right, jscrollpane doesn't apply to content that is not displayed (display:none).
To fix your problem, you simply need to call jscrollpane when the content is apended.
So instead of putting $('#music-results').jScrollPane({showArrows: true,autoReinitialise: false}); in the document ready(), simply put it after $("#music-results").append( response );. It should then work.
$.post(
T5Ajax.ajaxurl,
{
action: T6Ajax.action,
search_term: $s.val()
},
function( response ) {
$("#music-results").empty();
$("#music-results").append( response );
$('#music-results').jScrollPane({showArrows: true,autoReinitialise: false});
},
);
There is another way of doing what you want using the api.
Declare a global variable for the api, that will be available to all functions and then set it the document.ready()
var api;
$(document).ready(function(){
var element = $('##music-results').jScrollPane({showArrows: true,autoReinitialise: false});
api = element.data('jsp'); //you can now access the api through this variable.
});
Then, when you append the content to #music-results, simply reinitialize the scrollpane using the api.
$.post(
T5Ajax.ajaxurl,
{
action: T6Ajax.action,
search_term: $s.val()
},
function( response ) {
$("#music-results").empty();
$("#music-results").append( response );
api.reinitialise();
},
);
But remember, in order to do this, your content needs to be visible because jscrollpane needs to calculate the height and if it's not displayed, the height will not be found.
So if you append the content and the tab is not visible, simply reinitialize jscrollpane on the tab switch.
Hope this helps.

Drag from Tree to div

I am trying to implement a drag and drop senario from an extJs TreePanel into a div in the body of the page. I have been following an example by Saki here.
So far I have the below code:
var contentAreas = new Array();
var tree = new Ext.tree.TreePanel({
title : 'Widgets',
useArrows: true,
autoScroll: true,
animate: true,
enableDrag: true,
border: false,
layout:'fit',
ddGroup:'t2div',
loader:new Ext.tree.TreeLoader(),
root:new Ext.tree.AsyncTreeNode({
expanded:true,
leaf:false,
text:'Tree Root',
children:children
}),
listeners:{
startdrag:function() {
$('.content-area').css("outline", "5px solid #FFE767");
},
enddrag:function() {
$('.content-area').css("outline", "0");
}
}
});
var areaDivs = Ext.select('.content-area', true);
Ext.each(areaDivs, function(el) {
var dd = new Ext.dd.DropTarget(el, {
ddGroup:'t2div',
notifyDrop:function(ddt, e, node) {
alert('Drop');
return true;
}
});
contentAreas[contentAreas.length] = dd;
});
The drag begins and the div highlights but when I get over the div it does not show as a valid drop target and the drop fails.
This is my first foray into extJS. I'm JQuery through and through and I am struggling at the moment.
Any help would be appreciated.
Ian
Edit
Furthermore if I create a panel with a drop target in it, this works fine. What is the difference between creating an element and selecting an existing element from the dom. This is obviously where I am going wrong but I'm none the wiser. I have to be able to select existing dom elements and make them into drop targets so the code below is not an option.
Here is the drop target that works
var target = new Ext.Panel({
renderTo: document.body
,layout:'fit'
,id:'target'
,bodyStyle:'font-size:13px'
,title:'Drop Target'
,html:'<div class="drop-target" '
+'style="border:1px silver solid;margin:20px;padding:8px;height:140px">'
+'Drop a node here. I\'m the DropTarget.</div>'
// setup drop target after we're rendered
,afterRender:function() {
Ext.Panel.prototype.afterRender.apply(this, arguments);
this.dropTarget = this.body.child('div.drop-target');
var dd = new Ext.dd.DropTarget(this.dropTarget, {
// must be same as for tree
ddGroup:'t2div'
// what to do when user drops a node here
,notifyDrop:function(dd, e, node) {
alert('drop');
return true;
} // eo function notifyDrop
});
}
});
See if adding true as the second param here makes any difference:
var areaDivs = Ext.select('.content-area', true);
As a cosmetic note, the param name e conventionally indicates an event object (as in the second arg of notifyDrop). For an element, el is more typical. Doesn't matter functionally, but looks weird to someone used to Ext code to see e passed into the DropTarget constructor.
If you are having problem duplicating a working example such as that, copy the entire thing, then modify it to your needs line-by-line - you can't go wrong.
As i know you can't set DropZone to any Ext element, just to Ext component. So this might be you problem. Try to use DropTarget instead of DropZone.