Using ExtJS 4.2.3, I have GRID PANEL with list of attachments. Grid panel has cellclick listener which start to download file after selection cell. Need to remake code for image click in column renderer (column name 'Save')
Example of current code with cell click:
FileGrid = new Ext.grid.Panel({
renderTo: "EXT-CONTENT",
width: 500,
height: 600,
listeners: {
cellclick: function (table, td, cellIndex, record, tr, rowIndex, e) {
var url = 'http://.../Attachment/Get?document_GUID=' + record.get("document_GUID");
console.log(url);
window.location = url;
}
},
Code with column 'Save' where I need to reproduce cellclick function by column renderer:
},
columns: {
defaults: { filter: true },
items: [
{
text: 'Attachname', dataIndex: 'attachment_fileName', width: 395, cellWrap: true,
},
{
text: 'Save', width: 100, align: 'center', sortable: false, menuDisabled: true, cellWrap: true,
renderer: function (val) {
return '<a href="http://.../Attachment/Get?document" onclick="????">' + "<img src='/APPLICATION/Images/Save24.gif'/>" +
'</a>';
}
},
]
},
store: Ext.data.StoreManager.lookup('FileStore')
});
You need to use actioncolumn for this.
In this FIDDLE, I have create a demo using your code and put modification. I hope this will help or guide you to achieve your requirement.
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone', 'document_GUID'],
data: {
'items': [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "555-111-1224",
"document_GUID": 123
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234",
"document_GUID": 124
}, {
'name': 'Homer',
"email": "homer#simpsons.com",
"phone": "555-222-1244",
"document_GUID": 125
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "555-222-1254",
"document_GUID": 126
}]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}, {
xtype: 'actioncolumn',
width: 50,
text: 'Save',
items: [{
icon: 'https://image.flaticon.com/icons/svg/69/69656.svg', // Use a URL in the icon config
itemId: 'save',
handler: function (grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
var url = 'http://Attachment/Get?document_GUID=' + rec.get("document_GUID") + '_' + rec.get("name");
alert(url);
console.log(url);
}
}]
}],
height: 200,
renderTo: Ext.getBody()
});
Have you tried to use a action column instead?
{
xtype:'actioncolumn',
width:50,
items: [{
icon: 'urlToMyImage/image.png',
tooltip: 'Do Stuff',
handler: function(grid, rowIndex, colIndex) {
//The hole record to play with
var rec = grid.getStore().getAt(rowIndex);
//the ID
alert("My ID" + rec.get('MyIDColumn'));
}
}]
}
Related
Through ViewModel stores I'm getting this JSON data;
{
"success": true,
"msg": "OK",
"count": 2,
"data": [
{
"firstname": "BLA",
"lastname": "BLALA",
"isactive": true,
...
},
{
"firstname": "BLAAA",
"lastname": "BLALAAA",
"isactive": false,
...
}
I have two grids on one panel and one of them will load data only with isactive: true field, other grid will load only with false. So where and how I need to filtering store to load specified data to grids?
Here is VM;
Ext.define('MyApp.view.ListingVM', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.listing',
requires: [...],
reference: 'loyaltyvm',
stores: {
// Should I define the filter on here?
bonusTrans: {
storeId: 'bonusTrans',
// reference: 'bonusTrans',
model: 'MyApp.model.BonusTrans',
autoLoad: true,
session: true,
pageSize: MyApp.Globals.LIST_PAGE_SIZE
}
}
});
This is panel's grid sample where defined both of Grids. I've tried several way to get store and filtering but couldn't be succes;
getColumns: function () {
var me = this;
var panelItems = [
{
xtype: 'container',
layout: {type: 'hbox', align: 'stretch', pack: 'start'},
items: [
xtype: 'bonustrans',
flex: 1,
title: 'Current Bonus',
getListCols: function () {
var me = this;
debugger;
// var activeStore = Ext.getStore('bonusTrans');
// var activeStore = me.viewModel.get('bonusTrans');
// var view = me.getView();
// var vm = view.getViewModel();
// var vm.getStore('bonusTrans')
// var activeStore = me.getViewModel().getStore('bonusTrans');
var activeStore = me.getViewModel('loyaltyvm').getStores('bonusTrans');
activeStore.filter('isactive', 'true');
var listCols = [
{
xtype: 'firstnamecol',
flex: 1
},
{
xtype: 'checkoutcol'
},
{
xtype: 'bonustotalcol'
}
];
return listCols;
}
//... other Grid is just defined below of this line and it should loads data only with 'isactive' field is false.
Use chained stores, fiddle:
Ext.application({
name : 'Fiddle',
launch : function() {
new Ext.container.Viewport({
layout: {
type: 'hbox',
align: 'stretch'
},
viewModel: {
stores: {
everything: {
autoLoad: true,
proxy: {
type: 'ajax',
url: 'data1.json'
}
},
active: {
type: 'chained',
source: '{everything}',
filters: [{
property: 'active',
value: true
}]
},
inactive: {
type: 'chained',
source: '{everything}',
filters: [{
property: 'active',
value: false
}]
}
}
},
items: [{
flex: 1,
xtype: 'gridpanel',
title: 'Active',
bind: '{active}',
columns: [{
dataIndex: 'name'
}]
}, {
flex: 1,
xtype: 'gridpanel',
title: 'Inactive',
bind: '{inactive}',
columns: [{
dataIndex: 'name'
}]
}]
});
}
});
The way of chained stores is surely the best,
here you can see a working fiddle on classic
and here is the code:
Ext.application({
name: 'Fiddle',
launch: function () {
var storeAll = Ext.create('Ext.data.Store', {
storeId: 'storeAll',
fields: [{
name: 'firstname'
}, {
name: 'lastname'
}, {
name: 'active'
}],
data: [{
firstname: 'test1',
lastname: 'test1',
active: true
}, {
firstname: 'test2',
lastname: 'test2',
active: true
}, {
firstname: 'test3',
lastname: 'test3',
active: false
}]
}),
chainedStoreActive = Ext.create('Ext.data.ChainedStore', {
source: storeAll,
filters: [{
property: 'active',
value: true
}]
}),
chainedStoreNoActive = Ext.create('Ext.data.ChainedStore', {
source: storeAll,
filters: [{
property: 'active',
value: false
}]
});
Ext.create({
xtype: 'viewport',
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'gridpanel',
title: 'grid ALL',
store: storeAll,
columns: [{
text: 'First Name',
dataIndex: 'firstname'
}, {
text: 'Last Name',
dataIndex: 'lastname'
}],
flex: 1
}, {
xtype: 'gridpanel',
title: 'grid active',
store: chainedStoreActive,
columns: [{
text: 'First Name',
dataIndex: 'firstname'
}, {
text: 'Last Name',
dataIndex: 'lastname'
}],
flex: 1
}, {
xtype: 'gridpanel',
title: 'grid inactive',
store: chainedStoreNoActive,
columns: [{
text: 'First Name',
dataIndex: 'firstname'
}, {
text: 'Last Name',
dataIndex: 'lastname'
}],
flex: 1
}],
renderTo: Ext.getBody()
});
}
});
The global or the "allelements" store, need to be a global store, the chained ones can be created in a viewmodel of a view.
My live search grid works fine but when I click on next page or do other thing about the grid, the search grid lose highlight terms search,does anyone help me what do I do? I want to keep highlighted terms search in all page. Thanks
bellow a snippet of my code:
var pagingStore = Ext.create('Ext.data.Store', {
proxy: {
type: 'memory',
enablePaging: true
},
remoteFilter: true,
pageSize: 5
}),
remoteStore = Ext.create('Ext.data.Store', {
autoLoad: true,
proxy: {
type: 'ajax',
url: 'js/json/pagingStore.json',
reader: {
rootProperty: 'items'
}
},
fields: ['name', 'email', 'phone', 'type']
});
remoteStore.load(function () {
pagingStore.getProxy().setData(remoteStore.getRange());
pagingStore.load();
});
var bbar = new Ext.PagingToolbar({
store: pagingStore, //the store you use in your grid
displayInfo: true,
items: [ {
xtype: 'textfield',
name: 'searchField',
id: 'txtfield',
fieldLabel:'Search:',
labelAlign:'right',
emptyText:'search...',
width: 300,
listeners: {
change: {
fn: onTextFieldChange
}
}
}
]
});
bbar.down('#refresh').hide();
Ext.create('Ext.grid.Panel', {
height: 400,
title: 'Simpsons',
id: 'gridPanel',
store: pagingStore,
columns: [{
text: 'Name',
dataIndex: 'name',
filterable: true
}, {
text: 'Email',
dataIndex: 'email'
}, {
text: 'Phone',
dataIndex: 'phone'
},
{
text: 'Type',
dataIndex: 'type'
}],
bbar: bbar,
renderTo: Ext.getBody()
});
So I answer my own question, I've created a highlight() method and put it on the container: after field search input on each click, the highlight stay on the search terms: ;)
cont.getEl().on({
click: {
fn: highlight
}
});
I try to show colorpicker in grid cell. But i can't do it correct. It must look like show/hide panel whith colorpiker and save piked color in grid cell.
I try to use several controls. But allways have problems. Please explain to do it right way.
Now it's look like this:
and the code:
{
xtype: "widgetcolumn",
dataIndex: "color",
text: "Color",
width: 60,
widget: {
xtype: 'colorpicker',
align: 'right',
value: '993300',
},
listeners: {
select: function(picker, selColor) {
value = selColor,
hide(this);
}
}
}
show color picker in grid cell.double click on grid row then select menu bar color and click on update plugin color show on grid row.code check in js fiddler
Ext.onReady(function () {
var userStore = Ext.create('Ext.data.Store', {
autoLoad: 'false',
fields: [
{ name: 'name' },
{ name: 'email' },
{ name: 'colorCode' }
],
data: [
{ name: 'Lisa', email: 'lisa#simpsons.com'},
{ name: 'Bart', email: 'bart#simpsons.com'},
{ name: 'Homer', email: 'homer#simpsons.com'},
{ name: 'Marge', email: 'marge#simpsons.com'},
{ name: 'Homer', email: 'homer#simpsons.com' },
{ name: 'Marge', email: 'marge#simpsons.com'},
]
});
var customColors = ['FF4848', 'FF7575', 'FFA8A8', 'FFBBBB', 'FFCECE', 'FFECEC', 'FF68DD', 'FF86E3', 'FFACEC', 'FFC8F2', 'FF62B0', 'FF73B9', 'FF86C2', 'FFA8D3',
'E469FE', 'EA8DFE', 'EFA9FE', 'D568FD', 'D97BFD', 'DD88FD', 'E7A9FE', '9669FE', 'A27AFE', 'C4ABFE', 'D0BCFE', 'DDCEFF', 'FFA4FF', 'EAA6EA', 'D698FE', 'CEA8F4',
'BCB4F3', 'A9C5EB', '8CD1E6', 'FFBBFF', 'EEBBEE', 'DFB0FF', 'DBBFF7', 'CBC5F5', 'BAD0EF', 'A5DBEB', 'FFCEFF', 'F0C4F0', 'E8C6FF', 'E1CAF9', 'D7D1F8', 'CEDEF4',
'B8E2EF', '62A9FF', '62D0FF', '06DCFB', '01FCEF', '03EBA6', '01F33E', '99E0FF', '63E9FC', '74FEF8', '62FDCE', '72FE95', 'C0F7FE', 'CEFFFD', 'BEFEEB', 'CAFFD8',
'1FCB4A', '59955C', '48FB0D', '2DC800', '59DF00', '9D9D00', 'B6BA18', 'DFDF00', 'DFE32D', '93EEAA', 'A6CAA9', 'AAFD8E', '6FFF44', 'ABFF73', 'FFFF84', 'E7F3F1',
'EEF093', 'BDF4CB', 'C9DECB', 'CAFEB8', 'A5FF8A', 'D1FFB3', 'FFFFB5', 'F5F7C4', 'BABA21', 'C8B400', 'DFA800', 'DB9900', 'FFB428', 'FF9331', 'FF800D', 'D8F0F8',
'E6E671', 'E6CE00', 'FFCB2F', 'FFB60B', 'FFC65B', 'FFAB60', 'FFAC62', 'F7DE00', 'FFD34F', 'FFBE28', 'FFCE73', 'FFBB7D', 'FFBD82', 'EEEECE', 'EADFBF', 'E4C6A7',
'E6C5B9', 'DEB19E', 'E8CCBF', 'DDB9B9', 'E1E1A8', 'DECF9C', 'DAAF85', 'DAA794', 'CF8D72', 'DAAC96', 'D1A0A0', 'FF8E8E', 'E994AB', 'FF7DFF', 'D881ED', 'B7B7FF',
'A6DEEE', 'CFE7E2', 'FFC8C8', 'F4CAD6', 'FFA8FF', 'EFCDF8', 'C6C6FF', 'C0E7F3', 'DCEDEA', 'FFEAEA', 'F8DAE2', 'FFC4FF', 'EFCDF8', 'DBDBFF'];
Ext.create('Ext.window.Window', {
height: 400,
width: 350,
xtype: 'panel',
layout: 'fit',
items:
[
{
layout: 'border',
height: 200,
renderTo: Ext.getBody(),
items:
[
{
xtype: 'grid',
// height: 300,
region: 'center',
id: 'GridId',
store: userStore,
columns: [
{
header: 'Name',
width: 100,
sortable: false,
hideable: false,
dataIndex: 'name',
editor: {
xtype: 'textfield'
}
},
{
header: 'Email Address',
width: 150,
dataIndex: 'email',
editor: {
xtype: 'textfield',
}
},
{
header: 'Color',
dataIndex: 'colorCode',
width: '20%',
renderer: function (value, metaData) {
metaData.tdAttr = 'bgcolor=' + value;
return value;
},
editor: {
xtype: 'button',
text: 'Color Menu',
menu: new Ext.menu.ColorPicker({
resizable: true,
scrollable: true,
listeners: {
select: function (metaData, value) {
metaData.up('grid').getSelection()[0].dirty = true;
metaData.up('grid').getSelectionModel().getSelection()[0].data.colorCode = value;
}
}
}),
listeners: {
render: function (metaData, value) {
metaData.down('colorpicker').colors = [];
metaData.down('colorpicker').value = metaData.ownerCt.context.grid.getSelectionModel().getSelection()[0].data.colorCode;
for (var i = 0; i < customColors.length; i++) {
metaData.down('colorpicker').colors.push(customColors[i]);
}
metaData.down('colorpicker').updateLayout();
}
}
}
},
],
selModel: 'rowmodel',
plugins: {
ptype: 'rowediting',
clicksToEdit: 2
},
}
]
}]
}).show();
});
I have the following column specified in my Ext.grid.Panel:
{text: 'Home Country', dataIndex: 'homeCountryId', width: 250, xtype: 'country-column'},
The xtype is "country-column" which is defined as:
Ext.define("RateManagement.view.Columns.CountryColumn", {
extend: 'Ext.grid.column.Column',
xtype: 'country-column',
text: 'Country',
editor: { xtype: 'country-combo', allowBlank: false, blankText: 'Country is required.'},
renderer: function(val) {
var locationStore = Ext.data.StoreManager.lookup('RateManagement.store.CountryStore');
var index = locationStore.findExact('value', val);
if (index != -1) {
var record = locationStore.getAt(index).data;
return record.label;
}
},
sortable: true
});
When I click the column header in the grid ("Home Country"), it doesn't sort at all.
How can I make it sort by the record.label to sort alphabetically?
Edit: Here is how I have changed my model:
{name:'homeLocationId', type: 'string'},
{name:'homeLocation', type: 'string', convert: function (newValue, model) {
// homeCountryId is appened for uniqueness and additional sort
return (newValue ? newValue : '' ) + '_' + model.get('homeLocationId');
}
},
Here is my grid column:
{text: 'Home Location', dataIndex: 'homeLocationId', width: 250, xtype: 'location-column'},
You can set label as dataIndex and attach renderer with display 'Home Country'
Here is working sample: http://jsfiddle.net/KLX5q/
// Monel
Ext.define('CountryModel', {
extend: 'Ext.data.Model',
fields: [
{ name:'homeCountryId', type:'int'},
{ name:'HomeCountryName', type:'string'},
{ name:'label', type:'string',
convert: function (newValue, model) {
// homeCountryId is appened for uniqueness and additional sort
return (newValue ? newValue : '' ) + '_' + model.get('homeCountryId');
}
}
]
});
// store
Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
fields:['homeCountryId', 'HomeCountryName', 'label'],
data:{'items':[
Ext.create('CountryModel',{ homeCountryId: 1, HomeCountryName: 'Australia', label:'nnnn' }),
Ext.create('CountryModel',{ homeCountryId: 2, HomeCountryName:'Germany', label:'bbbb' }),
Ext.create('CountryModel',{ homeCountryId: 3, HomeCountryName:'Russia', label:'aaaa' }),
Ext.create('CountryModel',{ homeCountryId: 4, HomeCountryName:'United States', label:'zzzz' })
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
// gridpanel
Ext.create('Ext.grid.Panel', {
title: 'Countries',
margin: 5,
frame: true,
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{
text: 'HomeCountryName',
dataIndex: 'label',
flex: 1,
renderer: function(value, column, record){
return record.data.HomeCountryName;
}
}
//,{ text: 'homeCountryId', dataIndex: 'homeCountryId' } // uncomment if need
//,{ text: 'display label', dataIndex: 'label' }
],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
The message window hides behind the panel when click Tab on Editable cell.
For example: double click the first phone cell, press TAB button. You can see the message box and then hide behind the grid window.
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone'],
data: {
'items': [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "1234"
}, {
'name': 'Homer',
"email": "home#simpsons.com",
"phone": "1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "1254"
}]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
var table = Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [{
text: 'Name',
dataIndex: 'name',
editor: {
xtype: 'textfield'
}
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone',
editor: {
xtype: 'numberfield',
hideTrigger: true,
validateOnChange: false
}
}],
height: 200,
width: 400,
plugins: [Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 2
})],
listeners: {
'validateedit': function () {
Ext.MessageBox.show({
icon: Ext.MessageBox.ERROR,
buttons: Ext.MessageBox.OK,
title: 'test',
msg: 'test'
});
}
}
});
tablePanel.add(table);
tablePanel.show();
});
Anyone met such problem before?
I got answer from sencha site:
I see it does not do this in 4.07, but in 4.1. I will talk with dev team.
For now, you can use defer:
Code:
listeners:{
'validateedit':function(){
Ext.MessageBox.show({
icon: Ext.MessageBox.ERROR,
buttons: Ext.MessageBox.OK,
title: 'test',
msg: 'test'
}).defer(100);
}
}