This meteor client code uses chriswessels:hammer#4.0.2
, the swipeleft works by invoking console.log('moved left') but how can I get the html element to actually move with the finger? Thanks
Template.swipe.helpers({
'configureHammer': function() {
return function(hammer, templateInstance) {
let swipeleft = new Hammer.Swipe({
event: 'swipeleft',
pointers: 1,
velocity: 0.2
});
hammer.add(swipeleft);
return hammer;
}
},
'swipeGestures': {
'swipeleft .swipe': function(event, templateInstance) {
console.log('moved left');
}
}
});
Related
I have a modal window in Angular 4 that works fine but if the user clicks on the background / parent page the modal is closed.
I have found some solutions that suggest using backdrop='static' and keyboard=false when opening the modal but our modal uses a local Dialog class with a BehaviorSubject object so is opened using the .next method. I've also tried setting these attributes using div config but to no avail.
Therefore I'm looking for another solution, maybe using CSS or another setting / attribute that can be directly applied to the parent page or modal HTML.
See below for some of the relevant code.
dialog.component.ts:
constructor(private location: PlatformLocation,
private _dialog: DialogService,
private router: Router) { }
open() {
this.showDialog = true;
const body = document.body;
body.classList.add('cell-modal-open');
}
close() {
this.dialog = undefined;
}
private handleDialog(d: Dialog) {
if (!d) {
this.close();
} else if (d.template) {
if (this.showDialog) {
this.close();
}
this.dialog = d;
this.open();
}
}
ngOnInit() {
this.subscription = this
._dialog
.getDialog()
.subscribe({
next: (d) => { this.handleDialog(d); console.log('subscribed dialog') },
error: (err) => this.handleDialogError(err)
});
this.initialiseRoutingEventListeners();
}
dialog.service.ts
private d: Dialog = { template: null, size: DialogSizeEnum.XLarge };
private dialogSubject = new BehaviorSubject<Dialog>({ template: null, size: DialogSizeEnum.XLarge });
constructor() { }
showDialog(template: TemplateRef<any>, size = DialogSizeEnum.XLarge, requiresAction = false) {
Object.assign(this.d, { template: template, size: size, requiresAction: requiresAction });
if (this.d !== null) {
this.dialogSubject.next(this.d);
}
}
getDialog(): BehaviorSubject<Dialog> {
return this.dialogSubject;
}
clear() {
this.dialogSubject.next(null);
}
Any suggested approaches are welcome!
Added flag to the close() method and adding condition to only set to undefined if true (i.e. from a valid location).
I'm trying to scrape products with color and size variations.
Every variation is a form and to get the next variation I'm clicking on radio button and it is doing a form submit action on each click.
I have tried to click it using
1. “casper.getElementsInfo(element)[0].click();”
2. “document.querySelectorAll(element)[2].click();”
3. “casper.thenClick('element');”
4. “casper.evaluate(function(){document.querySelectorAll(element)[2].click();});”
After every click I'm doing a casper wait for 8 seconds !
So here is my problem Casperjs is getting error after clicking the next color/size
var casper = require('casper').create({
viewportSize: {
width: 1920,
height: 1080
},
pageSettings: {
loadImages: false,
loadPlugins: false
}
});
casper.then(function () {
self.thenOpen("https://scubapro.johnsonoutdoors.com/fins/fins/seawing-nova-fin-full-foot", function () {
casper.then(function () {
var varitoinCount = document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input').length;
var i = 0;
casper.repeat(varitoinCount + 1, function () {
try {
document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input')[i].click();
casper.log('we got to anhoter variatoin ...' + i);
} catch (error) {
console.log(error);
}
i++;
});
});
});
});
try {
casper.run();
} catch (e) {
consol.log("Error..... " + e);
}
(TypeError: undefined is not a constructor )
And btw when I'm doing the same thing in a console it works fine
You have to understand that accessing DOM is not possible in Casper environment. You should switch to browser environment to execute your DOM selectors by using Casper's evaluate method. Basically it used to get some information from within browser or to manually do some actions with javascript. To understand it you have a whole section dedicated for that in official documentation.
That being said, I amended your code to properly click on different color variation inputs.
var casper = require('casper').create({
viewportSize: {
width: 1920,
height: 1080
},
pageSettings: {
loadImages: false,
loadPlugins: false
}
});
casper
.start()
.thenOpen("https://scubapro.johnsonoutdoors.com/fins/fins/seawing-nova-fin-full-foot", function () {
var varitoinCount = this.evaluate(function() {
return document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input').length;
});
var i = 0;
this.repeat(varitoinCount + 1, function() {
this.evaluate(function(iterator) {
document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input')[i].click();
}, i);
i++;
})
});
try {
casper.run();
} catch (e) {
console.log("Error..... " + e);
}
However it still doesn't change the color since website(for some reason) needs to take 2 clicks to change the color and I suggest that you throw in some waitFor functions to be sure that color has changed.
I am trying to load 12 items only each time, until the user scroll all the way down and load another 12 elements
For some reason my code doesn't work. When i upload another item, i can see it in the admin panel so it is successfully uploaded but i can't see it in the normal user view. i can only view the first 12 items uploaded and it doesn't load anymore items when i scroll.
Here is my code in the client side
if (Meteor.isClient) {
var ITEMS_INCREMENT = 12; //this one refers to the number of elements to load
Session.setDefault('itemsLimit', ITEMS_INCREMENT);
Deps.autorun(function() {
Meteor.subscribe('items', Session.get('itemsLimit'));
});
Template.list_products.helpers({
applications: function () {
var limit = Session.get("itemsLimit");
//return Products.find({}, { sort: {createdAt: -1},limit: limit }); // render latest first
return Products.find({}, { sort: {createdAt: 1},limit: limit }); // render first first
}
});
Template.list_products.moreResults = function() {
// If, once the subscription is ready, we have less rows than we
// asked for, we've got all the rows in the collection.
return Products.find({}, { sort: {createdAt: -1},limit: limit });
}
// whenever #showMoreResults becomes visible, retrieve more results
function showMoreVisible() {
var threshold, target = $("#showMoreResults");
if (!target.length) return;
threshold = $(window).scrollTop() + $(window).height() - target.height();
if (target.offset().top < threshold) {
if (!target.data("visible")) {
// console.log("target became visible (inside viewable area)");
target.data("visible", true);
Session.set("itemsLimit",
Session.get("itemsLimit") + ITEMS_INCREMENT);
}
} else {
if (target.data("visible")) {
// console.log("target became invisible (below viewable arae)");
target.data("visible", false);
}
}
}
// The below line is to run the above func every time the user scrolls
$(window).scroll(showMoreVisible);
}
Here how i solved it:
if(Meteor.isClient) {
Session.set("itemsLimit", 9); // to set the limit to 9
lastScrollTop = 0;
$(window).scroll(function(event){
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) { // to detect scroll event
var scrollTop = $(this).scrollTop();
if(scrollTop > lastScrollTop){ // detect scroll down
Session.set("itemsLimit", Session.get("itemsLimit") + 9); // when it reaches the end, add another 9 elements
}
lastScrollTop = scrollTop;
}
});
}
It works like a charm now :)
You can implement it like this:
HTML File:
<template name="yourTemplateName">
<div id="divId">
{{#each dataArr}}
//your view here.
{{/each}}
</div>
{{#if noMoreItem}}
<span>No more items to show</span>
{{/if}}
</template>
JS File:
var pageNumber = new ReactiveVar(0);
var noMoreItem = new ReactiveVar(false);
var mainContainer = // Your element here example: document.getElementById('divId')
mainContainer.addEventListener('scroll', function(){
if(mainContainer.scrollHeight - mainContainer.scrollTop === mainContainer.clientHeight) {
getMoreItems();
}
});
var getMoreItems = function () {
if(pageNumber.get() < Math.floor(Counts.get('countItems')/12)) {
pageNumber.set(Number(pageNumber.get())+1);
Meteor.subscribe('pubName', pageNumber.get(), 12);
} else {
noMoreItem.set(true);
}
}
Template.yourTemplateName.rendered = function () {
pageNumber.set(0);
Meteor.subscribe('pubName', pageNumber.get(), 12);
}
Template.yourTemplateName.helpers({
'dataArr': function () {
return CollectionName.find();
},
'noMoreItem': function () {
return noMoreItem.get();
}
})
Publication:
Meteor.publish("pubName", function (pageNumber, pageSize) {
Counts.publish(this, 'countItems', Meteor.users.find(filter), {
noReady: true
});
return CollectionName.find({}, {
skip: pageNumber > 0 ? ((pageNumber) * pageSize) : 0,
limit: pageSize
})
});
I have a custom function according to documentation. What documentation doesn't cover (or I'm blind) is how to call one function from another. Here is what I tried:
var myRactive = new Ractive({
el: '#element',
template: '#template',
data: {
function1: function() {
return 100;
},
function2: function() {
return function1() / 2;
}
}
});
It doesn't work. I tried to change it to myRactive.function1(), myRactive.data.function1(), etc. but neither of them worked out.
You can use this.get('function1') to get it from your data object, then run it as a function like this.
var myRactive = new Ractive({
el: 'body',
template: '#ele',
data: {
function1: function() {
return 100;
},
function2: function() {
return this.get('function1')() / 2;
}
}
});
Working fiddle: http://jsfiddle.net/gs3yhhsz/1/
In pre 0.7 ractive, you could access the data-object directly (this.data). This got changed, and you should now use this.get() and this.set() instead.
So I have the #add_button in my main app.js:
{ xtype: 'button', text: 'Add', itemId: 'add_criteria' }
I have the controller here that is listens for each click and attempts to add 1 each time the #add_button is clicked:
Ext.define('AM.controller.Add', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'#add_button': {
click: this.add
}
});
},
add: function(btn) {
var count = 0;
if (count <= 3)
{
count++;
console.log('Count is now ' + count;
}
else {
console.log('wut');
}
}
});
The controller is set up properly, however I can't seem to keep a count on the number of times clicked. It's telling me it's 'undefined'. Any ideas?
And yes I've seen the Sencha docs on the 'button' component. I, however am handling the event with a controller.
You are using count as a local variable, and initializing it to 0 every time your button is clicked. You need to make count a member variable of the controller.
Ext.define('AM.controller.Add', {
extend: 'Ext.app.Controller',
init: function() {
this.count = 0;
this.control({
'#add_button': {
click: this.add
}
});
},
add: function(btn) {
if (this.count <= 3)
{
this.count++;
console.log('Count is now ' + this.count);
}
else {
console.log('wut');
}
}
});