I have a TabPanel like this:
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.TabPanel', {
items: [
{
title: "",
reference: 'tabpanel',
itemId: 'tab1',
items: [{
itemId: 'firstTab',
xclass: 'viewClass'
}],
}, {
title: "",
reference: 'tab2',
layout: 'fit',
items: [{
xclass: "view",
}]
}
]
in the xclass component there is the path of a class where is defined the view. In the view should be a button, after tap on it, the view should refresh and show another class, for example the view should be defined by 'viewClass2' and not anymore by 'viewClass' I'm imaging a function triggered on button tap like this:
Ext.getCmp('tab1').remove('firstTab');
Ext.getCmp('tab1').add({
itemId: 'firstTab',
xclass: 'viewClass2'
})
BUT I must use itemId and not id so I cannot use "Ext.getCmp" and i should use Ext.Component.query but I don't know how to manage remove and add operations
You have to get reference of the component first, then remove it.
Ext.create('Ext.TabPanel', {
id: 'myTabPanel',
items: [
{
title: "",
reference: 'tabpanel',
itemId: 'tab1',
items: [{
itemId: 'firstTab',
xclass: 'viewClass'
}],
}, {
title: "",
reference: 'tab2',
layout: 'fit',
items: [{
xclass: "view",
}]
}
];
var tabPanel = Ext.getCmp('myTabPanel');
var tab = tabPanel.getComponent("tab1");
// remove by id
tab.remove(tab.down("[itemId='firstTab']").id);
// remove by reference
tab.remove(tab.down("[itemId='firstTab']"));
Related
Well considering a grid I create in my application:
{
xtype: 'ordergrid',
itemId: 'ordergrid',
titleBar: {
shadow: false,
items: [{
align: 'right',
xtype: 'button',
text: 'Update status',
stretchMenu: true,
menu: {
itemId: 'status_menu',
defaults: {
handler: 'updateStatus'
},
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
}
}]
},
With ordergrid being defined with:
extend: 'Ext.grid.Grid',
xtype: 'ordergrid',
I wish to modify the items of the menu dynamically. I've first tried doing this through a store:
menu: {
itemId: 'status_menu',
defaults: {
handler: 'updateStatus'
},
indented: false,
store: { type: 'status' }
Though this doesn't seem to work. Then I tried accessing this menu through a component query, during the init function of some controller:
Ext.define('BinkPortalFrontend.view.main.OrderController', {
extend: 'Ext.app.ViewController',
alias: 'controller.order',
init: function () {
console.log('..... initializing ......');
const menus = Ext.ComponentQuery.query('ordergrid #status_menu');
const menu = menus[0];
menu.setItems([{
text: 'some',
value: 'some'
}, {
text: 'new',
value: 'mew'
}]);
},
};
However this returns an error: "Cannot read property 'setItems' of undefined"
Debugging shows the obvious problem: it doesn't find any menu.
What's more, even a "catch all" query like
Ext.ComponentQuery.query('menu');
or
Ext.ComponentQuery.query('#status_menu');
Shows an empty array: so what's going on? (I most definitely see the menu from its initial load).
There is one reason your menu is not created. Menu will created whenever button will tap or whenever getMenu() method get called.
If you want to get your menu using Ext.ComponentQuery.query(), so for this you need to do use initialize event of button and forcefully create menu using getMenu() method like below :-
{
xtype: 'button',
text: 'Update status',
stretchMenu: true,
menu: {
itemId: 'status_menu',
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
},
listeners: {
initialize: function(btn) {
Ext.defer(function() {
// This will print undefined because menu have not created
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
//When we use getMenu method it will create menu item
btn.getMenu().hide();
// This will print menu component
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
}, 10)
}
}
}
Another way you can use getMenu() method of button. It will return the menu component.
In this FIDDLE, I have created a demo using grid, button and menu. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
var store = Ext.create('Ext.data.Store', {
fields: ['name', 'email', 'phone'],
data: [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "home#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "555-222-1254"
}]
});
Ext.create('Ext.grid.Grid', {
title: 'Change menu items dynamically',
titleBar: {
shadow: false,
items: [{
align: 'right',
xtype: 'button',
text: 'Update status',
stretchMenu: true,
itemId: 'statusbtn',
menu: {
itemId: 'status_menu',
defaults: {
// handler: 'updateStatus'
},
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
},
listeners: {
initialize: function (btn) {
Ext.defer(function () {
// This will undefined because menu has not been created
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
//When we use getMenu method it will create menu item
btn.getMenu().hide();
// This will menu component
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
}, 10)
}
}
}, {
xtype: 'button',
align: 'right',
text: 'Change Items',
handler: function (btn) {
var newItems = [];
store.each(rec => {
newItems.push({
text: rec.get('name'),
value: rec.get('name')
})
});
/*
* You can also get menu using button
* btn.up('titlebar').down('#statusbtn').getMenu().setItems(newItems);
*/
Ext.ComponentQuery.query('#status_menu')[0].setItems(newItems);
Ext.toast('Menu items has been change. Please check', 2000);
}
}]
},
store: store,
columns: [{
text: 'Name',
dataIndex: 'name',
width: 200
}, {
text: 'Email',
dataIndex: 'email',
width: 250
}, {
text: 'Phone',
dataIndex: 'phone',
width: 120
}],
height: 200,
layout: 'fit',
fullscreen: true
});
}
});
For more details about component you can also see this ComponentManager
I try to use jquery together with extjs. I want when I click on an image to get the id of the image and store it in a variable. I use jquery for this part. The image lives in an extjs panel. I use with no result and afterrender listener Here is my code:
items: [{
xtype: 'tabpanel',
width: 600,
activeTab: 0,
flex: 2,
layout: {type: 'fit'},
items: [{
xtype: 'panel',
title: 'Images',
items: [{contentEl:'img',autoScroll:true,height:500 }],
listeners: {afterrender: function(c){c.el.on('click', function()
{
$('img').on( 'click',function() { // event delegation
var idImg = $(this).attr('id');
alert(idImg);
addMarker(idImg)
var alt = $(this).attr('alt'); // get the value of alt
$('#curInterId').val(alt); // place the internal id in the text box
});
});}},
},{
xtype: 'panel',
title: 'Material',
items: [{contentEl:'msg',autoScroll:true,height:500 }]
}]
}],renderTo : Ext.getBody()
},
Try something like this:
Fiddle Link
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.create("Ext.panel.Panel", {
layout: "fit",
renderTo: Ext.getBody(),
items: [{
xtype: 'panel',
title: 'Images',
items: [{
xtype: 'image',
height: 200,
width: 600,
src: 'http://www.newbridgegreen.com/assets/bootstrap/img/sencha_logo.png',
listeners: {
el: {
click: function() {
Ext.Msg.alert("Message");
}
}
}
}]
}]
});
}
});
The key here is the el: within listeners, you can add standard DOM click handlers to any element using this method.
My question s in relation to the possible answer in this post Sencha Touch 2 - How to get form values?
Im having the same issue trying to retrieve the values from a form in a View using a Controller.
My current error is Uncaught TypeError: Object # has no method 'getValues'
View:
Ext.define("App.view.Login", {
extend: 'Ext.form.Panel',
requires: [
'Ext.field.Password'
],
id: 'loginview',
config: {
items: [{
xtype: 'titlebar',
title: 'Login',
docked: 'top'
},
{
xtype: 'fieldset',
id: 'loginForm',
defaults: {
required: true
},
items: [{
items: [{
xtype: 'textfield',
name: 'username',
label: 'Username:'
},
{
xtype: 'passwordfield',
name: 'password',
label: 'Password:'
}]
}]
},
{
xtype: 'toolbar',
layout: {
pack: 'center'
}, // layout
ui: 'plain',
items: [{
xtype: 'button',
text: 'Register',
id: 'register',
ui: 'action',
}, {
xtype: 'button',
text: 'Login',
id: 'login',
ui: 'confirm',
}] // items (toolbar)
}]
}
});
Controller:
Ext.define('App.controller.Login', {
extend: 'Ext.app.Controller',
requires: [
'App.view.Login',
'Ext.MessageBox'
],
config: {
refs: {
loginForm: '#loginForm',
register: '#register',
login: '#login'
},
control: {
register: {
tap: 'loadRegisterView'
},
login: {
tap: 'loginUser'
}
},
history: null
},
loadRegisterView: function(btn, evt) {
/*var firststep = Ext.create('App.view.Register');
Ext.Viewport.setActiveItem(firststep);*/
},
loginUser: function(btn, evt) {
var values = loginForm.getValues();
console.log(values);
}
});
Thanks
Edit:
So the below code works but its not how i see everyone doing it.
var form = Ext.getCmp('loginview');
console.log(form.getValues());
Everyone else does this.getLoginView().getValues(); . I dont understand "this" is in the wrong scope and where would getLoginView even be declared? No one ever includes this information in their snippets. Here is another example Sencha Touch 2 - How to get form values?
Add xtype in view below the "id":
xtype: 'loginform',
and then replace the reference of loginForm with this:
loginForm: 'loginform',
Your code will work. The mistake you were doing is you were trying to access the method of 'formpanel' in 'fieldset'.
I'm quite new to using Sencha Touch. I'm creating an app that has a sidebar and a map pane and when the user clicks on the Show Map button in the sidebar area the map is supposed to center on that location. Where I'm having an issue is that I'm unsure of how to access the {lat} and {lon} properties that are in the tpl variable from the handler function. My apologies if this is a trivial question, but it has me stumped.
Ext.define('Admin.view.Details',
{
extend: 'Ext.Panel',
xtype: 'details',
config:
{
styleHtmlContent: true,
scrollable: 'vertical',
title: 'Individual',
tpl:
[
'Account Number: {comid}',
'<br />',
'Address: ',
'{address} <br />',
'{lat},{lon}',
],
items:
[
{
title: 'Utilities',
items:
[
{
xtype: 'selectfield',
label: 'Utility Type',
options:
[
{text: 'Electricity', value: 'U1'},
{text: 'Water', value: 'U2'},
{text: 'Gas', value: 'u3' },
],
id: 'utilityType',
},
{
xtype: 'selectfield',
label: 'Coverage Area',
options:
[
{text: 'Subdivision', value: 'a1'},
{text: 'Zipcode', value: 'a2'},
{text: 'County', value: 'a3' },
],
id: 'areaType',
},
{
xtype: 'button',
text: 'Show Map',
ui: 'round',
padding:3,
margin:10,
id: 'mapsBTN',
handler: function() {
olMap.setCenter(new OpenLayers.LonLat(lon, lat).transform
(
new OpenLayers.Projection("EPSG:4326"),
olMap.getProjectionObject()
), 16);
}
},
]
},
]
}
});
You need to either implement de handler in your view's controller by adding references to your view and your button and then add a listener for the itemtap event of the button OR implement it in the constructor method of the view :
Ext.define('Admin.view.Details',{
extend: 'Ext.Panel',
xtype: 'details',
config:{
...
},
constructor: function() {
this.callParent(arguments);
var me = this;
this.child('#mapsBTN').setHandler(function() {
me.getTpl(); // Here's your tpl config object
});
}
});
Hope this helped
You can get any variable inside config object by getter.
this.getTpl(); //returns tpl variable
Also note that this must point out to your Admin.view.Details view.
I'm trying to learn how to use Sencha Touch to build web apps. I've been following the tutorial Here and I am a bit stuck. Below have created one controller, two views and a model (All other code is copy & paste from the tutorial). The first view, Index works great. However if I try to access the second, it brings up a blank page, none of the toolbar buttons work and it doesn't fire the alert.
If I do comment out the line this.application.viewport.setActiveItem(this.editGyms);, the alert will fire, but obviously, it doesn't render the page.
I've looked at a couple other tutorials, and they seem to also be using the setActiveItem member to switch views.. Am I missing something, or do I have to somehow deactivate the first view to activate the second or something?
HomeController.js
Ext.regController('Home', {
//Index
index: function()
{
if ( ! this.indexView)
{
this.indexView = this.render({
xtype: 'HomeIndex',
});
}
this.application.viewport.setActiveItem(this.indexView);
},
editGyms: function()
{
if ( ! this.editGyms)
{
this.editGyms = this.render({
xtype: 'EditGymStore',
});
}
this.application.viewport.setActiveItem(this.editGyms);
Ext.Msg.alert('Test', "Edit's index action was called!");
},
});
views/home/HomeIndexView.js
App.views.wodList = new Ext.List({
id: 'WODList',
store: 'WODStore',
disableSelection: true,
fullscreen: true,
itemTpl: '<div class="list-item-title"><b>{title}</b></div>' + '<div class="list-item-narrative">{wod}</div>'
});
App.views.HomeIndex = Ext.extend(Ext.Panel, {
items: [App.views.wodList]
});
Ext.reg('HomeIndex', App.views.HomeIndex);
views/home/EditGymStore.js
App.views.EditGymStore = Ext.extend(Ext.Panel, {
html: 'Edit Gyms Displayed Here',
});
Ext.reg('EditGymStore', App.views.EditGymStore);
models/appModel.js
Ext.regModel('WOD', {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
{ name: 'date', type: 'date', dateFormat: 'c' },
{ name: 'title', type: 'string' },
{ name: 'wod', type: 'string' },
{ name: 'url', type: 'string' }
],
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'title' }
]
});
Ext.regStore('WODStore', {
model: 'WOD',
sorters: [{
property: 'id',
direction: 'DESC'
}],
proxy: {
type: 'localstorage',
id: 'wod-app-localstore'
},
// REMOVE AFTER TESTING!!
data: [
{ id: 1, date: new Date(), title: '110806 - Title1', wod: '<br/><br/>Desc1</br><br/>' },
{ id: 1, date: new Date(), title: '110806 - Title1', wod: '<br/><br/>Desc2</br><br/>' }
]
});
viewport.js with toolbar
App.views.viewport = Ext.extend(Ext.Panel, {
fullscreen: true,
layout: 'card',
cardSwitchAnimation: 'slide',
scroll: 'vertical',
styleHtmlContent: true,
style: 'background: #d8e2ef',
dockedItems: [
{
xtype: 'toolbar',
title: 'The Daily WOD',
buttonAlign: 'right',
items: [
{
id: 'loginButton',
text: 'Login',
ui: 'action',
handler: function() {
Ext.Msg.alert('Login', "This will allow you to Login!");
}
},
{
xtype: 'spacer'
},
{
xtype: 'button',
iconMask: true,
iconCls: 'refresh',
ui: 'action',
handler: function() {
Ext.Msg.alert('Refresh', "Refresh!");
}
}]
},
],
});
Thanks for the help!!
In HomeController.js your action function (editGyms) is the same name as the variable you're using for your view (this.editGyms) so when it tries to setActiveItem(this.editGyms) its actually passing the controllers action function rather than the results of this.render({...})
Either change the name of the controller action or change the name of the variable you use to hold the view.. like
editGyms: function() {
if ( ! this.editGymView) {
this.editGymView = this.render({
xtype: 'EditGymStore',
});
}
this.application.viewport.setActiveItem(this.editGymView);
Ext.Msg.alert('Test', "Edit's index action was called!");
}
I am colleagues with the guy that wrote the tutorial you are referring to. You should add a comment on that post because I described your problem to him and he said that he knows the solution.
You can just add a link to this page so that you won't need to describe everything again.
Also he will (very) soon publish the 3rd part of that tutorial that will cover some similar things.