Fail to catch tab change event - javascript

I'm using button to move between tabs. But for that I have to remember the user's tab position. So my buttons keep working when the user leaves the screen and returns later.
The tabchange event should be the event to use for that, however I cannot get it to trigger.
View:
Ext.define('MyApp1.view.Home',
{
extend: 'Ext.form.Panel',
requires:
[
'Ext.tab.Panel'
],
xtype: 'home',
config:
{
itemId: 'home',
layout: 'fit',
items:
{
xtype: 'tabpanel',
tabBarPosition: 'top',
height: 500,
renderTo: document.body,
listeners:
{
beforetabchange: function (tabs, newTab, oldTab)
{
console.log('tab is going to change');
},
tabchange: function ()
{
console.log('recorded tab change from listener');
},
change: function ()
{
console.log('change of tab from listener');
}
},
items:
[
{
title: 'one'
},
{
title: 'two'
}
]
}
}
});
Controller:
Ext.define('MyApp1.controller.HomeController',
{
extend: 'Ext.app.Controller',
requires:
[
'MyApp1.view.Main'
],
config:
{
refs:
{
home: 'home'
},
control:
{
home:
{
beforetabchange: 'onTabChange',
tabchange: 'onTabChange',
change: 'onTabChange'
}
}
},
init: function()
{
console.log('HomeController initialized');
},
onTabChange: function ()
{
console.log('active tab changed');
}
});
So I see the initialization text in the log but none of the tab change events when I click the tab buttons.

First off it seems you can only implement these listeners on the tabBar of the tabPanel
Having looked through the source code though it seems that this never get's fired even though it is documented. http://docs-origin.sencha.com/touch/2.4/2.4.1-apidocs/source/Bar3.html#Ext-tab-Bar-event-tabchange
What I could suggest is either as you pointed out to hook into the activeitemchange event on the panel or activetabchange (which strangely is firing twice) event of the tabbar as activeitemchange also seems not to work as intended.
https://fiddle.sencha.com/#fiddle/g44

Turns out I was looking at the ExtJs 5 docs, instead of the Sencha 2.4.1 docs...
Which only has the 'activeitemchange' event.

Related

Prevent Click Event from document Level to child elements

I am create a hybrid app using Sencha frame work where I have a setting screen, when setting screen is visible in the screen I want to prevent all the touch event from the user to other components except specific views. I saw some of the post saying that event the stopProgation() and preventDefault() will the event further But i am not clear about It.
I tried to add click event to document to release my setting list from the view when user tap on the screen but if the user tap on other component in that screen it will trigger that button action also, how to prevent this.
Also I don't want to prevent the action of touch when user click on setting list or some specific component in my view.
Note: I not able to use jquery in this project because using jquery side by with Sencha may cause performance issue.
Code:
Ext.define('MyApp.view.ControlPanel.ControlPanel', {
extend: 'Ext.Container',
alias: "widget.controlpanel",
requires: [
'Ext.SegmentedButton'
],
config: {
layout: {
pack:'stretch'
},
docked:'bottom'
},
documentClickHandler:function(event){
console.log('Document Clicked');
document.removeEventListener('click', arguments.callee, false);
var settingListContainer = Ext.ComponentQuery.query("#setting-list-container")[0];
if (settingListContainer) {
var controlpanel = settingListContainer.up('controlpanel');
if (controlpanel) {
controlpanel.remove(settingListContainer, true);
var segmentButton = controlpanel.down("#control-segment-button");
if (segmentButton) {
segmentButton.setPressedButtons();
}
}
}
event.preventDefault();
return false;;
},
onSegmentToggled: function (container, button, pressed)
{
console.log("Toggle Event");
var index = container.getItems().indexOf(button);
if (index == 0) {
if (pressed) {
container.setPressedButtons();
var settingListContainer = this.down("#setting-list-container");
if (settingListContainer) {
this.remove(settingListContainer, true);
// close nav by touching the partial off-screen content
}
}
}a
else {
var settingListContainer = this.down("#setting-list-container");
if (!pressed&&settingListContainer) {
this.remove(settingListContainer, true);
}
else if (pressed) {
var existingList = Ext.ComponentQuery.query('settingList')[0];
if (existingList) {
this.add(existingList);
document.addEventListener('click', this.documentClickHandler, false);
}
else {
this.add({ xtype: "settingList", height: '349px', sortHandler: this.config.sortHandler, segmentControl: container });
document.addEventListener('click',this.documentClickHandler, false);
}
}
}
},
listeners: [
{
delegate: "#control-segment-button",
event: 'toggle',
fn: 'onSegmentToggled'
}
],
initialize: function () {
//Ext.require("");
var segmentedButton = Ext.create('Ext.SegmentedButton', {
layout: {
type: 'hbox',
pack: 'center',
align: 'stretchmax'
},
docked: 'bottom',
id:'control-segment-button',
allowMultiple: false,
allowDepress: true,
config: { flex: 1 },
items: [
{
iconCls: 'time',
width: '50%',
cls:'palin-segment',
style:"border-radius:0px"
},
{
iconCls: 'settings',
width: '50%',
cls: 'palin-segment',
style: "border-radius:0px"
}
]
});
this.add(segmentedButton);
}
});
event.preventDefault(); is what keeps the framework or the document from also handling this event.

Sencha Tap listener not firing

I have a test application with a couple of views. I am trying to invoke a simple 'tap' listener on my buttons. Even though the controller is instantiated and launched, the tap event does not seem to fire.
Here's my app.js
Ext.application({
name: 'MyApp',
requires: [
'Ext.MessageBox',
'Ext.form.FormPanel',
'Ext.navigation.View'
],
views: [
'Main',
'Tasks'
],
controllers: [
'Main'
],
models: [
'Task',
'Schedule'
],
stores: [
'Tasks',
'Schedules'
],
launch: function() {
// Destroy the #appLoadingIndicator element
try{
Ext.fly('appLoadingIndicator').destroy();
}catch(err){
console.warn("[CUSTOMWARN]Could not destroy loading indicator because of -- \n"+err);
}
var DEBUG=false;
if(!DEBUG){
// Initialize the main view
Ext.Viewport.add(Ext.create('MyApp.view.Main'));
}
}
});
Main.js -- controller
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
requires: [
'MyApp.view.Main'
],
init: function(){
// download and parse data from server here.
console.log('controller initiated!');
},
config: {
refs: {
loginBtn: 'button[action=login]'
},
control: {
loginBtn: {
tap: 'loginBtnHandler'
}
}
},
loginBtnHandler: function(){
this.callParent(arguments);
Ext.Msg.alert('here');
}
});
Main.js -- view
Ext.define('MyApp.view.Main', {
extend: 'Ext.navigation.View',
alias: 'customnavigationview',
requires: [
'MyApp.form.Login'
],
config: {
navigationBar: {
hidden: true
},
items: [
{
xtype: 'logincard',
flex: 1
}
],
}
});
Login.js -- for xtype: 'logincard'
Ext.define('MyApp.form.Login', {
extend: 'Ext.form.Panel',
xtype: 'logincard',
requires: [
'Ext.field.Password',
'Ext.field.Email',
'Ext.form.FieldSet',
'Ext.field.Toggle',
'Ext.Label'
],
// id: 'loginForm',
config: {
items: [
{
xtype : 'label',
html : 'Login failed. Please enter correct credentials.',
itemId : 'signInFailedLabel',
hidden : true,
hideAnimation : 'fadeOut',
showAnimation : 'fadeIn',
style : 'color:#990000;',
margin : 10
},
{
title: 'Please log in',
xtype: 'fieldset',
items:[
{
xtype: 'textfield',
name : 'username',
label: 'UserName'
},
{
xtype: 'passwordfield',
name : 'password',
label: 'Password'
}
]
},
{
xtype: 'fieldset',
items: [
{
xtype : 'togglefield',
name : 'rememberLogin',
label : 'Remember Me '
}
]
},
{
xtype : 'button',
id : 'loginSubmitBtn',
itemId : 'loginSubmitItemBtn',
text : 'Login',
ui : 'action',
action : 'login',
margin : 10
}
]
}
});
Any help would be highly appreciated!
EDIT: So I tried to use Ext.ComponentQuery.query("#loginSubmitBtn") and on printing the output on console, I can see that it is pointing to the correct button. Here's the output.
0: Class
_badgeCls: "x-badge"
_baseCls: "x-button"
_disabledCls: "x-item-disabled"
_floatingCls: "x-floating"
_hasBadgeCls: "x-hasbadge"
_hiddenCls: "x-item-hidden"
_icon: false
_iconAlign: "left"
_itemId: "loginSubmitItemBtn"
_labelCls: "x-button-label"
_margin: 10
_pressedCls: "x-button-pressing"
_pressedDelay: 0
_styleHtmlCls: "x-html"
_text: "Login"
_ui: "action"
action: "login"
badgeElement: Class
bodyElement: Class
config: objectClass
currentUi: "x-button-action"
element: Class
eventDispatcher: Class
getEventDispatcher: function () {
getId: function () {
getObservableId: function () {
getUniqueId: function () {
iconElement: Class
id: "loginSubmitBtn"
initConfig: function (){}
initialConfig: Object
initialized: true
innerElement: Class
managedListeners: Object
observableId: "#loginSubmitBtn"
onInitializedListeners: Array[0]
parent: Class
referenceList: Array[4]
refreshFloating: function () {
refreshSizeState: function () {
renderElement: Class
rendered: true
textElement: Class
usedSelectors: Array[1]
__proto__: Object
length: 1
**EDIT 3: ** Found it! See answer here: Sencha Tap listener not firing
The listener for a button tap should be just 'tap' instead of 'itemtap'
tap: 'loginBtnHandler'
Hope it helps-
I think I've had this problem in the past. Try qualifying the ref in the controller with the view name to narrow the query down:
loginBtn: 'logincard button[action=login]'
Not the best, but should work:
First remove the tap listener on the controller. Also remove the 'action' property on the button, and set the handler on the button:
{
xtype : 'button',
id : 'loginSubmitBtn',
itemId : 'loginSubmitItemBtn',
text : 'Login',
ui : 'action',
//action : 'login',
margin : 10,
handler : function () {
MyApp.app.getController('Main').loginBtnHandler()
}
}
Ok, this is weird, but I found out why my buttonclick was not being handled properly. I usually use Google Chrome as my testing browser with web inspector on. I downloaded Safari and tried the same code and it worked like its supposed to. I looked at both the browsers, and the only difference was that Chrome had web inspector on, while Safari didn't. I closed the web inspector in Chrome and the button handler worked great (without reloading). I restarted the browser, pushed the inspector to a separate window, none of them worked. However, Safari works great even with inspector on. Probably a Chrome bug?
Google Chrome version: 27.0.1453.110
*EDIT: * I had the touch emulation turned on in the web inspector. With this turned on, we have to close the web inspector for the touch event to register. Otherwise, we have to turn off the touch emulation to register for the events while the web inspector is open.
TL;DR: Close your web inspector in Chrome before testing, if you have touch emulation turned on.

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

Sencha Touch 2 Ext.List - programmatically add detail view

I’m trying to add different detail view based on taped item in list.
I have home screen that is using List component and this view is displaying ['Real estate', 'Vehicles', 'Jobs']... as menu items.
Based on selected item in list, I want to display different view.
And I want to follow MVC design pattern..
Here is some code...
App.js
Ext.application({
name: 'App',
controllers: ['Main'],
views: ['Viewport', 'HomePage'],
stores: ['HomePageItems'],
models: ['HomePageItem'],
launch: function () {
Ext.Viewport.add(Ext.create('App.view.Viewport'));
}
});
Viewport.js
Ext.define("App.view.Viewport", {
extend: 'Ext.navigation.View',
requires: [ 'App.view.realestate.Realestate',
'App.view.HomePage',
'App.view.jobs.Jobs',
'App.view.other.Other',
'App.view.vehicles.Vehicles'
],
config: {
items: [
{
xtype: 'homepage'
}
]
}
});
HomePage.js ( xtype = "homepage" )
Ext.define('App.view.HomePage', {
extend: 'Ext.List',
xtype: 'homepage',
id: 'homepage',
config: {
title: 'Oglasi',
itemTpl: '<strong>{name}</strong><p style="color:gray; font-size:8pt">{description}</p>',
store: 'HomePageItems',
onItemDisclosure: true
}
});
Main.js
Ext.define('App.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
main: '#homepage'
},
control: {
'homepage': {
disclose: 'HookUpDetailView'
}
}
},
HookUpDetailView: function (element, record, target, index, ev) {
// TO DO: I have 4 differente views to load programmaticaly based on selected item in List
//'App.view.realestate.Realestate'
//'App.view.jobs.Jobs'
//'App.view.other.Other'
//'App.view.vehicles.Vehicles'
}
});
I found one example, but it's not working for me (push method doesn't exist)
this.getMain().push({
xtype: 'realestatehome'
});
Thank in advance!
The method you're looking for is
http://docs.sencha.com/touch/2-0/#!/api/Ext.Container-method-add
this.getMain().add({xtype: 'realestatehome'});
But what you have doesnt make sense, realestatehome is a list, you can't add a component under it. You need to read about layoutsFrom the link above
Push should work. You could try something like this.
HookUpDetailView: function (list, record) {
if(record.data.description==='real estate'){
this.getRealEstate().push({
xtype: 'realestatehome',
title: record.data.description,
data. record.data
});
if(record.data.description==='Vehicles'){
this.getVehicles().push({
xtype: 'vehicles',
title: record.data.description,
data. record.data
});
}
}
And a particular view could look like
Ext.define('App.view.RealEstateHome', {
extend: 'Ext.Panel',
xtype: 'realestatehome',
config: {
styleHtmlContent: true,
scrollable: 'vertical',
tpl: [
'{description}, {example}, {example}, {example}'
]
}
});
And the refs to access your particular view should look something like
refs: {
realEstate: 'realestatehome',
vehicles: 'vehicleshome'
},
Hope that helps
I made a mistake in controller this.getMain()
get main is returning Ext.List and I need Ext.navigation.View that have 'push' method.
So... I added xtype and id to my viewport ("container")
and quick change in my controller solved my troubles...
refs: {
main: '#homepage',
container: '#container'
}
and instead of getting Ext.List object
this.getContainer().push({
xtype: 'realestatehome'
});
And this work like a charm :)

SenchaTouch2 - Listening to store load event, set tab panel item "badgeText"

I'am trying to build my first little Sencha Touch 2 app. I've created some stuff that is working as expected and now I could like to create some event handling stuff.
I've created the following store:
Ext.define('Mobile.store.Blogs', {
extend: 'Ext.data.Store',
config: {
},
listeners: {
'load' : function(store,records,options) {
store.loaded = true;
console.log("fired blogCountAvailable");
store.fireEvent("blogCountAvailable");
},
'blogCountAvailable': function(store, records, options) {
console.log("blogCountAvailable has been fired");
}
}
});
This stuff works as expected, but now comes the next step.
Here is the code of my tab panel bar:
Ext.create("Ext.tab.Panel", {
xtype:'mainTabPanelBottom',
tabBarPosition: 'bottom',
fullscreen: true,
items: [
{
title: 'Blog',
iconCls: 'home',
xtype:'mainpanel'
},
{
title: 'Users',
iconCls: 'user',
xtype:'userpanel'
}
],
listeners: {
blogCountAvailable: function(tabpanel, newTab) {
var tab = newTab.tab,
badge = 10;
tab.setBadge(badge);
console.log("blogCountAvailable has been fired");
}
}
});
My question now is how I could achieve it to "fire" my custom event blogCountAvailable to the tab panel?
The easiest way is just set an id for your TabPanel and then:
Ext.getCmp('your_TabPanel_id').fireEvent("blogCountAvailable");

Categories