Sencha Touch 2 dynamic button on Navigation View - javascript

I'm trying to initialize() and destroy() dynamically a button on Navigation View's bar from another view. Button is created fine, but I can't remove it... Tried also hide(), but it's being called twice and isn't helpful. So I'm officially stuck, please help! :-)
My Controller:
Ext.define('MyApp.controller.Application', {
extend: 'Ext.app.Controller',
config: {
refs: {
buttonNew1: '#btn-new1',
buttonNew2: '#btn-new2',
buttonNew3: '#btn-new3',
buttonNew4: '#btn-new4',
buttonDataNew: '#btn-data-new'
},
control: {
buttonNew1: { tap: 'onNewButtonTap' },
buttonNew2: { tap: 'onNewButtonTap' },
buttonNew3: { tap: 'onNewButtonTap' },
buttonNew4: { tap: 'onNewButtonTap' },
buttonDataNew: { tap: 'onDataNewButtonTap' },
}
},
onNewButtonTap: function(button) {
console.log(button);
},
onDataNewButtonTap: function(button) {
console.log(button);
}
});
My Navigation View:
Ext.define('MyApp.view.Main', {
extend: 'Ext.navigation.View',
xtype: 'view-main',
config: {
autoDestroy: false,
items: [
{
xtype: 'container',
layout : { type: 'vbox', pack: 'top', align: 'middle' },
items: [
{
xtype: 'container',
layout: 'hbox',
items: [
{
xtype: 'button',
id: 'btn-new1',
text: 'New1'
},
{
xtype: 'button',
id: 'btn-new2',
text: 'New2'
}
]
},
{
xtype: 'container',
layout: 'hbox',
items: [
{
xtype: 'button',
id: 'btn-new3',
text: 'New3'
},
{
xtype: 'button',
id: 'btn-new4',
text: 'New4'
}
]
}
]
}
]
}
});
My Data View:
Ext.define("MyApp.view.Data", {
extend: 'Ext.dataview.DataView',
xtype: 'view-data',
config: {
useComponents: true,
layout: { type: 'fit', align: 'center' },
defaultType: 'view-data-item',
store: 'MyStore'
},
initialize: function() {
this.callParent();
Ext.Viewport.getActiveItem().getNavigationBar().add(Ext.create('Ext.Button', {
id: 'btn-data-new',
ui: 'normal',
iconCls: 'add1',
align: 'right',
iconMask: true,
hideAnimation: Ext.os.is.Android
? false : { type: 'fadeOut', duration: 200 },
showAnimation: Ext.os.is.Android
? false : { type: 'fadeIn', duration: 200 }
}));
},
destroy: function() {
this.callParent();
var button = Ext.getCmp('btn-data-new');
if (button) {
Ext.Viewport.getActiveItem().getNavigationBar().remove(button);
}
}
});

Well, I figured it out finally... The problem was with autoDestroy: false in the Navigation View!

Related

ExtJs keys form.Panel

keys config working on Ext.window.Window but it dose not effect on Ext.form.Panel.
i have tried many method,but still did not work. How can i resolve this?
Ext.define('Settings.view.security.service.List', {
extend: 'Ext.form.Panel',
xtype: 'service',
requires: [
'Settings.controller.Service',
],
viewModel: { type: 'service' },
title: l.cp.service.self,
controller: 'service',
trackResetOnLoad:true,
frame: false,
padding: YsCfg.listPadding,
fieldDefaults: {
labelWidth: 180,
labelAlign: 'left',
maxLength: 63,
msgTarget: 'side',
},
//fieldDefaults: YsCfg.fieldDefaults,
border: false,
scrollable: true,
items:[{
...
}],
bbar: {
itemId: 'bbar',
defaults: {minWidth: YsCfg.btnMinWidth},
items: ['->', {
text: l.cp.common.save,
ui: 'ys-theme',
handler: 'handlerSave'
}, {
text: l.cp.common.cancel,
ui: 'ys-theme',
handler: 'handlerCancel'
}, '->']
},
keys: {
key: Ext.event.Event.ENTER,
fn: function(obj){
var controller = Ext.getCmp('control-panel').down('service').getController();
if(controller){
controller.handlerSave();
}
},
scope: this
},
listeners: {
show: 'showOpt',
boxready: 'readyOpt',
},
});

ExtJS 5: disable form fields in hidden card

I have a form panel with a radiogroup, and depending on the radiogroup selection, it will show some other components. If a radiofield is not selected, then its items will be hidden, as they're not part of the active card.
Now, if I have allowblank: false set on a field (and it's empty) within the hidden card, my form is still considered invalid. Being hidden means the user would not like to use it, so it should not be considered as part of the form. Here's an example.
In the example, I have 2 forms... the top form is the one that I'm curious about... is there a way to get this working without having to bind to disabled? I tried looking at hideMode, but that wasn't what I was looking for.
Ideally, I wouldn't have to create a formula for each card that I add... that seems silly. I realize I could create a generic formula, but once again, that just seems extraneous. Another option could be ditching the card layout, and binding each card to hidden and disabled, but I'm creating more formulas. Is there some sort of property I'm missing?
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('MyController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myview',
onValidityChange: function(form, isValid, eOpts) {
this.getViewModel().set('isFormValid', isValid);
}
});
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myview',
data: {
activeItem: {
myInput: 0
}
},
formulas: {
activeCardLayout: function(getter) {
var myInput = getter('activeItem.myInput');
console.log(myInput);
return parseInt(myInput);
}
}
});
Ext.define('MyForm', {
extend: 'Ext.form.Panel',
title: 'My Form',
controller: 'myview',
viewModel: {
type: 'myview'
},
layout: {
type: 'hbox'
},
listeners: {
validitychange: 'onValidityChange'
},
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
layout: {
type: 'hbox'
},
items: [{
xtype: 'button',
text: 'Save',
reference: 'saveButton',
disabled: true,
bind: {
disabled: '{!isFormValid}'
}
}]
}],
items: [{
xtype: 'radiogroup',
vertical: true,
columns: 1,
bind: {
value: '{activeItem}'
},
defaults: {
name: 'myInput'
},
items: [{
boxLabel: 'None',
inputValue: '0'
}, {
boxLabel: 'Something',
inputValue: '1'
}]
}, {
xtype: 'container',
layout: 'card',
flex: 1,
bind: {
activeItem: '{activeCardLayout}'
},
items: [{
xtype: 'container',
layout: 'fit'
}, {
xtype: 'container',
layout: 'fit',
items: [{
xtype: 'textfield',
fieldLabel: 'hello',
allowBlank: false
}]
}]
}]
});
Ext.define('MyViewModel2', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myview2',
data: {
activeItem: {
myInput: 0
}
},
formulas: {
disableSomethingCard: function(getter) {
return getter('activeItem.myInput') !== '1';
},
activeCardLayout: function(getter) {
var myInput = getter('activeItem.myInput');
console.log(myInput, 'here');
return parseInt(myInput);
}
}
});
Ext.define('MyForm2', {
extend: 'MyForm',
title: 'My Form 2 (works)',
viewModel: {
type: 'myview2'
},
items: [{
xtype: 'radiogroup',
vertical: true,
columns: 1,
bind: {
value: '{activeItem}'
},
defaults: {
name: 'myInput'
},
items: [{
boxLabel: 'None',
inputValue: '0'
}, {
boxLabel: 'Something',
inputValue: '1'
}]
}, {
xtype: 'container',
layout: 'card',
flex: 1,
bind: {
activeItem: '{activeCardLayout}'
},
items: [{
xtype: 'container',
layout: 'fit'
}, {
xtype: 'container',
layout: 'fit',
bind: {
disabled: '{disableSomethingCard}'
},
items: [{
xtype: 'textfield',
fieldLabel: 'hello',
allowBlank: false
}]
}]
}]
});
Ext.create('MyForm', {
renderTo: Ext.getBody()
});
Ext.create('MyForm2', {
renderTo: Ext.getBody()
});
}
});

Losing scope in combobox ExtJS 4.2

I have a popup window with a combobox and a few buttons. The idea is to make a selection in the combobox and then either save the selection to a store or cancel. I have done this before and never had any problems, but with this code I get Uncaught TypeError: Cannot call method 'apply' of undefined whenever I try to interact with the combo. It seems to me like ExtJS is trying to run code meant for the store on the combobox.
I load the popup window with Ext.create('Account.Window.Reuse');
The definitions:
Ext.define('SimpleAccount', {
extend: 'Ext.data.Model',
idProperty: 'AccountID',
fields: [ {
name: 'AccountID',
type: 'int',
useNull: true
}, 'Name']
});
var userAccountReuseStore = Ext.create('Ext.data.Store', {
model: 'SimpleAccount',
storeId: 'userAccountReuseStore',
data: [{"AccountID":"1", "Name":"FirstAccount"},
{"AccountID":"2", "Name":"SecondAccount"},
{"AccountID":"3", "Name":"ThirdAccount"}]
});
Ext.define('Account.Reuse.ComboBox', {
extend: 'Ext.form.ComboBox',
alias: 'widget.accountReuseComboBox',
initComponent: function(){
Ext.apply(this, {
fieldLabel: 'Account',
displayField: 'Name',
valueField: 'AccountID',
queryMode: 'local'
})
}
});
Ext.define('Account.Reuse.Fieldset', {
extend: 'Ext.form.FieldSet',
alias: 'widget.accountReuseFieldset',
initComponent: function(){
Ext.apply(this, {
items: [
{
xtype: 'label',
cls: 'text-important',
margin: '0 0 10 0',
style: 'display: block',
text: 'Only attach an account you have permission to use. After attaching the account you will not be able to use, remove, or edit it until approved by SCSAM'
},
{
xtype: 'accountReuseComboBox',
store: userAccountReuseStore
}
]
});
this.callParent();
}
});
Ext.define('Account.Reuse.Details', {
extend: 'Ext.form.Panel',
alias: 'widget.accountReuseDetails',
initComponent: function(){
Ext.apply(this, {
plain: true,
border: 0,
bodyPadding: 5,
fieldDefaults: {
labelWidth: 55,
anchor: '100%'
},
layout: {
type: 'vbox',
align: 'stretch',
flex: 1
},
items: [
{
xtype: 'accountReuseFieldset',
defaults: {
labelWidth: 89,
anchor: '100%',
layout: {
type: 'vbox',
defaultMargins: {top: 0, right: 5, bottom: 0, left: 0},
align: 'stretch'
}
},
title: 'Details',
collapsible: false
}]
});
this.callParent();
}
});
Ext.define('Account.Window.Reuse', {
extend: 'Ext.window.Window',
alias: 'widget.accountWindowReuse',
initComponent: function(){
Ext.apply(this, {
title: 'Account Details',
width: 400,
autoShow: true,
modal: true,
layout: {
type: 'fit',
align: 'stretch' // Child items are stretched to full width
},
items: [{
xtype: 'accountReuseDetails',
id: 'attachAccountReuseForm'
}],
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
ui: 'footer',
layout: {
pack: 'center'
},
items: [{
minWidth: 80,
text: 'Attach',
id: 'saveButton',
handler: function(){
var rec = this.up('accountWindowReuse').down('accountReuseDetails').getValues();
var store = Ext.getStore('userAccountReuseAttachStore');
store.add(rec);
this.up('window').close();
}
},{
minWidth: 80,
text: 'Cancel',
handler: function(){
this.up('window').close();
}
}]
}]
});
this.callParent();
}
});
It looks like you forget call parent in your Account.Reuse.ComboBox initComponent function so combobox is not initialized properly.
Your Account.Reuse.ComboBox initComponent function should look like this:
initComponent: function(){
Ext.apply(this, {
fieldLabel: 'Account',
displayField: 'Name',
valueField: 'AccountID',
queryMode: 'local'
});
this.callParent();
}

Adding views to the navigation view - BEGINNER

I have added a navigation view (called MainView), and a button. When i click on the button, the next view gets displayed (In the following example its called DASHBOARD). In the dashboard there's another button when i click on that another view should display. The name of that view is MOREDETAILS.
But, when i click on the button in the DASHBOARD view, MOREDETAILS view doesn't get added to the navigation view or even get displayed.
How can i resolve this ???
My Code :
MAINVIEW
Ext.define('MyApp.view.MainView', {
extend: 'Ext.navigation.View',
config: {
fullscreen: true,
id: 'MainView',
ui: 'light',
modal: true,
useTitleForBackButtonText: true,
items: [
{
xtype: 'formpanel',
title: 'TEST',
layout: {
type: 'card'
},
items: [
{
xtype: 'button',
docked: 'bottom',
itemId: 'mybutton9',
ui: 'confirm',
iconAlign: 'right',
text: 'Click'
}
]
}
],
listeners: [
{
fn: 'onMybutton9Tap',
event: 'tap',
delegate: '#mybutton9'
}
]
},
onMybutton9Tap: function(button, e, eOpts) {
this.push(Ext.create('MyApp.view.Dashboard',{
title:'Dashboard'
}));
}
});
DASHBOARD
Ext.define('MyApp.view.Dashboard', {
extend: 'Ext.form.Panel',
config: {
id: 'DashboardID',
layout: {
animation: 'slide',
type: 'card'
},
modal: true,
scrollable: 'vertical',
items: [
{
xtype: 'list',
id: 'ListItem',
scrollable: true,
itemTpl: [
'<div> blah blah</div>'
],
store: 'MyJsonPStore',
items: [
{
xtype: 'button',
docked: 'top',
itemId: 'mybutton10',
text: 'MyButton10'
}
]
}
],
listeners: [
{
fn: 'onMybutton10Tap',
event: 'tap',
delegate: '#mybutton10'
}
]
},
onMybutton10Tap: function(button, e, eOpts) {
this.push(Ext.create('MyApp.view.MoreDetails',{
title:'Neeeeee'
}));
}
});
MOREDETAILS
Ext.define('MyApp.view.MoreDetails', {
extend: 'Ext.Panel',
config: {
id: 'MoreInfo',
layout: {
animation: 'slide',
type: 'card'
},
scrollable: 'vertical',
items: [
{
xtype: 'list',
itemTpl: [
'<div>jhhhjhjhjhjhjh</div>'
],
store: 'MyJsonPStore'
}
]
}
});
In onMybutton10Tap, you are calling push on this, which is a formpanel, not a navigationview. You need to get a reference to the parent before calling push.
First, give your first class an alias, which allows you to create it using xtype:
Ext.define('MyApp.view.MainView', {
extend: 'Ext.navigation.View',
alias: 'widget.mainview'
//...more here
});
Then use up to get a reference to the parent using that xtype:
onMybutton10Tap: function(button, e, eOpts) {
this.up('mainview').push(Ext.create('MyApp.view.MoreDetails',{
title:'Neeeeee'
}));
}

ExtJs 4 MVC Nested Layouts

I'm trying to implement a simple framework for an app. The idea is to create a background viewport type 'layout' with a north region containing the page header and an interchangeable center region.
When my app starts, a Login form is shown. If the user/password is ok, the form is destroyed and the main layout should appear. The main layout should insert a nested layout in its center region.
This is my background layout code:
Ext.define('DEMO.view.BackgroundLayout', {
extend: 'Ext.container.Viewport',
alias: 'widget.background',
requires: [
'DEMO.view.Main'
],
layout: {
type: 'border'
},
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
region: 'north',
html: '<h1 class="x-panel-header">Page Title</h1>'
},
{
xtype: 'mainview',
region: 'center',
forceFit: false,
height: 400
}
]
});
me.callParent(arguments);
}
});
The main layout is this:
Ext.define('DEMO.view.Main', {
extend: 'Ext.container.Viewport',
alias: 'widget.mainview',
requires: [
'DEMO.view.MyGridPanel'
],
layout: {
type: 'border'
},
initComponent: function() {
var me = this;
console.log('bb');
Ext.applyIf(me, {
items: [
{
xtype: 'mygridpanel',
region: 'center',
forceFit: false
},
{
xtype: 'container',
height: 38,
forceFit: false,
region: 'north',
items: [
{
xtype: 'button',
height: 34,
id: 'btnLogout',
action: 'logout',
text: 'Logout'
}
]
}
]
});
me.callParent(arguments);
}
});
As you can see, the center region needs an xtype named "mygridpanel". This is the code for it:
Ext.define('DEMO.view.ui.MyGridPanel', {
extend: 'Ext.grid.Panel',
border: '',
height: 106,
title: 'My Grid Panel',
store: 'MyJsonStore',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
viewConfig: {
},
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'Id',
text: 'Id'
},
{
xtype: 'gridcolumn',
dataIndex: 'Name',
text: 'Name'
},
{
xtype: 'gridcolumn',
dataIndex: 'Sales',
text: 'Sales'
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'top',
items: [
{
xtype: 'button',
disabled: true,
id: 'btnDelete',
allowDepress: false,
text: 'Delete'
},
{
xtype: 'button',
disabled: true,
id: 'btnEdit',
allowDepress: false,
text: 'Edit'
}
]
}
]
});
me.callParent(arguments);
}
});
My problem is that when I call Ext.create('DEMO.view.BackgroundLayout', {}); it only shows the nested layout, and the background layout is hidden, also I get this error in Chrome's console:
Uncaught Error: HIERARCHY_REQUEST_ERR: DOM Exception 3
What I'm doing wrong?.
Thanks in advance,
Leonardo.

Categories