I have a small query with regards to Sencha Touch. i am trying to program some code which has an event kickstart as you scroll down the main panel (The end ideal experiment I am trying to achieve is to get the Panel to render images as you scroll down, but at the moment I am settling for just firing off a console.log from a function).
I was wondering if anyone knew of a method which would the program to detect how far down someone has scrolled vertically and fire off an event once you reach a certain y coordinate. I know of the scrollTo event, but I cannot seem to find any events which allow me to detect the x and y coordinate.
The basic coding for my panel is as follows:
headlinepanel = new Ext.Panel(
{
layout:
{
type:'vbox',
align:'stretch'
},
monitorOrientation: true,
scroll:
{
direction: 'vertical',
bounces: false,
outOfBoundRestrictFactor : 0,
threshold:20,
},
style: 'background-color:black;',
listeners:
{
afterrender: function()
{
if(headlinepanel.scroller.offsetBoundary.bottom == 500)
{
console.log("You are here!");
}
}
}
});
This is what I have at the moment and I tried to see if I could get the offsetBoundary property to work, but none of my programming friends has tried something like this before, so I am not very familar with this. I would appriciate any help, but I understand if this is not really possible with Sencha. Thank you for reading this.
This is how you listen for scroll events:
headlinepanel.scroller.on('scroll',function(me,offset){
console.log(offset.x);
console.log(offset.y);
});
This event is fire on every change, there are other events too. Check the API here: http://docs.sencha.com/touch/1-1/#!/api/Ext.util.Scroller-event-scroll
And here is an example: http://jsfiddle.net/sSyqF/14/
Related
I'm using the Cytoscape Qtip extension to display qtips when you click nodes.
Usually you can prevent qtips from hiding when with the hide: false option. When this is used, you can still hide the qtips if it has a button.
However, when using cytoscape, this appears to not work. When clicking else where, a hide event will be triggered.
cy.elements().qtip({
content: function(event, api){
api.set('content.button', true);
return 'Example qTip on ele ' + this.id();
},
position: {
my: 'top center',
at: 'bottom center'
},
hide: false,
style: {
classes: 'qtip-bootstrap',
tip: {
width: 16,
height: 8
}
}
events: {
hide: function(event, api){
console.log(event);
}
}
});
I can prevent the hide event from following through with event.preventDefault(), but this will also stop the the close button from hiding the event, which is a bit messy.
Any idea while it's behaving this way?
Here's the quick and dirty to make this work (closes on button close only) if you need it:
events:{
hide: function(event, api){
if(event.originalEvent.target.parentElement.parentElement.id != this[0].id){
event.preventDefault();
}
}
Explanation:
Any mouse clicks will trigger a hide event all visible qtips.
We look at target of that mouse click (event.originalEvent.target.parentElement.parentElement.id) to see it close box of the qtip that is currently try to close. If it's not then we preventDefault().
This is potentially pretty bed performance wise, because it run these preventDefault() for every open qtip on every mouse click.
Remember that because this wraps Qtip on non-DOM elements, bindings to Cytoscape graph elements must be made. These bindings are outside of the DOM and outside of Qtip's control (for example, the hide case).
Did you try setting the hide event to the empty string ""?
Cleanest solution I've found is to give a garbage event for the hide event.
Using null, false or "" all don't seem to work.
hide: {
event: "asdf" //garbage event to allow hiding on close button click only
},
I'm using Hammer.js to look for horizontal pan gestures, I've devised a simple function to clicks a button when panned left or right. It works okay, except the vertical scroll doesn't do anything on a touch device, or it's really glitchy and weird.
Here's the function:
var panelSliderPan = function() {
// Pan options
myOptions = {
// possible option
};
var myElement = document.querySelector('.scroll__inner'),
mc = new Hammer.Manager(myElement);
mc.add(new Hammer.Pan(myOptions));
// Pan control
var panIt = function(e) {
// I'm checking the direction here, my common sense says it shouldn't
// affect the vertical gestures, but it blocks them somehow
// 2 means it's left pan
if (e.direction === 2) {
$('.controls__btn--next').click();
// 4 == right
} else if (e.direction === 4) {
$('.controls__btn--prev').click();
}
};
// Call it
mc.on("panstart", function(e) {
panIt(e);
});
};
I've tried to add a horizontal direction to the recognizer but it didn't really help (not sure if I did it even right):
mc = new Hammer.Manager(myElement, {
recognizers: [
[Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL }],
]
});
Thanks!
Try setting the touch-action property to auto.
mc = new Hammer.Manager(myElement, {
touchAction: 'auto',
recognizers: [
[Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL }],
]
});
From the hammer.js docs:
When you set the touchAction to auto it doesnt prevent any defaults, and Hammer would probably break. You have to call preventDefault manually to fix this. You should only use this if you know what you're doing.
User patforna is correct. You need to adjust the touch-action property. This will fix scrolling not working when you have hammer bound on a big element in mobile.
You create a Hammer instance like so
var h = new Hammer(options.contentEl, {
touchAction : 'auto'
});
I was working on a pull to refresh feature, so I need the pan event.
Add the recognizers.
h.get( 'pan' ).set({
direction : Hammer.DIRECTION_VERTICAL,
});
h.on('panstart pandown panup panend', eventHandler);
Inside the eventhandler, you'd look at the event that was triggered and manually call on event.preventDefault() when you require it. This is applicable for hammer 2.0.6.
For anyone who's looking the pull to refresh code was taken from - https://github.com/apeatling/web-pull-to-refresh
My problem was that vertical scroll was toggling a sidebar that was supposed to show/hide on horizontal pan/swipe. After looking at the event details, I realized that Hammer probably triggers panleft and panright event based on X delta and doesn't consider Y delta, so my quick solution was to check the pan direction in my handler:
this.$data.$hammer.on('panleft', (e) => {
if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
return;
}
this.isVisible = true;
});
I was stuck on this for several days. Hope this will fix your problem.
mc = new Hammer(myElement, {
inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput,
touchAction: 'auto',
});
When the relevant gesture is triggered, we applied a css class to the element, that would set the touch-action to none.
mc.on('panmove panstart', event => {
mc.addClass('is-dragging');
}
);
.is-dragging {
touch-action: none !important;
}
Hammer 2.x does not support vertical swipe/pan. Documentation says:
Notes:
When calling Hammer() to create a simple instance, the pan and swipe recognizers are configured to only detect horizontal gestures
You can however use older 1.1.x version, which supports vertical gestures
——
Clarification: this refers to a ‘simple instance’ which is when you don’t pass in any recognizer configuration as the second parameter. In other words these are the defaults but can (and usually should) be overridden.
Highcharts offers the opportunity to detect clicks on chart points, but is it possible
to detect other events, such as the double click or mousedown event?
Thanks in advance
Each component only supports certain events, for example the Chart component will detect addSeries, click, load, redraw, and selection. I don't believe this set is extensible, so you can't capture a different event like mousedown.
You could try to inspect the source of your page and attach listeners to the elements that HighCharts generates, but this would be an undocumented work-around and would be liable to break in future releases. In addition, if you have to support < IE9 you would need handlers for both SVG and VML generated markup.
You can get creative with some events. Here's an example of detecting a double click using a click handler:
Working Demo
var clickDetected = false;
// create the chart
$('#container').highcharts({
chart: {
events: {
click: function(event) {
if(clickDetected) {
alert ('x: '+ event.xAxis[0].value +', y: '+ event.yAxis[0].value);
clickDetected = false;
} else {
clickDetected = true;
setTimeout(function() {
clickDetected = false;
}, 500);
}
}
}
},
...
It's possible, but in a different way. In Highcharts you can add event to each element using element.on. For example:
chart.series[0].data[0].graphic.on('dblclick', function() {
//callback here
});
And simple jsFiddle for you. Good thing is that you can add to all elements, and make sure work in all browsers.
I have read the SO question: Controller for Buttons Sencha Touch 2 [Solved] to achieve tapping the button. It works!
Unfortunately, I need tapping on the container, not the button. Once I change xtype:'container', to xtype:'button', it taps fine and I see the console.log message so everything works fine. Once I change it back to xtype:'container', it stops working, there is no console.log message.
So, my question is: how to make tap event working for my xtype:'container'? Why does it work for buttons only? Am I missing something?
P.S. As far as I see there is no tap event for container. What's the solution then? Would making a button to have several strings of a text and a background be a solution?
OK, based on your answers, it is still unclear, how to make the button look like the container. The container is an image with two strings above. Here is my container:
{
xtype:'container',
cls:'home-img',
id: 'home-img',
layout : {
type : 'vbox',
align: 'middle'
},
items:[
{ xtype:'container',
html:'Your current rate is:'
},
{ xtype:'container',
tpl:'{rate}'
}
],
},
Once I replace xtype:'container', with xtype:'button', I'm having difficulties to show {rate} parameter and unable to make two strings.
I'm not a pro at sencha touch, but in this case i think you need a listener on the element.
this is what works for me:
Ext.define('RSSFramework.view.ListContainer', {
extend: 'Ext.Container',
config: {
layout: {
type: 'fit'
},
listeners:[
{
element: 'element',
event: 'tap',
fn: function() {
console.log('TAP!');
}
}
]
}
});
In Sencha, there is no tap event available for a container. A container basically works like something which can hold different inner components/elements. However, you can indeed workaround if you want a tap event to be placed on container. As you have mentioned, you can go ahead and create a button, set a background, and set some strings (But that's not what a button should be used for, though). Or you can just set HTML with the desired string and background, make it a div and set Onclick event on it.
I'm having some trouble with blur and click events in backbone. I have a view (code below) that creates a little search entry div with a button. I pop open this div and put focus on the entry field. If someone clicks off (blur) I notify a parent view to close this one. If they click on the button I'll initiate a search.
The blur behavior works fine, however when I click on the button I also get a blur event and can't get the click event. Have I got this structured right?
BTW, some other posts have suggested things like adding timers to the div in case its being closed before the click event fires. I can comment out the close completely and still only get the blur event. Do these only fire one at a time on some kind of first-com-first-served basis?
PB_SearchEntryView = Backbone.View.extend({
template: _.template("<div id='searchEntry' class='searchEntry'><input id='part'></input><button id='findit'>Search</button></div>"),
events: {
"click button": "find",
"blur #part": "close"
},
initialize: function(args) {
this.dad = args.dad;
},
render: function(){
$(this.el).html(this.template());
return this;
},
close: function(event){ this.dad.close(); },
find: function() {
alert("Find!");
}
});
I am not sure what the problem was, but here is the jsbin code.