Get Extjs grid on which context menu item is clicked - javascript

I have a Grid and on grid context menu I am calling one function as follows-
On grids context menu I have added the following item
{ text: 'Preview', handler: 'PreviewGrid', scope: cnt, };
In controller-
previewGrid: function (contextMenuItem) {
// Here I am getting the item i.e. contextmenu item.
// But I want here is grid on which there was right click
}
I tried using item.ownerCt.up('grid')
but it is not working.
Any help will be appreciated.

Sample code: https://fiddle.sencha.com/#fiddle/1i9o
Ext.application({
name: 'Fiddle',
launch: function() {
var grid = Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
width: 400,
height: 500,
title: 'itemcontextmenu',
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": "homer#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": ""
}]
},
columns: [{
text: 'Name',
dataIndex: 'name',
flex: 1
}]
});
var contextMenu = Ext.create('Ext.menu.Menu', {
width: 200,
items: [{
text: 'Preview',
handler: function() {
var record = grid ? grid.getSelection()[0] : null;
if (!record) {
return;
}
alert(record.get('name'));
}
}]
});
grid.on("itemcontextmenu", function(grid, record, item, index, e) {
e.stopEvent();
contextMenu.showAt(e.getXY());
});
}
});

This works for me.
In grid listeners:
listeners: {
itemcontextmenu: function (grid, record, item, index, e) {
var contextMenu = Ext.create('Ext.menu.Menu', {
height: 200,
width: 250,
items: [{
text:'Preview',
handler: function () {
//code...
}
}]
});
e.stopEvent();
contextMenu.showAt(e.getXY());
}
}

Related

ExtJS Modern - Add multiple buttons to grid cell

In ExtJS Modern 6.2 how can I add multiple buttons to a grid cell?
I have seems examples using widgetcell but this seems to only work for a single button.
What I would like to do is have 2 buttons where one is always hidden depending on value in row.
You can use segment button as a widget:
Ext.application({
name: 'Fiddle',
launch: function () {
var store = Ext.create('Ext.data.Store', {
fields: ['name', 'email', 'phone', 'homeHidden'],
data: [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "555-111-1224",
"homeHidden": true
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234",
"homeHidden": false
}, {
'name': 'Homer',
"email": "home#simpsons.com",
"phone": "555-222-1244",
"homeHidden": true
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "555-222-1254",
"homeHidden": false
}]
});
Ext.create('Ext.grid.Grid', {
title: 'Simpsons',
itemConfig: {
viewModel: true
},
rowViewModel: true,
store: store,
columns: [{
text: 'Tool',
cell: {
xtype: 'widgetcell',
widget: {
xtype: 'segmentedbutton',
allowToggle: false,
items: [{
iconCls: 'x-fa fa-home',
bind: {
hidden: '{record.homeHidden}'
},
handler: function (btn, evt) {
const record = btn.up('widgetcell').getRecord();
console.log("Button Home", record.getData());
}
}, {
iconCls: 'x-fa fa-user',
handler: function (btn) {
const record = btn.up('widgetcell').getRecord();
console.log("Button User", record.getData());
}
}]
}
}
}, {
text: 'Name',
dataIndex: 'name',
width: 200
}, {
text: 'Email',
dataIndex: 'email',
width: 250
}, {
text: 'Phone',
dataIndex: 'phone',
width: 120
}],
layout: 'fit',
fullscreen: true
});
}
});

Sencha 6.5 (modern) how to dynamically change the items in a menu in a title bar?

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

extjs change grid cell type on rowclick listener

I am working on extjs Grid panel which has 3 columns user, email, password .
On rowclick event, I want to decrypt the password. I am trying this by setting a type to 'text' in config of password field column.
But I am not able to see the decrypted password.
Please suggest me the solution.
Thanks in advance.
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone'],
data: [{
"name": "Lisa",
"email": "lisa#simpsons.com",
"pass": "555-111-1224"
}, {
"name": "Bart",
"email": "bart#simpsons.com",
"pass": "555--1234"
}, {
"name": "Homer",
"email": "homer#simpsons.com",
"pass": "-222-1244"
}, {
"name": "Marge",
"email": "marge#simpsons.com",
"pass": "111-1254"
}]
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
listeners: {
rowclick: function (grid, record, e) {
var _this = this;
showPass('text');
function showPass(val) {
_this.getEl().component.columns[2].setConfig('type', "text");
}
}
},
columns: [{
header: 'Name',
dataIndex: 'name',
editor: 'textfield'
}, {
header: 'Email',
dataIndex: 'email',
flex: 1
}, {
header: "Password",
dataIndex: 'pass',
inputType: 'password',
renderer: function(val) {
var toReturn = "";
for (var x = 0; x < val.length; x++) {
toReturn += "●";
}
return toReturn;
}
}],
selType: 'rowmodel',
height: 200,
width: 400,
renderTo: Ext.getBody()
});
In ExtJs grid you can use widgetcolumn it provide config to add xtype inside widgetcolumn. You can refer ExtJs widgetcolumn docs
I have create small demo to show you, how it work. Sencha fiddle example
Hope it will help you.
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone'],
data: [{
"name": "Lisa",
"email": "lisa#simpsons.com",
"pass": "555-111-1224"
}, {
"name": "Bart",
"email": "bart#simpsons.com",
"pass": "555--1234"
}, {
"name": "Homer",
"email": "homer#simpsons.com",
"pass": "-222-1244"
}, {
"name": "Marge",
"email": "marge#simpsons.com",
"pass": "111-1254"
}]
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
listeners: {
select: function (grid, record, index) {
this.doChangeInputType(this.query('#password')[index]);
},
deselect: function (grid, record, index) {
this.doChangeInputType(this.query('#password')[index]);
},
rowclick: function (grid, record, element, rowIndex, e, eOpts) {
this.getSelectionModel().select(record)
}
},
columns: [{
header: 'Name',
dataIndex: 'name',
editor: 'textfield'
}, {
header: 'Email',
dataIndex: 'email',
flex: 1
}, {
header: "Password",
flex: 1,
dataIndex: 'pass',
xtype: 'widgetcolumn',
widget: {
xtype: 'textfield',
itemId: 'password',
inputType: 'password',
readOnly: true
}
}],
selType: 'rowmodel',
height: 300,
width: '100%',
renderTo: Ext.getBody(),
doChangeInputType: function (passwordField) {
var inputDom = Ext.get(passwordField.getInputId()).dom,
type = inputDom.type;
inputDom.type = type == "text" ? 'password' : 'text';
}
});
Having a background in security I cannot think of a situation where it's valid to have decrypted passwords displayed in a GUI to end users.

Itemtap listener in grid in ext.js not work

I'm a new in ext.js and I'm trying to figure why this example I borrowed from tutorial on http://docs.sencha.com/extjs/6.5.1/guides/quick_start/handling_events.html
doesn't work for me.
I added two listeners to code: itemmouseenter - it's work correctly, and itemtap - it's not working.
Ext.create('Ext.tab.Panel', {
renderTo: Ext.getBody(),
xtype: 'tabpanel',
items: [{
title: 'Employee Directory',
xtype: 'grid',
iconCls: 'x-fa fa-users',
listeners: {
itemmouseenter: function() {
console.log( 'Mouse Enter');
},
itemtap: function(view, index, item, e) {
console.log("item tap")
}
},
store: {
data: [{
"firstName": "Jean",
"lastName": "Grey",
"officeLocation": "Lawrence, KS",
"phoneNumber": "(372) 792-6728"
}, {
"firstName": "Phillip",
"lastName": "Fry",
"officeLocation": "Lawrence, KS",
"phoneNumber": "(318) 224-8644"
}, {
"firstName": "Peter",
"lastName": "Quill",
"officeLocation": "Redwood City, CA",
"phoneNumber": "(718) 480-8560"
}]
},
columns: [{
text: 'First Name',
dataIndex: 'firstName',
flex: 1
}, {
text: 'Last Name',
dataIndex: 'lastName',
flex: 1
}, {
text: 'Phone Number',
dataIndex: 'phoneNumber',
flex: 1
}]
}, {
title: 'About Sencha',
iconCls: 'x-fa fa-info-circle'
}]
});
In classic the event is itemclick. The sample you're looking at is for modern.
As I have checked in sencha fiddle itemtap is working fine for modern but for Classic you have to user itemlick. I am using your same code in my fiddle you can check by given below link:-
EXTJS GRID ITEM TAP
Ext.application({
name : 'Fiddle',
launch : function() {
var panel = Ext.create('Ext.window.Window', {
width:'100%',
height:'100%',
layout:'fit',
items:[{
xtype: 'tabpanel',
items: [{
title: 'Employee Directory',
xtype: 'grid',
layout:'fit',
iconCls: 'x-fa fa-users',
listeners: {
itemmouseenter: function() {
console.log('Mouse Enter');
},
itemclick: function(grid, record, item, index, e, eOpts) {
Ext.Msg.alert('Info',`You have tapped on ${index+1} item`);
}
},
store: {
data: [{
"firstName": "Jean",
"lastName": "Grey",
"officeLocation": "Lawrence, KS",
"phoneNumber": "(372) 792-6728"
}, {
"firstName": "Phillip",
"lastName": "Fry",
"officeLocation": "Lawrence, KS",
"phoneNumber": "(318) 224-8644"
}, {
"firstName": "Peter",
"lastName": "Quill",
"officeLocation": "Redwood City, CA",
"phoneNumber": "(718) 480-8560"
}]
},
columns: [{
text: 'First Name',
dataIndex: 'firstName',
flex: 1
}, {
text: 'Last Name',
dataIndex: 'lastName',
flex: 1
}, {
text: 'Phone Number',
dataIndex: 'phoneNumber',
flex: 1
}]
}, {
title: 'About Sencha',
iconCls: 'x-fa fa-info-circle'
}]
}]
});
panel.show()
}
});

How to select extjs grid action column using the query component from the MVC controller file?

starting with the MVC demo project guide I added an extra actioncolumn and I was wondering how to wire it in the controller file ?
guide: http://www.sencha.com/learn/the-mvc-application-architecture/
Ext.define('app.view.admin.viewlist', {
extend: 'Ext.grid.Panel',
columnLines: true,
region: 'center',
menuDisabled: true,
layout: 'fit',
initComponent: function (cnfg) {
this.columns = [
{
text: 'date',
dataIndex: 'Series',
sortableColumns: false,
hideable: false,
enableLocking: false,
width: 100
},{
hidden : true,
text:'Values',
sortableColumns : false,
hideable: false,
columns:[{
header: 'D1',
hidden: true,
dataIndex: 'D10EOD',
sortableColumns : false,
hideable: false
},{
xtype: 'actioncolumn',
icon: '/static/img/icon/table_refresh.png',
tooltip: 'Reset',
align: 'center'
}]
}
];
this.callParent(arguments);
}});
Controller init function
init: function() {
this.control({
'volatilityedit actioncolumn img' : { <--- ??
click: this.reset
}
});
},
reset: function(grid, rowIndex, colIndex) {
//var rec = grid.getStore().getAt(rowIndex);
alert("Go");
},
Thanks
Depend on what your actions should do you can decide if you need controler or not.
You should use controller when your action interacts with other components - otherwise you can write own methods inside component (grid)
Here you have simple example of grid with actioncolumn:
Ext.onReady(function () {
Ext.create('Ext.data.Store', {
storeId: 'employeeStore',
fields: ['firstname', 'lastname', 'seniority', 'dep', 'hired'],
data: [{
firstname: "Michael",
lastname: "Scott"
}, {
firstname: "Dwight",
lastname: "Schrute"
}, {
firstname: "Jim",
lastname: "Halpert"
}, {
firstname: "Kevin",
lastname: "Malone"
}, {
firstname: "Angela",
lastname: "Martin"
}]
});
Ext.create('Ext.grid.Panel', {
title: 'Action Column Demo',
store: Ext.data.StoreManager.lookup('employeeStore'),
columns: [{
text: 'First Name',
dataIndex: 'firstname'
}, {
text: 'Last Name',
dataIndex: 'lastname'
}, {
xtype: 'actioncolumn',
width: 50,
items: [{
icon: 'app/resources/images/cog_edit.png',
// Use a URL in the icon config
tooltip: 'Edit',
handler: function (grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
alert("Edit " + rec.get('firstname'));
}
}, {
icon: 'app/resources/images/delete.png',
tooltip: 'Delete',
handler: function (grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
alert("Terminate " + rec.get('firstname'));
}
}]
}],
width: 250,
renderTo: Ext.getBody()
});
});
This is an example with an action column and a function in a controller:
View:
{
xtype: 'actioncolumn',
id:'actionColumnGridCas',
flex: 1,
hideable: false,
items: ['->',{
icon: '/images/user_edit.png',
tooltip: 'edit',
iconCls:'act-edit'
},
{
icon: '/images/user_delete.png',
tooltip: 'delete',
iconCls:'act-delete'
}]
}
Controller:
'.grid_alias actioncolumn[id=actionColumnGrid]': {
click: me.onActionColumnGridCasSelect
}
onActionColumnGridCasSelect: function(view, cell, rowIndex, colIndex, e) {
var m = e.getTarget().className.match(/\bact-(\w+)\b/);
if (m === null || m === undefined) {
return;
}
var action = m[1];
switch (action) {
case 'edit':
alert('edit');
break;
case 'delete':
alert('delete');
break;
}
}

Categories

Resources