I would like to grab the text value from the input text field "workItemTextField" but I can't get the keypress event to fire with the below code.
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
_onWorkItemKeyPress: function() {
console.log('In _onWorkItemKeyPress');
console.log(this);
},
launch: function() {
this.add({
title: 'Time Entry',
width: 800,
padding: 10,
bodyPadding: 10,
renderTo: Ext.getBody(),
layout: {
type: 'vbox',
align: 'bottom'
},
items: [
{
xtype: 'rallytextfield',
itemId: 'workItemTextField',
fieldLabel: 'Work Item ID',
labelAlign: 'top',
listeners: {
scope: this,
keypress: this._onWorkItemKeyPress
}
}]
});
}
});
I was able to get it to fire replacing the listener with this:
listeners: {
keypress: {
element: 'el',
fn: this._onWorkItemKeyPress
}
}
But it doesn't return what I would expect. "this" is the textfield, but I can't call getValue() on it, and the attributes I would expect to be passed in (from looking at the api) are not what I would expect. The first arg is the event, 2nd not sure, and 3rd is the html element.
I am using apps/2.0rc3/sdk.js. I have looked at all the code I can find online and it looks like I am foing this correctly, but there must be something I am missing. What an I doing wrong?
I can get the value of the rallytextfield by using specialkey set to wait for ENTER, and then calling _onWorkItemKeyPress(field). field.getValue() works in this case. Unless your goal is not to get the complete value entered by the user, it is better not to use keypress and wait until the user indicated that they are done typing.
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
items:{ html:'App SDK 2.0rc3 Docs'},
launch: function() {
var that = this;
that.add({
title: 'My Text',
itemId:'mytext',
width: 800,
padding: 10,
bodyPadding: 10,
layout: {
type: 'vbox',
align: 'bottom'
},
items: [
{
xtype: 'rallytextfield',
itemId: 'workItemTextField',
fieldLabel: 'Work Item ID',
labelAlign: 'top',
listeners: {
specialkey: function(field, e){
// e.HOME, e.END, e.PAGE_UP, e.PAGE_DOWN,
// e.TAB, e.ESC, arrow keys: e.LEFT, e.RIGHT, e.UP, e.DOWN
if (e.getKey() == e.ENTER) {
that._onWorkItemKeyPress(field);
}
else{
console.log('?');
}
}
}
}]
});
},
_onWorkItemKeyPress:function(field){
console.log('value:',field.getValue());
}
});
Related
I have a button at the top right of every page that I want to link to a certain page within my application. Is there a way to give each instance of this button the same behaviour? and if so where would the code sit so that it affects every page? Many thanks in advance.
View:
items: [
{
title: '<span class="logo"></span>',
xtype: 'titlebar',
docked: 'top',
items: [
{
xtype: 'button',
align: 'right',
iconAlign: 'right',
id: 'buytickets',
text: 'Buy Tickets'
}
]
}
]
Controller (specific to one page):
config: {
refs: {
main: 'ListNav'
},
control: {
"button#buytickets": {
tap: 'buytickets'
}
}
},
buytickets: function(button, e, eOpts) {
this.getMain().push({
xtype: 'buyticketspanel'
});
},
You could just put the button at the top of your Viewport, in the app.js file:
Ext.application({
name: 'MyApp',
requires: [],
views: [/*Views*/],
controllers: [/*Controllers*/],
viewport: {
layout: 'vbox'
},
launch: function() {
var me = this;
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
Ext.Viewport.add([
{
title: '<span class="logo"/>',
xtype: 'titlebar',
docked: 'top',
items: [
{
xtype: 'button',
align: 'right',
iconAlign: 'right',
id: 'buytickets',
text: 'Buy Tickets',
handler: me.doBuyTickets
}
]
},
Ext.create('MyApp.view.Main', {flex: 1})
]);
},
doBuyTickets: function() {
//do stuff
}
});
****EDIT****:
However, you won't be able to re-purpose that bar as the title bar for a NestedView. If you need to have that, then you might be best served with a utils file that has a method to add a button to a toolbar, and just reuse that in the init function of any NestedView components.
Utils.js:
Ext.define("MyApp.util.Utils", {
singleton: true,
addBuyButton: function(toolbar)
{
toolbar.add({
text: 'Buy Tickets',
align: 'right',
handler: function() {
//do stuff
}
});
}
});
Controller:
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
config: {
refs: {
nestedList: 'nestedlist'
},
control: {
app-page: {
initialize: 'initAppPage'
}
}
},
initAppPage: function()
{
MyApp.utils.addBuyButton(this.getNestedList().getNavigationBar());
}
});
I have put two buttons inside a tab Panel in Sencha Touch 2 application. The code is given below:
var btnAttendance = Ext.create('Ext.Button', {
text: 'Take Attendance',
padding: 10,
width: 200,
handler: function () {
alert('a');
}
});
var btnAddUser = Ext.create('Ext.Button', {
text: 'Add User',
padding: 10,
width: 200,
handler: function () {
alert('a');
}
});
var buttonContainer = Ext.create('Ext.Panel', {
fullscreen: true,
title: 'Home',
defaults: {
margin: 5
},
layout: {
type: 'vbox',
align: 'center'
},
padding: 10,
items: [
btnAttendance,
btnAddUser
]
});
Ext.application({
requires: [
'Ext.tab.Panel'
],
launch: function () {
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
buttonContainer,
{
title: 'Present',
items: {
html: '2',
centered: true
},
cls: 'present'
},
{
title: 'Absent',
items: {
html: '3',
centered: true
},
cls: 'absent'
}
]
});
}
});
I have tried modifying the handler function as:
handler: function (button, event)
But this also doesn't work.
Thanks,
Nitin
You need to put all your code inside Ext.application... and launch:function(){...}.... Your code is working fine. See demonstration here.
But then again, buttonContainer is not really being added to any tab panel. If you change the tab, you can see buttonContainer is gone once to change the tabs. If you want to add it inside any tab do this-
First -
Set fullscreen:false to you buttonContainer panel.
var buttonContainer = Ext.create('Ext.Panel', {
fullscreen: false,
....... //rest of the code.
And suppose you want to add those buttons in Present tab. You can do this with following--
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
{
title: 'Present',
cls: 'present',
items: [
{
html: '2',
centered: true
},
buttonContainer
]
},
{
title: 'Absent',
items: {
html: '3',
centered: true
},
cls: 'absent'
}
]
});
Here, buttonContainer is added as an item inside present tab only. You can switch the tabs and can see buttons there with correct event handler.
See this demo here
If you follow MVC architecture, your job becomes much easier writing application having multiple views and user interactions. ST is all about MVC and it's good practice to follow it.
Pardon me if this doesnt make much sense as i am still trying to understand certain aspects of extjs.. I m trying to to dynamically fetch a menu when a page is loaded. But seems like my MenuFetch() function does not get called.
Here is my code and here is the page:
http://srikanthrajan.com/test/
Center = Ext.create('Ext.panel.Panel', {
title: "User Admin",
region: 'center',
layout: 'fit',
dockedItems: {
xtype: 'panel',
dock: 'left',
title: 'Main Menu',
width: 160,
layout: 'anchor',
collapsible: true,
collapseDirection: 'left',
items: [
{
defaults: {
width: 140,
layout: 'vbox',
xtype: 'linkbutton'
},
id: 'MainMenu',
xtype: 'panel',
listeners: {
load: function(menu) {
menu.show()
MenuFetch()
this.load()
}
}
}
]
}
});
//function that uses ajax to fetch menu items and add them
function MenuFetch() {
Ext.getBody().mask('loading')
var menu = Ext.ComponentManager.get('MainMenu')
menu.removeAll(true)
Ext.Ajax.request({
url: 'PanelScripts/getMenu.php',
method: 'POST',
callback: function(opt, success, response) {
var text = response.responseText;
var obj = Ext.JSON.decode(text);
if (success && !obj.failure) {
menu.add(obj)
Ext.getBody().unmask()
menu.show()
} else {
obj = Ext.JSON.decode(response.responseText);
Ext.Msg.alert('Error',obj.Error)
Ext.getBody().unmask()
}
}
});
}
PS: I am not sure if I even need the load listener. Basically I need to call the menuftech function which fetches the menu items in a json format.
Use the Ext.ComponentLoader (or loader config property) to load remote content for the menu. It seems like the xtype should be 'menu' instead of 'panel' based on what you are trying to accomplish. Try something like this:
var adminPanel = Ext.create('Ext.panel.Panel', {
title: 'User Admin',
region: 'center',
layout: 'fit',
dockedItems: {
xtype: 'panel',
dock: 'left',
title: 'Main Menu',
width: 160,
layout: 'anchor',
renderTo: Ext.getBody(),
items:[
{
xtype: 'menu',
width: 100,
loader: {
url: 'foo.bar',
autoLoad: true,
callback: function(loader, success, response, options) {
var menu = adminPanel.down('menu');
if (success) {
menu.add(response.items);
menu.show();
}
},
scope: this
}
}
]
}
});
In a small program that I have, I'm trying to have custom containers for every leaf node of my Nested List.
Here are a couple arbitrary example containers that I'm trying to test with:
Ext.define('DetailContainer1', {
extend: 'Ext.Container',
xtype: 'detail-container1',
layout: {
type: 'vbox'
},
height: 300,
style: 'background-color: #a9a9a9;',
// flex: 1,
items: [{
html: 'Detail Container1'
}]
});
Ext.define('DetailContainer2', {
extend: 'Ext.Container',
xtype: 'detail-container2',
layout: {
type: 'vbox'
},
height: 300,
style: 'background-color: #c9c9c9;',
// flex: 1,
items: [{
html: 'Detail Container2',
flex: 1
}, {
xtype: 'button',
text: 'Hit me!',
flex: 1
}]
});
How can I switch in the new containers when the user clicks on the leaf node?
This action should happen in onLeafItemTap(). Btw the initial container (#2) isn't showing at the moment. Is this a layout issue?
Here's some idea of what the screen should look like:
Complete source:
Ext.Loader.setConfig({
enabled: true
});
Ext.define('DetailContainer1', {
extend: 'Ext.Container',
xtype: 'detail-container1',
layout: {
type: 'vbox'
},
height: 300,
style: 'background-color: #a9a9a9;',
// flex: 1,
items: [{
html: 'Detail Container1'
}]
});
Ext.define('DetailContainer2', {
extend: 'Ext.Container',
xtype: 'detail-container2',
layout: {
type: 'vbox'
},
height: 300,
style: 'background-color: #c9c9c9;',
// flex: 1,
items: [{
html: 'Detail Container2',
flex: 1
}, {
xtype: 'button',
text: 'Hit me!',
flex: 1
}]
});
Ext.define('ListItem', {
extend: 'Ext.data.Model',
config: {
fields: ['text']
}
});
Ext.define('Sencha.view.MainView', {
extend: 'Ext.Container',
xtype: 'mainview',
layout: {
type: 'hbox'
},
initialize: function() {
this.treeStore = Ext.create('Ext.data.TreeStore', {
model: 'ListItem',
defaultRootProperty: 'items',
root: {
items: [{
text: 'Containers',
items: [{
text: 'Detail #1',
leaf: true
}, {
text: 'Detail #2',
leaf: true
}]
}]
}
});
this.detailContainer = Ext.create("DetailContainer2", {});
this.nestedList = Ext.create('Ext.NestedList', {
docked: 'left',
width: 300,
flex: 1,
store: this.treeStore,
detailCard: true,
detailContainer: this.detailContainer,
listeners: {
scope: this,
leafitemtap: this.onLeafItemTap
}
});
this.setItems([this.detailContainer, this.nestedList]);
},
onLeafItemTap: function(nestedList, list, index, node, record, e) {
var detailCard = nestedList.getDetailCard();
// nestedList.setDetailContainer(Ext.create("DetailContainer1", {}))
// detailCard.setHtml(record.get('text') + "...");
}
});
Ext.application({
launch: function() {
var container = Ext.create("Ext.Container", {
layout: {
type: 'hbox'
},
items: [{
xtype: 'mainview'
}]
});
Ext.Viewport.add(container);
}
});
Finally I've figured out the proper way to solve your problem.
Some explanations:
If you want to display "customized detailContainer" at the right side of your hbox, it's quite obvious that you should disable detailCard config for your Ext.NestedList because it's designed to display inline (i.e. take place of your Ext.NestedList).
When using Ext.define, everything should be included in config (except extend, xtype, alias, id, so in this case, layout has to be put in config).
flex should be defined in config as well.
At leafitemtap event, simply update your detailContainer config and remove/add it again as it would not be updated dynamically.
Please take a look at modified code snippet below, it works perfectly for me.
Ext.Loader.setConfig({ enabled: true });
Ext.define('DetailContainer1', {
extend: 'Ext.Container',
xtype: 'detail-container1',
config: {
flex: 1,
layout: {
type: 'vbox'
},
style: 'background-color: #a9a9a9;',
items: [
{html: 'Detail Container1'}
]
}
});
Ext.define('DetailContainer2', {
extend: 'Ext.Container',
xtype: 'detail-container2',
config: {
flex: 1,
layout: {
type: 'vbox'
},
style: 'background-color: #c9c9c9;',
items: [
{html: 'Detail Container2', flex: 1},
{xtype: 'button', text: 'Hit me!', flex: 1}
]
}
});
Ext.define('ListItem', {
extend: 'Ext.data.Model',
config: {
fields: ['text']
}
});
Ext.define('Sencha.view.MainView', {
extend: 'Ext.Container',
xtype: 'mainview',
id: 'mainview',
config: {
layout: {
type: 'hbox'
},
},
initialize: function() {
this.treeStore = Ext.create('Ext.data.TreeStore', {
model: 'ListItem',
defaultRootProperty: 'items',
root: {
items: [
{
text: 'Containers',
items: [
{ text: 'Detail #1', leaf: true },
{ text: 'Detail #2', leaf: true }
]
}
]
}
});
this.detailContainer = Ext.create("DetailContainer2");
this.nestedList = Ext.create('Ext.NestedList', {
flex: 1,
store: this.treeStore,
listeners: {
scope: this,
leafitemtap: this.onLeafItemTap
}
});
this.setItems([this.nestedList, this.detailContainer]);
},
onLeafItemTap: function(nestedList, list, index, node, record, e) {
mainview = Ext.getCmp('mainview');
if (index==0) {
mainview.detailContainer = Ext.create("DetailContainer1");
} else {
mainview.detailContainer = Ext.create("DetailContainer2");
}
mainview.removeAt(1);
mainview.add(mainview.detailContainer);
}
});
Ext.application({
launch: function() {
Ext.Viewport.add(
Ext.create("Ext.Container", {
layout: {
type: 'card'
},
items: [
{ xtype : 'mainview'}
]
}));
}
});
I have a panel whose items are a list and a panel like below
When I click on a button, I want to hide this panel. So far, I managed to do that, but this is what I get
I would like to know how to remove this grey space form the bottom of the panel.
I already this but it's not working :
this.toolsPnl.hide({type:'slide', direction:'up'});
this.doComponentLayout();
this.doLayout();
Update : Code
this.pasteBtn = new Ext.Button({
cls:'paste-copy-tools-panel',
text: 'Coller',
ui: 'normal',
handler : this.onPasteBtnTap,
scope:this
});
this.cancelBtn = new Ext.Button({
cls:'cancel-copy-tools-panel',
text: 'Annuler',
ui: 'normal',
handler: this.onCancelBtnTap,
scope:this
});
this.toolsPnl = new Ext.Panel({
layout:{type:'hbox', align:'stretch'},
height:40,
cls:'document-tools-panel',
hidden:true,
items:[this.pasteBtn,this.cancelBtn]
});
this.currentFolderPnl = new Ext.Panel({
cls:'document-current-folder-panel',
html:'/'
});
this.list = new Ext.List({
flex:1,
cls:'document-list',
id: 'document-list',
store: app.stores.Document,
itemTpl: app.templates.document
});
app.views.DocumentList.superclass.constructor.call(this, {
selectedCls : "x-item-selected",
dockedItems: [{
xtype: 'toolbar',
ui:'dark',
title: 'Documents',
items:[this.backBtn,{xtype:'spacer'},this.newBtn]
}],
layout: 'vbox',
items: [
this.currentFolderPnl,
this.list,
this.toolsPnl,
]
});
May help you with some hack. The main trick is in fixListHeight function, but for showing tools panel for the first time I have to call doComponentLayout for its container first. Don't know why this functionality doesn't work out of the box... have the feeling there is something I have missed. Nevertheless, here is the code.
new Ext.Application({
launch: function() {
// helper property
// indicates whether toolsPnl was shown already
this.first = true;
this.viewport = new Ext.TabPanel({
fullscreen: true,
layout: 'card',
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'spacer'
}, {
text: 'show',
listeners: {
tap: function (btn) {
var panel = Ext.getCmp('toolsPnl');
if (panel.isHidden()) {
panel.show({type:'slide', direction:'up'});
btn.setText('hide');
} else {
panel.hide({type:'slide', direction:'up'});
btn.setText('show');
this.fixListHeight();
}
},
scope: this
}
}]
}],
tabBar: {
layout: {
type: 'fit'
}
},
tabBarDock: 'bottom',
items: [{
title: 'Some tabs here...',
id: 'docTab',
iconCls: 'favorites',
layout: 'card',
dockedItems: [{
id: 'toolsPnl',
dock: 'bottom',
html: 'Tools panel',
style: {
'background-color': 'lightblue',
'line-height': '2em',
'text-align': 'center',
'height': '40px',
'width': '100%'
},
hidden:true,
listeners: {
show: function () {
if (this.first) {
Ext.getCmp('docTab').doComponentLayout();
this.fixListHeight();
this.first = false;
}
Ext.defer(function () {
this.fixListHeight(-1);
}, 250, this);
},
scope: this
}
}],
items : [{
xtype: 'list',
id: 'docList',
itemTpl: '{item}',
store: new Ext.data.Store({
data: [{item: 'Some data in the list...'}],
fields: ['item']
})
}]
}]
});
this.fixListHeight = function (direction) {
var panel = Ext.getCmp('toolsPnl'),
tab = Ext.getCmp('docTab'),
list = Ext.getCmp('docList'),
el,
h = list.getHeight(),
dh = panel.getHeight(),
dir = direction || 1;
el = tab.getEl().child('.x-panel-body');
el.setHeight(h + dh * dir);
el.child('.x-list').setHeight(h + dh * dir);
el.down('.x-scroller').setHeight(h + dh * dir);
};
}
});
That looks like the default sencha touch grey. A simple work around would be adding the code below to the panel
style:'background-color:White'