How to use Extjs delegate pattern to add tooltip on Extjs toolbar - extjs4

I used Extjs tool bar with many buttons.can i know how to apply tool tip for that buttons with delegate pattern

here my toolbar button
xtype: 'toolbar',
dock: 'top',
id: 'toolbar-id',
items: [
{
xtype: 'button1',
id: 'button-id1',
cls: 'tb-btn',
qtipText: 'tool tip description',
qtipTitle: 'tool tip title'
},
{
xtype: 'button2',
id: 'button-id2',
cls: 'tb-btn',
qtipText: 'tool tip description',
qtipTitle: 'tool tip title'
}
]
apply tooltip with using delegate pattern
render: function(Component, eOpts) {
Component.tip = Ext.create('Ext.tip.ToolTip', {
target: Component.el,
delegate: '.tb-btn',
renderTo: Ext.getBody(),
listeners: {
beforeshow: function updateTipBody(tip) {
var btnData = Component.getComponent(tip.triggerElement.id);
tip.update("<div class='tol-box'><h4 class='tool-tip-title'>" + btnData.qtipTitle + '</h4><p>' + btnData.qtipText + "</p></div>");
}
}
});
}

The code should be like this :
var store = Ext.create('Ext.data.ArrayStore', {
fields: ['company', 'price', 'change'],
data: [
['3m Co', 71.72, 0.02],
['Alcoa Inc', 29.01, 0.42],
['Altria Group Inc', 83.81, 0.28],
['American Express Company', 52.55, 0.01],
['American International Group, Inc.', 64.13, 0.31],
['AT&T Inc.', 31.61, -0.48]
]
});
var grid = Ext.create('Ext.grid.Panel', {
title: 'Array Grid',
store: store,
columns: [
{text: 'Company', flex: 1, dataIndex: 'company'},
{text: 'Price', width: 75, dataIndex: 'price'},
{text: 'Change', width: 75, dataIndex: 'change'}
],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
grid.getView().on('render', function(view) {
view.tip = Ext.create('Ext.tip.ToolTip', {
// The overall target element.
target: view.el,
// Each grid row causes its own seperate show and hide.
delegate: view.itemSelector,
// Moving within the row should not hide the tip.
trackMouse: true,
// Render immediately so that tip.body can be referenced prior to the first show.
renderTo: Ext.getBody(),
listeners: {
// Change content dynamically depending on which element triggered the show.
beforeshow: function updateTipBody(tip) {
tip.update('Over company "' + view.getRecord(tip.triggerElement).get('company') + '"');
}
}
});
});
If you want more examples or details ,you can refer this Site.

Related

Creating user story popover

Could someone help me create a popover that appears on mouse hover to display user story name and project it belongs to. I've created a custom app in rally that displays parent and child stories in a grid. I would like to create a popover when user hover on child story ID to view Name and project information. How can this functionality be added?
this.grid = this.down('#gridCnt').add({
xtype: 'rallygrid',
id: 'dataGrid',
showPagingToolbar: true,
flex: 1,
store: myCustomStore,
plugins: ['rallyboardformattedidhoverable'],
enableBlockedReasonPopover: false,
columnCfgs: [{
xtype: 'templatecolumn',
text: 'ID',
dataIndex: 'FormattedID',
width: 80,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
}, {
text: 'Name',
dataIndex: 'Name',
},
{
text: 'Child stories',
dataIndex: 'Children',
flex: 1,
renderer: function(value) {
var html = [];
Ext.Array.each(value, function(child) {
html.push('' + child.FormattedID + '' + ' - ' + child.Project);
});
return html.join('</br>');
}
},
There is a plugin that should do exactly what you are looking for. Just add the plugin to your grid config:
plugins: ['rallyboardformattedidhoverable'],
getRecord: function(x) {
return this.view.getRecord(x);
},

Button Event not getting fired when put inside Tab Panel in Sencha Touch 2

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.

Passing rowIndex to a window in extjs 4

I have a store, a grid, a window and a few text boxes in the window. What I need is that on clicking the actioncolumn in the grid, i need to get the rowIndex of the clicked row and pass it to the window as a parameter. There, i need to load the store and get the values and set it in the appropriate textboxes. I'm not sure how to pass the rowIndex from grid to window on click. Wen I try to alert the value of a in the testfunction, it comes up as undefined. Pls help and below is my code.
Js File:
Ext.onReady(function() {
var rIx;
Ext.create('Ext.data.Store', {
storeId:'employeeStore',
fields:['firstname', 'lastname', 'senority', 'dep', 'hired'],
data:[
{firstname:"Michael", lastname:"Scott", senority:7, dep:"Manangement", hired:"01/10/2004"},
{firstname:"Dwight", lastname:"Schrute", senority:2, dep:"Sales", hired:"04/01/2004"},
{firstname:"Jim", lastname:"Halpert", senority:3, dep:"Sales", hired:"02/22/2006"},
{firstname:"Kevin", lastname:"Malone", senority:4, dep:"Accounting", hired:"06/10/2007"},
{firstname:"Angela", lastname:"Martin", senority:5, dep:"Accounting", hired:"10/21/2008"}
]
});
Ext.create('Ext.grid.Panel', {
title: 'Employee Data',
store: Ext.data.StoreManager.lookup('employeeStore'),
columns: [
{ text: 'First Name', dataIndex: 'firstname' },
{
header: 'Button',
xtype: 'actioncolumn',
icon : 'test.png',
handler: function(grid, rowIndex, colIndex, item, e , record) {
rIx=rowIndex;
//var rec = grid.getStore().getAt(rowIndex);
//alert("Edit " + rec.get('firstname'));
Ext.create('MyWindow').show();
}
}
],
width: 500,
renderTo: Ext.getBody()
});
var testFunction = function(a){alert("a= "+a);
var r = Ext.data.StoreManager.lookup('employeeStore').getAt(a);
var firstname = r.get('firstname');
Ext.getCmp('fname').setValue(firstname);
};
Ext.define('MyWindow', {
extend: 'Ext.window.Window',
store : Ext.data.StoreManager.lookup('employeeStore'),
height: 250,
width: 250,
title: 'My Window',
items: [
{
xtype: 'textfield',
id : 'fname',
fieldLabel:'Name'
}
],
listeners: {
afterrender: Ext.Function.pass(testFunction, [rIx])
}
});
});
Ext.Function.pass(testFunction, [rIx]) takes the current value of rIx when pass is executed. The method is being called long before rIx is ever set to anything meaningful. Javascript is a pass-by-value language. It doesn't matter that eventually rIx gets set to the row index. By that point Ext.Function.pass has already been executed and the parameter it passed in was undefined.
Another approach is to just push the rowIndex onto your window as a property.
Ext.create('Ext.grid.Panel', {
title: 'Employee Data',
store: Ext.data.StoreManager.lookup('employeeStore'),
columns: [
{ text: 'First Name', dataIndex: 'firstname' },
{
header: 'Button',
xtype: 'actioncolumn',
icon : 'test.png',
handler: function(grid, rowIndex, colIndex, item, e , record) {
Ext.create('MyWindow', {rIx: rowIndex}).show();
}
}
],
width: 500,
renderTo: Ext.getBody()
});
Ext.define('MyWindow', {
extend: 'Ext.window.Window',
store : Ext.data.StoreManager.lookup('employeeStore'),
height: 250,
width: 250,
title: 'My Window',
items: [
{
xtype: 'textfield',
id : 'fname',
fieldLabel:'Name'
}
],
listeners: {
afterrender: function(win){
alert("idx= " + win.rIx);
var r = Ext.data.StoreManager.lookup('employeeStore').getAt(win.rIx);
var firstname = r.get('firstname');
Ext.getCmp('fname').setValue(firstname);
}
}
});
Another option is to setup the window's afterrender listener in your handler function instead of adding it in the window's class definition. This approach is a bit cleaner in my opinion. I'm not a big fan of adding unrelated state properties to components.
Ext.create('Ext.grid.Panel', {
title: 'Employee Data',
store: Ext.data.StoreManager.lookup('employeeStore'),
columns: [
{ text: 'First Name', dataIndex: 'firstname' },
{
header: 'Button',
xtype: 'actioncolumn',
icon : 'test.png',
handler: function(grid, rowIndex, colIndex, item, e , record) {
var win = Ext.create('MyWindow');
// add the listener after to avoid bashing any listener config
// that may already exist for the window.
win.on('afterrender', function() {
// rowIndex is available in the closure
alert("idx= " + rowIndex);
var r = Ext.data.StoreManager.lookup('employeeStore').getAt(rowIndex);
var firstname = r.get('firstname');
Ext.getCmp('fname').setValue(firstname);
});
win.show();
}
}
],
width: 500,
renderTo: Ext.getBody()
});

Extjs 4 portlet on load collapsed not working properly

I am using ExtJS portal code in my application
I want to make portlet in collapsed state at the time of loading the page. So I have done something like
items: [{
id: 'portlet-1',
title: 'Grid Portlet Texsds',
tools: this.getTools(),
height:200,
**collapsed:true,**
autoScroll :true,
items: Ext.create('Ext.app.GridPortlet'),
listeners: {
'close': Ext.bind(this.onPortletClose, this),
'endDrag': Ext.bind(this.onPortletDrag, this),
'resize' :Ext.bind(this.onPortletResize, this)
}
}
I have made collapsed property to true. But because of this when I am trying to expand the portlet [after page load] I can see blank Grid.Plz. refer the attached image.
What is the problem ? do I need to do refresh or something ? because when I set collapsed to false I can see the grid.
Please suggest what is missing here.
This is a code for the getTools: function(){
{
type: 'Minimize',
handler: function(e,target,panelHeader,tool){
//panelHeader.ownerCt.toggleCollapse();
if (panelHeader.ownerCt.collapsed)
{
panelHeader.ownerCt.expand();
}
else {
panelHeader.ownerCt.collapse();
}
}
}
for the first time when the portlet get load it is in collapsed state, Now when I click on cross icon not [the "^" for expand icons ] I can see the Blank grid.
Hope this time I am able to explain well.
I took the Ext JS 4 example portal app and added your code (without the asterisks) to portlet-1. It is properly collapsed on load and expands to show the grid.
I don't think there is anything wrong with the code you've posted. Perhaps you've changed the layout or layout properties of the surrounding container and that is affecting your portlet.
Here is my complete portal.js:
Ext.define('Ext.app.Portal', {
extend: 'Ext.container.Viewport',
//requires: [ 'Ext.diag.layout.ContextItem', 'Ext.diag.layout.Context' ],
uses: ['Ext.app.PortalPanel', 'Ext.app.PortalColumn', 'Ext.app.GridPortlet', 'Ext.app.ChartPortlet'],
getTools: function(){
return [{
xtype: 'tool',
type: 'gear',
handler: function(e, target, panelHeader, tool){
var portlet = panelHeader.ownerCt;
portlet.setLoading('Loading...');
Ext.defer(function() {
portlet.setLoading(false);
}, 2000);
}
}];
},
initComponent: function(){
var content = '<div class="portlet-content">'+Ext.example.shortBogusMarkup+'</div>';
Ext.apply(this, {
id: 'app-viewport',
layout: {
type: 'border',
padding: '0 5 5 5' // pad the layout from the window edges
},
items: [{
id: 'app-header',
xtype: 'box',
region: 'north',
height: 40,
html: 'Ext Portal'
},{
xtype: 'container',
region: 'center',
layout: 'border',
items: [{
id: 'app-options',
title: 'Options',
region: 'west',
animCollapse: true,
width: 200,
minWidth: 150,
maxWidth: 400,
split: true,
collapsible: true,
layout:{
type: 'accordion',
animate: true
},
items: [{
html: content,
title:'Navigation',
autoScroll: true,
border: false,
iconCls: 'nav'
},{
title:'Settings',
html: content,
border: false,
autoScroll: true,
iconCls: 'settings'
}]
},{
id: 'app-portal',
xtype: 'portalpanel',
region: 'center',
items: [{
id: 'col-1',
items: [{
id: 'portlet-1',
title: 'Grid Portlet',
tools: this.getTools(),
collapsed: true,
height: 200,
autoscroll: true,
items: Ext.create('Ext.app.GridPortlet'),
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
},{
id: 'portlet-2',
title: 'Portlet 2',
tools: this.getTools(),
html: content,
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
},{
id: 'col-2',
items: [{
id: 'portlet-3',
title: 'Portlet 3',
tools: this.getTools(),
html: '<div class="portlet-content">'+Ext.example.bogusMarkup+'</div>',
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
},{
id: 'col-3',
items: [{
id: 'portlet-4',
title: 'Stock Portlet',
tools: this.getTools(),
items: Ext.create('Ext.app.ChartPortlet'),
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
}]
}]
}]
});
this.callParent(arguments);
},
onPortletClose: function(portlet) {
this.showMsg('"' + portlet.title + '" was removed');
},
showMsg: function(msg) {
var el = Ext.get('app-msg'),
msgId = Ext.id();
this.msgId = msgId;
el.update(msg).show();
Ext.defer(this.clearMsg, 3000, this, [msgId]);
},
clearMsg: function(msgId) {
if (msgId === this.msgId) {
Ext.get('app-msg').hide();
}
}
});

Panel not hiding properly

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'