Click event on view not firing in Titanium Appcelerator - appcelerator

In my controller, I populate a TableView with rows dynamically by building up an array of TableViewRow and populating it with a View & Image.
Here's the code that creates the View & ImageView and a click event on the view:
// Create product image view
var productImageView = Titanium.UI.createView({
borderRadius: 5,
left: 10,
top: 10,
bottom: 10,
width: 130,
backgroundColor: '#FFFFFF',
productName: Name,
imageUrl: ThumbnailUrl,
});
productImageView.add(Titanium.UI.createImageView({
backgroundColor: '#FFFFFF',
defaultImage: 'image-missing',
image: ThumbnailUrl
}));
productImageView.addEventListener('click', function(e) {
if (e.source.productName && e.source.imageUrl) {
Alloy.createController('view_product_image', { ProductName: e.source.productName, ImageUrl: e.source.imageUrl }).getView().open({
modalTransitionStyle: Ti.UI.iPhone.MODAL_TRANSITION_STYLE_COVER_VERTICAL,
modalStyle: Ti.UI.iPhone.MODAL_PRESENTATION_FORMSHEET
});
} else {
console.log('data not set');
}
});
When this code runs, within the table row, I can see the image. When I click it, nothing happens. I tried attaching the click event on the ImageView directly also but still nothing happens.
Any ideas why the click event is not getting fired? Should I be subscribing to a different event instead?

You are not receiving click event because your event source is imageview and it has no productName and imageUrl property.
To receive click event of view, you need to set touchEnabled property to false of your image view.
productImageView.add(Titanium.UI.createImageView({
backgroundColor: '#FFFFFF',
defaultImage: 'image-missing',
image: ThumbnailUrl,
touchEnabled :false
}));
however I think instead of adding a listener to each view you can add a common Listener to tableView and handle the event based on e.source.productName property as suggested by others.

I tried your code and it works for me on iOS and Android.
Maybe, can you show the TableView creation?
However, although your solution is correct, it is preferable and more efficient to add a event listener at your TableView not inside a TableViewRow due the number of listeners that will be created, then to reduce the scope of your click event only to the image, You check if the e.source has the productName and imageURL properties (e.g), otherwise you can infer that the click was outside the image.
Try like this:
$.tableView.addEventListener('click', function(e) {
if (e.source.productName && e.source.imageUrl)
console.log('hit')
});

Related

Unable to access UserMin/UserMax in eventObject of click event in RangeSelector in Highcharts

I am working on a task where I have implemented RangeSelector in Highcharts(in React using functional components). I have implemented a click event for month category. In the event handler I need to access UserMin and UserMax values which are inside the event object present as argument. But, I am unable to access only those two properties in the event object which has the form
PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
You can check this fiddle https://jsfiddle.net/pravindvarma/k65eq92v/
When you click on the month button, the console shows this object. When I click on YTD, it shows undefined for e.xAxis.
Thank you
You can use afterSetExtremes event, check if it is triggered by range selector button and get the userMin and userMax values.
xAxis: {
events: {
afterSetExtremes: function(e){
if (e.trigger === 'rangeSelectorButton') {
const { userMin, userMax } = e;
console.log(userMin, userMax);
}
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/362gv98u/
API Reference: https://api.highcharts.com/highcharts/xAxis.events.afterSetExtremes

Horizontal scrolling issue using angularjs-dragula

I am using angularjs-dragula and I am not able to auto scroll to the overflow container that is hidden from the screen.
This is my issue:
I have five containers in my dragula and the 5th container is hidden from the screen. Now I want to drag an element from the first container and drop it in the 5th container. But I am not able to do this, since the screen is not auto scrolling to the 5th container.
Does angularjs-dragula support vertical scrolling? or is there a property that I'm missing?
Example Plunkr : https://plnkr.co/edit/iD38MugmHIx298p7OlrI?p=preview
var app = angular.module('angular-dragula-demo', [angularDragula(angular)]);
app.controller('MainCtrl', function($scope, dragulaService) {
dragulaService.options($scope, 'fifth-bag', {
copy: true
});
});
It seems like this option is not implemented in Dragula. Dragula's developer suggests to use the module dom-autoscroller.
See this issue on Github: https://github.com/bevacqua/dragula/issues/121
To implement this functionality with AngularJS:
1) Download dom-autoscroller from the official repo: https://github.com/hollowdoor/dom_autoscroller/blob/master/dist/dom-autoscroller.min.js
2) Include it in your project folder
3) Enable autoscroll in your controller:
// ENABLE AUTOSCROLL FOR GOALS LIST
var scroll = autoScroll([
document.querySelector('.list')
], {
margin: 30,
maxSpeed: 10,
scrollWhenOutside: true,
autoScroll: function () {
//Only scroll when the pointer is down
return this.down
}
});

ExtJS BoxComponent - show tooltip while loading an image

I have an ExtJS popup in my application.
Inside the popup there is a BoxComponent with an image. The image usually takes a few seconds to load. I would like to show a "Loading..." spinner message in the box to inform the user know that something is happening.
Here is a sample of my code right now:
function createPopup(id) {
picUrl='/create_image.py?date='+id
popup = new GeoExt.Popup({
title: 'Info: ' + id,
height: 350,
width:425,
items: [pic]
});
pic = new Ext.BoxComponent({
id: 'pic',
autoEl: {tag: 'img', src: picUrl},
border: false,
width: 400,
height: 300,
listeners: {
//SHOULD I HANDLE MY PROGRESS SPINNER SOMEWHERE HERE???
}
});
popup.show();
}
I'm a newbie to ExtJs and I couldn't figure out how to do this.
I assume that I probably must create two event listeners:
The first event is when the BoxComponent (or the popup?) appears.
The second event is when the image finishes loading. In the first event, I show the progress spinner and in the second event, I hide the progress spinner.
What are the events in the Ext.BoxComponent or in the Ext.Popup that I should use?
Or is there an easier way to show the progress spinner while the image is loading?
I suggest by default having a rule on an image component that shows a background image of spinner, and then place a listener for onload which would remove the rule to hide it.
The suggestion by Vu Nguyen set me on the right track. My version of ExtJs is 3.4 so I couldn't use 'image component'. But I discovered the Ext.LoadMask component that works well as a loading progress spinner. First, I attached the LoadMask to the popup.el element. The next trick was to capture the render event of the BoxComponent and the load event of the image. In the render event I show the LoadMask spinner and in the load event I hide it:
pic = new Ext.BoxComponent({
id: 'pic',
autoEl: {
tag: 'img',
src: picUrl
},
border: false,
width: 400,
height: 300,
listeners: {
render: function (c) {
var myMask = new Ext.LoadMask(popup.el, {
msg: "Loading station data..."
})
//show the spinner when image starts loading
myMask.show()
c.getEl().on('load', function () {
//hide the spinner when image finishes loading
myMask.hide()
})
}
}
})
popup = new GeoExt.Popup({
title: 'Info: ' + stname,
height: 350,
width: 425,
items: [pic]
})
popup.show()

Cancel panel opening from toolbar widget onClick handler

I have a Firefox extension which adds a toolbar Widget with a panel which should display when the widget is clicked. Under certain circumstances, the panel should not show when the toolbar widget is clicked.
I am instantiating the toolbar and panel like so:
var popup = panel.Panel({
width: 310,
height: 400,
contentURL: self.data.url('panel.html'),
contentScriptFile: self.data.url('panel.js'),
// NOTE: You can't use the contentStyleFile option here.
});
var toolbarOptions = {
id: 'someid',
label: 'Some Label',
contentURL: self.data.url('icon-16.png'),
panel: popup
};
// There doesn't seem to be a way to remove the toolbar in PB mode.
var toolbar = widgets.Widget(toolbarOptions);
How can I cancel the panel opening from the widget click handler? It seems to always open no matter what logic I put in there.
toolbar.on('click', function() {
if (dontShowPanel()){
// I want to somehow cancel the panel opening at this point.
} else {
panel.show();
}
});
I have tried to return false; from the click hander which doesn't seem to work. I have also tried to call panel.hide(). That doesn't seem to work either.
I'm using version 1.10 of the add-on SDK.
Your click event handler is called before the panel shows up which means that you can still change the panel at this point. However, something that is non-obvious: changing the panel of the Widget object won't have any immediate effect, you need to change it for the WidgetView object (the widget instance in the particular browser window). That object is being passed as a parameter to the click event handler. So your toolbar options could look like this:
var toolbarOptions = {
id: 'someid',
label: 'Some Label',
contentURL: self.data.url('icon-16.png'),
onClick: function(view) {
if (dontShowPanel()){
view.panel = null;
} else {
view.panel = popup;
}
}
};
When you create the widget, you need to add the panel instance as a property:
var panel = require("panel").Panel({
width: 250,
height: 250,
contentURL: data.url('panel.html')
});
require("widget").Widget({
id: 'id',
label: 'my-label',
contentURL: data.url('http://www.mozilla.org/favicon.ico'),
panel: panel
});
Update: sorry I didn't understand the entire question. As far as I know there is no way to conditionally prevent show the panel based on the click event, in a way that will preserve the anchoring.

Appcelerator TableViewRow swipe

Does anyone know of a hack to allow for a left->right swipe on a tableviewrow. The default swipe action opens a delete button however I require additional buttons but want to maintain the same UX but the "swipe" event listener doesn't seem to fire on rows.
myTblRow.addEventListener('swipe', function(e){
Titanium.API.info("huzzah, a row was swiped");
});
The above == no dice.
It does require a bit of a hack.. remove the editable property on the tableView declaration.
The hack is to apply a view that covers the tableRow:
var row1 = Titanium.UI.createView({
width: Titanium.Platform.displayCaps.platformWidth,
height: 145,
zIndex: 100,
opacity: 0.1
});
row.add(row1);
Notice the zIndex, the opacity makes it exist but be totally transparent.
You now need to create a 'swipe' event listener:
tableView.addEventListener('swipe', function(e){
tableView.updateRow(e.index, createUpdateRow(e.source.myProperty), {
animationStyle: Titanium.UI.iPhone.RowAnimationStyle.LEFT
});
});
When the event fires, createUpdateRow() is called, which returns a tableRow. This tableRow you add all of your custom buttons to, you can change the height of the row, anything. The animation style property will mean if you swipe from the right > left, the new row will animate in from the left, which is an effect I like..
Hope this helps, anyone else.. The extra View (row1) is what got me for ages!

Resources