I'd like to be able to hide and show certain buttons in a navigation view bar when a view is push and popped onto the view stack. Shame I can't control that from the view config itself (but I'll save that moan for another time).
I wanted to know which events I should be using when a view is push/popped on a navigation view. The docs sometimes lie and I've been told many times not too trust it, so I'm not! Come on Sencha, Microsoft wouldn't get away with this!
So Any ideas? When I try to print out all the events for a view I get very unreliable behaviour:
What I've found:
When I push a view I get:
initialize
hide
show
When I pop a view I get:
hide
show
What the flip is going on?!?
The code to show events happening:
control: {
myViewRef: {
initialize: function() { console.log("initialize") },
activated: function() { console.log("activated") },
deactivated: function() { console.log("deactivated") },
painted: function() { console.log("painted") },
show: function() { console.log("show") },
hide: function() { console.log("hide") }
},
}
The code to actually push/pop a view:
onInBoxListViewItemTap: function(scope, index, item, record) {
console.log("onInBoxListViewItemTap");
var detailsView = this.getEnquiryDetailsViewRef();
// push view
var navview = this.getMyInboxViewRef();
navview.push(detailsView);
}
Does this stuff actually work properly i.e. Are there concrete events which are guaranteed to fire when a view is pushed and popped?
First of all - you have a typo in your code. You need to reference activate and deactivate not activate_d and deactivate_d.
Second, I would try to subscribe to push and pop events of navigation view and see if it would get you what you want.
I have the same problem.I use painted handler to solve it.
You can't handle 'painted' event in controller
the painted event description
Related
I have a navigationView with some items on it, if I pop the item, and push a modified one back, the event listeners in my controller no longer trigger. How can I get them to work again? I don't get it because each item destroyed and created from scratch when I push it back. Autodestroy is enabled.
//Add a view
this.view = Ext.create('ec.view.view1')
this.getNavigation().push(this.view);
//Remove a view (or press back in the navigationview)
this.getNavigation().pop();
//Add a fresh view back
this.view = Ext.create('ec.view.view1')
this.getNavigation().push(this.view);
Controller tap handler
refs {
button : '#button'
},
control : {
button : {
tap: 'OnTap'
}
},
OnTap: function() { console.log("Tap") }
With the above, all the events, taps, etc break for the view
I had the same issue, search for loads of forums, lost lots of time, got angry about Sencha support and finally moved the button handler code from the controller back into the view:
xtype: 'button',
text: 'Save',
handler: function(button, event) {
console.log('button pressed');
}
"Dirty", but it works.
I suspect the cause of this behavior is NavigationView.pop() destroying the actual NavigationView, but not it's subordinate objects.
Double clicking fast on a button in Sencha Touch 2 when having a navigation view will on some Android device push the new view twice on the view stack, how to solve it? Doesnt happen on iPhone
If you're having problems with the single click, then wrap the event function in a delayed task... for instance:
tap: function(button, e, eOpts) {
if(this.delayedTask == null){
this.delayedTask = Ext.create('Ext.util.DelayedTask', function() {
this.myFunctionToCall();
this.delayedTask = null;
}, this);
this.delayedTask.delay(500);
}
}
So in the example above, if another tap is registered and this.delayedTask has yet to be null, then it will not create the new delayed task which ultimately calls whatever function you need after 500 miliseconds... hope this makes sense, it's also a way to create double tap events on buttons...
This issue is a bit old but I was facing the same issue in the app I'm working on in my company. This is especially frustrating when buttons are bound to an Ajax call.
I took back Jeff Wooden's solution to override every button in my app :
Ext.define('MyApp.override.CustomButton', {
override : 'Ext.Button',
doTap: function(me, e) {
if(this.delayedTask == null){
this.callOverridden(arguments);
this.delayedTask = Ext.create('Ext.util.DelayedTask', function() {
this.delayedTask = null;
}, this);
this.delayedTask.delay(500);
} else {
console.log("Preventing double tap");
}
}
});
How does it works?
Each button action will trigger a delayedTask which will intercept button action for 500 ms, therefore preventing doubletap
This will work for 'tap' and 'handler:', which both pass through 'doTap' method
this is linked to the current button so it won't reverberate on other buttons
To use it simply add it in your app.js 'requires' block
Ext.application({
requires: [
...
'MyApp.override.CustomButton',
...
],
Helpfull Sources :
https://www.sencha.com/forum/showthread.php?173374-Ext-override()-on-Ext-components-in-ExtJS-4-x
Best practice for overriding classes / properties in ExtJS?
this post
I have a tabpanel with items of nestedlists. Each nested list goes several levels deep. If I drill down one of the nested list, then i click on a different item in the tabpanel, then click back to it, the nested list is still drilled down, instead of refreshing to the top level of the nested list.
How do I get the nestedlist to display the top level instead of the drilled down level everytime I return to it?
Additional Info
OK, I'm part way there. Here's the code I have now:
var tabBar = new Ext.TabPanel({
fullscreen: true,
id : 'footer',
cardSwitchAnimation:false,
listeners: {
cardswitch: {
fn: function() {
Ext.getCmp('footer').getActiveItem().setActiveItem(0);
}
}
},
tabBar: {
dock: 'bottom'
},
items: [/* some nestedlist components */]
});
So the final problem is that everytime I cardswitch, I see the "drillup/slideback" animation of the nested list sliding back or drilling back to the top level item. How do I get it to just show the top level item without this drill up/slide back animation? I want to preserve the slide forward and drill down animation when the user drills down the nestedlist.
You can try to set the cardSwitchAnimation parameter to false in the setActiveItem method
[UPDATE] Deselect item
Add an event listener for the item tap event on the nested list
nestedList.on("itemtap", function(nestedlist, index, item, e){setTimeout(function(){nestedlist(index);},500);}, this);
[UPDATE] From John
For some reason your code didn't do anything for me. But this one worked:
var nestedList = new Ext.NestedList({
store: store,
listeners: {
itemtap: function(dv, ix, item, e) {
// Clear the selection soon
setTimeout(function(){dv.deselect(ix);},500);
}
}
});
In March 2014, with version 2.3.1, I had the above problem with the Ext.dataview.NestedList object. The suggested approach of using the "deselect" method did not work for me - probably because of the two years that have gone by since the original question.
To resolve problem, I used the following:
nestedList.goToNode( nestedList.getStore().getRoot() );
Sencha Touch 1.1.1 --
Is there a way to set up a listener to listen for click events on the Back button of a NestedList? I can only find examples of how to set up for clicks on the 'body' or 'el' element. How would you be more specific and target the NestedList's back button?
Many Thanks
Code so far
MyTest.views.Justacard = Ext.extend(Ext.NestedList, {
title: "The Title",
...
listeners: {
click: {
element: 'el', // ANYTHING HERE TO TARGET THE BACK BUTTON?
fn: function(){
// do action
}
}
}
});
Ext.reg('justacard', MyTest.views.Justacard);
On a side note: because the NestedList component adds the back button automatically, there's no opportuity to configure it and add a handler (I think).
PS: adding the following code (below title: for example) allows me to respond to the Back button clicks - however, it also removes all the normal Back button functionality and the NestedList no longer slides back to the parent list.
onBackTap: function() {
alert('boo');
}
Turning into a proper 'lumpy carpet' scenario ; )
Try
MyTest.views.Justacard = Ext.extend(Ext.NestedList, {
title: "The Title",
...
listeners: {
back: function() {
alert('back?');
}
}
});
or
onBackTap: function() {
this.callParent(arguments);
alert('boo');
}
P.S. Sorry, I didn't test this (just looked at sources)
I have a nestedList with a few levels that appears when the user presses a button on the screen. When the nestedList appears, there is no back button (because we're at the top of the tree, so understandably there is nowhere to go back to), whereas tapping on items in the list takes you to screens with a back button.
I'd like to add a back button to the first screen. I have managed to do this, but not without adding the same back button to every sublist in the nestedList - this has the effect of 1 back button at the top level, and 2 back buttons (one to take you out of the nestledList completely, and one to take you up a level) at every subsequent level.
Can anyone help me figure out how to have 1 back button on each screen, including the top level to close the list?
Many thanks
PS a nasty workaround that I'm using at the moment is to have a "close" button in the top right of every screen instead.
I don't know how comfortable you are with the inner workings of Sencha Touch so how you go about doing this is up to you--
The back button is there, hidden, when the nested list is shown (created in the initComponent function with hidden: true), and then onBackTap, onItemTap and setActivePath will all call syncToolbar near the end of their functions which is where the back button is hidden when you are at a depth of 0.
So there are 2 places you need to do something about, first is initComponent which is easy-- just implement initComponent in your nestedList, call the superclass' initComponent and then set the backButton visible
var myNestedList = new Ext.NestedList({
...,
initComponent: function() {
myNestedList.superclass.initComponent.call(this);
this.backButton.setVisible(true);
},
...
});
That takes care of showing it intially.. how you care to deal with fixing syncToolbar is up to you. You can use Ext.override, you can straight up copy and paste the whole syncToolbar function into your nestedList object which would also override it or you could do what you're told never to do and just edit the sencha-touch.js file directly. However you decide to do it, what you're looking to change is
syncToolbar: function(card) {
...
backToggleMth = (depth !== 0) ? 'show' : 'hide';
if (backBtn) {
backBtn[backToggleMth]();
if (parentNode) {
backBtn.setText(backBtnText);
}
}
... };
You can either change backToggleMth to = 'show' or just delete the if (backBtn {...} all together.
In the Sencha Touch 2.2 I had to use a different code:
Ext.create('Ext.NestedList', {
...,
listeners: {
initialize: function(obj) {
obj.getBackButton().show();
},
back: function(obj, node, lastActiveList, detailCardActive) {
switch(node.getDepth()) {
case 1:
obj.getBackButton().show();
break;
case 0:
alert("wohooooooo!");
break;
}
}
}
}