Sencha Touch 2: How to override back button on Navigation View - javascript

I was wondering how to ovverride the back button on a navigation view. I tried using onBackButtonTap but it doesnt seem to work http://www.senchafiddle.com/#8zaXf
var view = Ext.Viewport.add({
xtype: 'navigationview',
onBackButtonTap: function () {
alert('Back Button Pressed');
},
//we only give it one item by default, which will be the only item in the 'stack' when it loads
items: [
{
//items can have titles
title: 'Navigation View',
padding: 10,
//inside this first item we are going to add a button
items: [
{
xtype: 'button',
text: 'Push another view!',
handler: function() {
//when someone taps this button, it will push another view into stack
view.push({
//this one also has a title
title: 'Second View',
padding: 10,
//once again, this view has one button
items: [
{
xtype: 'button',
text: 'Pop this view!',
handler: function() {
//and when you press this button, it will pop the current view (this) out of the stack
view.pop();
}
}
]
});

The fiddle you've mentioned works well in my local project on my machine. For some reason, it doesn't work on fiddle site. Try running it on your local project.
Still instead of using onBackButtonTap config, it's good to extend Ext.navigation.View class and override onBackButtonTap method. That way you'll have more control over whole components. You'd also like to override other configs as well. Here's what I'd use -
Ext.namespace('Ext.ux.so');
Ext.define('Ext.ux.so.CustomNav',{
extend:'Ext.navigation.View',
xtype:'customnav',
config:{
},
onBackButtonTap:function(){
this.callParent(arguments);
alert('back button pressed');
}
});
the line this.callParent(arguments) will allow component to behave in default way + the way to wanted it to behave. And if you want to completely override the back button behavior you can remove this line. Try doing both ways.
To use this custom component, you can use -
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
var view = Ext.create('Ext.ux.so.CustomNav', {
fullscreen: true,
items: [{
title: 'First',
items: [{
xtype: 'button',
text: 'Push a new view!',
handler: function() {
//use the push() method to push another view. It works much like
//add() or setActiveItem(). it accepts a view instance, or you can give it
//a view config.
view.push({
title: 'Second',
html: 'Second view!'
});
}
}]
}]
});
}
Give this a shot. It'll work for you yoo.

Related

Adding multiple buttons in TinyMce in a loop doesn't work

I have a config list for buttons like this:
var config = [{
name: 'first',
insertionConfig: {
title: 'first button',
onsubmit: function(){
// do sth
}
}
},{
name: 'second',
insertionConfig: {
title: 'second button',
onsubmit: function(){
// do sth
}
}
}
]
and in my TinyMce plugin I want to add all buttons according to their config. So it would end up like this:
tinymce.PluginManager.add('myPlugin', function(editor, url) {
for (var i in config) {
item = config[i];
editor.addButton(item.name, {
text: item.name,
onclick: function() {
editor.windowManager.open({
title: item.insertionConfig.title,
onsubmit: item.insertionConfig.onsubmit
}
};
}
});
but when I click on first button, it shows the second button's title. all configs of buttons refer to last added button. I know problem is something about the 'item' in the loop (all buttons refer to same item object which is the last one) but I don't know how to fix it.
Try creating a locally scoped variable for item inside the onclick function:
The issue you are running into is how variables are managed in JavaScript at the time the function is actually run. The click function is not actually run until you click an item and at that time item is pointing to the last item in the array.
EDIT: Check out this TinyMCE Fiddle for how this may happen: http://fiddle.tinymce.com/REfaab/1

EXTJS inline initComponent method within items config

Disclaimer: I am relatively new to ExtJS (version 5.01). I am hoping to reach some ExtJS experts to point me in the right direction:
I am getting an error when specifying an initComponent method within an items config. The code below generates the error:
"Uncaught TypeError: Cannot read property 'items' of undefined"
The error disappears when the 'initComponent' function of the north-child panel is commented out. I have the feeling I missed something on initialization order.
Q: How can I specify an initComponent method of a child item within the items configuration?
Ext.define('MyApp.view.TestView', {
extend: 'Ext.panel.Panel',
title: 'Parent',
height: 300,
layout: 'border',
items: [{
xtype: 'panel',
region: 'north',
title: 'North Child',
/* Problematic function: If commented, it works */
initComponent: function(){
console.log("test north child");
this.callParent(arguments);
}
}],
initComponent: function(){
console.log("Test parent");
this.callParent(arguments);
}
});
Short answer: You can't define initComponent on a child, because you can't do anything there that can't be done anywhere else.
InitComponent is executed when an instance of the component 'MyApp.view.TestView' is created (you only defined it here, using Ext.define). It can be created using Ext.create('MyApp.view.TestView',{, or by creating another view that has this component added as an item, or by deriving another component (extend:'MyApp.view.TestView').
All the child components are also created when 'MyApp.view.TestView' is created, so the initComponent function on the child would be superfluous, because the child cannot be created without the parent, so the initComponent of the parent can be used for everything that you want to do in the child's initComponent.
If you need sth. to be calculated before the items can be addded, you would proceed as follows:
Ext.define('MyApp.view.TestView', {
extend: 'Ext.panel.Panel',
title: 'Parent',
height: 300,
layout: 'border',
initComponent: function(){
var me = this,
tf = Ext.getCmp("someTextField"),
myTitle = (tf?tf.getValue():'');
Ext.applyIf(me,{
items: [{
xtype: 'panel',
region: 'north',
title: myTitle,
}]
});
this.callParent(arguments);
}
});
Please refer to the docs what exactly Ext.applyIf does (and how it differs from Ext.apply, because that function also comes handy sometimes).

how to add back button in navigation bar in sencha touch?

In Innerdata.js, i have a a tag and on tap event i navigate it to the Group.js.
Gruop.js contain some html.I try to add here navigation bar with back button. Here the only Navigation bar is display no back button. Now this is where I fall down, I can't figure out why the Back button is not display.
I am trying to add Back button in navigation bar in Group.js page so when i click this button i navigate to the Inner.js page.so what is the problem here?
Inner.js:
Ext.define('chat.view.Inner', {
extend: 'Ext.Panel',
xtype:'Inner',
config: {
items: [
{xtype:'Innerdata'}
]
}
});
Innerdata.js:
Ext.define('chat.view.Innerdata',{
extend:'Ext.Panel',
xtype:'Innerdata',
config: {
items: [
{
html:'<a class="groupimg"><img src="stylesheets/images/groupchat.png"/></a>',
listeners: [
{
element: 'element',
delegate: 'a.groupimg',
event: 'tap',
fn: function() {
console.log('One!');
Ext.Viewport.setActiveItem(Ext.create('chat.view.Group'));
}
}
]
},
]
}
});
Group.js:
Ext.define('chat.view.Group', {
extend: 'Ext.navigation.View',
//extend: 'Ext.Panel',
xtype:'Group',
config:{
items: [
{html:'<div>Hello Hello Hello Hello</div>'}
]
},
onBackButtonTap:function(){
this.callParent(arguments);
}
});
here is the screen shot of Group.js page, i am trying to add Back button in Blue bar.
I believe there is a misuse of Ext.navigation.View in your code. Please don't use it in your situation.
Here are some explanations and instructions on how you can fix this problem:
If a view, says Group.js, is a subclass of Ext.navigation.View, it works according to push/pop pattern. Please see an example here: http://docs-origin.sencha.com/touch/2.3.0/#!/api/Ext.navigation.View. That's why a navigatioin view, which you applied to Group.js, should never have a back button on the top and very first screen.
So, there's no reason to use navigationview in this case. You just need to use a simple Ext.Container instead. So change your parent class of Group.js to Ext.Container. After that, add a toolbar on the top, add the back button to it and bind a handler.
Ext.define('chat.view.Group', {
//extend: 'Ext.navigation.View',
extend: 'Ext.Container',
xtype:'Group',
config:{
items: [
{xtype: 'toolbar',
docked: 'top',
items: [
{xtype: 'button',
text: 'Back',
ui: 'back',
handler: function(){Ext.Viewport.setActiveItem(Ext.create('chat.view.Inner'));}}
]}
{html:'<div>Hello Hello Hello Hello</div>'}
]
},
});

Added an enter event to EXT JS Application search text box to fire search

Hi I have the code below my my enter event is never triggering, any help will be appreciated.
items: [{
xtype: 'textfield',
id: 'idhere',
name: 'namehere',
fieldLabel: 'lablehere:',
width: 500,
handler: {
key:13,
fn : function () {
if (e.getKey() == e.ENTER) {
alert("You pressed an enter button in text field.");
}
}
}
},{
xtype: 'button',
text: 'texttodisplay',
handler: function() {
//my function.
}
}]
I actually solved this by using:
listeners: {
specialkey: function (f,e) {
if (e.getKey() == e.ENTER) {
loadData();
}
}
}
I am not sure why Sencha never included Ext.ux.form.SearchField in the API docs but the component has been included in all versions of the framework I've used. It is set-up to fire a submit and a cancel event and includes the appropriate search and cancel buttons attached to the field.
You can find it in your framework files at: [extjs-root]\examples\ux\form\SearchField.js
I would recommend using that component instead of trying to create your own searchfield. I usually override the default search function to fit my own needs but there have been a few scenarios where I did not need to also.
If you add a requires statement at the top of your component JS you can create it like any other (non-UX) component:
E.g:
Requires statement:
Ext.define('MyApp.view.SomeComponent', {
extend: 'Ext.grid.Panel',
alias: 'widget.mycomponent',
requires: [
'Ext.ux.form.SearchField'
],
...
Creating a search field in the panel's bottom toolbar:
bbar: {
items: [{
text: 'A Button'
}, {
text: 'Another Button'
}, '-', {
xtype: 'searchfield', // <- can use this xtype with requires stmt
itemId: 'search',
width: 250,
emptyText: 'Enter first and last name to search...'
}]
},
...
If you have trouble with the requires statement you could also just create it like this:
var search = Ext.create('Ext.ux.form.SearchField', {
itemId: 'search',
width: 250,
emptyText: 'Enter first and last name to search...'
});
Just to supply how to add such a listener. There is a specialkey event that can be used for such a case
fieldinstance.on('specialkey', function(f, e){
if (e.getKey() == e.ENTER) {
// your action
}
});
Anyway I recommend to use the ux component that #Geronimo mentioned

ExtJS and this.control query

I have an issue with the next code block:
run: function(e, row){
var me = this;
var container = Ext.getCmp('centercontainer');
try {
container.removeAll();
} catch(e) { }
// This block is called from another file, I just put it here to show you.
me.panels = [{
xtype: 'tabpanel',
id: 'containertabpanel',
items: [{
itemId: 'package',
title: me.PackageTitle
},{
itemId: 'excursion',
title: me.ExcursionTitle
}]
}];
// Reset
container.setTitle(me.EditDestinationTitle + row.data.name);
container.add(me.panels);
me.tabs = container.getComponent('containertabpanel');
// console.log(Ext.ComponentQuery.query('#containertabpanel > #package'))
me.control({
// Work with
// 'tab': {
// Doesn't work
'containertabpanel > package': {
mouseover: me.doPackage
}
})
},
Anyone knows how do I get to catch the click event of "package" item of tabpanel component?
I saw when I use just "tab" selector on this.control query, that work, but I can't get only "package" tab component.
Thank you in advance.
In your definition of your tabpanel you can specify -
listeners:{
click:{
fn: function(){
//click handling code goes here
}
}
}
If I understood correctly this is controller code and you are trying to catch an item click on the panel which is one of many in a tabpanel
What you can do is identify your panel by any property that is unique to it via the component query syntax like this: button[myprop=blah]
This syntax will match any buttons on the page with the following config:
{
xtype:'button'
myprop:'blah'
}
In your case you can try tab[itemId=package]
What you also need to be careful about is controller can listening only for events that are fired by the components. Make sure the event you are listening for is fired (check the docs). You can always fire custom events if necessary.
You need to do this
me.control({
// Work with
// 'tab': {
// Doesn't work
'containertabpanel > #package': {
mouseover: me.doPackage
}
})

Categories