ExtJS 4 cell "renderer" problem - extjs

After reading this article, I've managed to change rendering.
I'm calling an internal function:
renderer: this.onRenderCell
And this function is like this:
onRenderCell: function(value, metaData, record, rowIndex,
colIndex, store, view) {
metaData.css = 'ini-cell-pas-traduit';
return '«'+value+'»';
}
If you read carefully I return '«'+value+'»'; so for each value it is transformed to: '«value»'; . This is a proof that on every single line, it works perfectly. So should it be for the css. But the css is applied one time out of two!! This drives me nuts.
Here's what it gives (latest Firefox, same with latest Chrome):
Any idea where I should take a look?
Here's a big sample of my source code:
Ext.define('Lang.grid.Panel', {
extend: 'Ext.grid.Panel',
alias: 'widget.langgrid',
requires: [
'Ext.grid.plugin.CellEditing',
'Ext.form.field.Text',
'Ext.toolbar.TextItem'
],
initComponent: function(){
this.editing = Ext.create('Ext.grid.plugin.CellEditing');
Ext.apply(this, {
iconCls: 'icon-grid',
plugins: [this.editing],
dockedItems: [{
xtype: 'toolbar',
items: [{
iconCls: 'icon-add',
text: 'Add',
scope: this,
handler: this.onAddClick
}, {
iconCls: 'icon-delete',
text: 'Delete',
disabled: true,
itemId: 'delete',
scope: this,
handler: this.onDeleteClick
}]
}],
columns: [{
text: 'label',
flex:2,
sortable: true,
dataIndex: 'label'
},{
header: 'fr',
flex: 3,
sortable: true,
dataIndex: 'fr',
renderer: this.onRenderCell,
field: {
type: 'textfield'
}
},{
header: 'es',
flex: 3,
sortable: true,
dataIndex: 'es',
renderer: this.onRenderCell,
field: {
type: 'textfield'
}
},{
header: 'us',
flex: 3,
sortable: true,
dataIndex: 'us',
renderer: this.onRenderCell,
field: {
type: 'textfield'
}
}
]
});
this.callParent();
this.getSelectionModel().on('selectionchange', this.onSelectChange, this);
},
(...)
(snip useless code)
(...)
onRenderCell: function(value, metaData, record, rowIndex,
colIndex, store, view) {
metaData.css = 'ini-cell-pas-traduit';
return '<span style="color:red; font-weight:bold;">«'+
value+'»</span>';
}
});

In the metadata.css (ini-cell-pas-traduit) do this for background-color
background-color : red !important //or whichever color you've specified.
EDIT :
This is happening because the grid is configured with stripeRows : true. I dunno if this is done by default or you did it in the config but forgot to mention it here. When you use stripeRows it sets a background-color which can be overriden using the !important keyword.

Varun Achar is right about using !important, but since you are using Ext JS 4 you should also change
metaData.css = 'ini-cell-pas-traduit';
to
metaData.tdCls = 'ini-cell-pas-traduit';
The 'css' and 'attr' members of metaData have now been replaced with tdCls and tdAttr and the old ones will only work in Ext JS 4 if you also install the Ext 3 compatibility layer.

Related

Getting Error as getEditor undefined

I'm trying to get the value of a cell in a grid using below. In-fact I'm just trying to print it in the console
console.log(Ext.ComponentQuery.query('gridcolumn[itemId=gridId]')[0].getEditor().getStore().findRecord('description', 'Description'));
Grid Code
Ext.define('Examples.grid.fdGrid', {
extend: 'Ext.grid.Panel',
xtype: foodGrid',
forceNewStore: true,
itemId: 'foodGrid',
height: Ext.getBody().getViewSize().height - 200,
autoload: false,
columns: [
{
text: 'Food Distrib',
xtype: 'gridcolumn',
itemId:'gridId',
dataIndex: 'food_distributor',
flex: 1,
renderer: function(value){
if(Ext.isNumber(value)){
var store = this.getEditor().getStore();
return store.findRecord('foodid',value).get('description');
}
return value;
},
editor: {
xtype: 'combobox',
allowBlank: true,
displayField: "description",
valueField: "foodid",
listeners: {
expand: function () {
var call = this.up('foodgrid[itemId=foodGrid]').getSelectionModel().selection.record.data.networkname.trim();
this.store.clearFilter();
this.store.filter({
property: 'call',
value: call,
exactMatch: true
})
}
},
},
}
});
But i'm getting an error as Uncaught TypeError: Cannot read property 'getEditor' of undefined
What's the error please?
Added the Grid Code part, and the column whose value I want to print.
The editor is created when needed (when the first edit occurs). So when the renderer is first called, the editor is not yet available.
What you want to do from inside your renderer, is to directly access the store, not go through the editor. Then you only need a pre-loaded store to be able to render the grid correctly.
renderer: function(value){
if(Ext.isNumber(value)){
var store =Ext.getStore("MyStore");
return store.findRecord('foodid',value).get('description');
}
return value;
},
editor: {
xtype:'combobox',
store:'MyStore'
Of course, you have to make sure that MyStore is loaded before you render the grid.
One can only guess what you are trying to do there but:
Column doesn't have a selection model of itself. Grid does.
Combobox needs a store.
getEditor may return String OR Object if an editor was set and column is editable
editable is provided by a grid plugin. In other words, specifying a column as being editable and specifying a column editor will not be enough, you also need to provide the grid with the editable plugin.
Some working example:
Ext.define('Examples.grid.fdGrid', {
extend: 'Ext.grid.Panel',
xtype: 'feedGrid',
forceNewStore: true,
itemId: 'foodGrid',
height: Ext.getBody().getViewSize().height - 200,
autoload: false,
selModel: 'cellmodel',
plugins: {
ptype: 'cellediting',
clicksToEdit: 1
},
columns: [
{
text: 'Food Distrib',
xtype: 'gridcolumn',
itemId:'gridId',
dataIndex: 'food_distributor',
flex: 1,
editable: true,
renderer: function(value){
if(Ext.isNumber(value)){
var store = this.getEditor().getStore();
return store.findRecord('foodid',value).get('description');
}
return value;
},
editor: {
xtype: 'combobox',
allowBlank: true,
displayField: "description",
valueField: "foodid",
store: {
fields:['food_distributor', 'description'],
data:[
{
'food_distributor':'a',
foodid:1,
description:'aaaaa'
},
{
'food_distributor':'a',
foodid:2,
description:'bbbbbb'
},
{
'food_distributor':'a',
foodid:3,
description:'aaaaa'
}]
},
listeners: {
expand: function () {
debugger;
var desc = this.up('grid').getSelectionModel().getSelection()[0].get('description').trim();
this.store.clearFilter();
this.store.filter({
property: 'description',
value: desc,
exactMatch: true
})
}
},
},
}
]
});
Ext.create('Examples.grid.fdGrid', {
store: {
fields:['food_distributor', 'description'],
data:[
{
'food_distributor':'a',
foodid:1,
description:'aaaaa'
},
{
'food_distributor':'a',
foodid:2,
description:'bbbbbb'
},
{
'food_distributor':'a',
foodid:3,
description:'aaaaa'
}]
},
renderTo:Ext.getBody()
})
Do you have
var cellEditing = Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
});
Without the plugin the editor doesnt work! and the editor will be undefined when you will try to obtain it

EXT JS Grid - Auto-increment rendered inputs

I have an EXT JS 4.2 Grid that has 2 columns that use the renderer to place checkboxes in 1 column and radio buttons in another. How can I auto increment the ID's on these HTML inputs so that I can specifically target them via EXT JS (see columns 'Full' and 'Primary')
// Render library grid
var grid4 = Ext.create('Ext.grid.Panel', {
xtype: 'gridpanel',
id:'button-grid',
store: data,
columns: [
{text: "Library", width: 170, sortable: true, dataIndex: 'name'},
{text: "Market", width: 125, sortable: true, dataIndex: 'market'},
{text: "Expertise", width: 125, sortable: true, dataIndex: 'expertise'},
{text: 'Full', dataIndex:'isFull', renderer: function() {
var rec = grid4.getStore().getAt(this.rowIndex);
return "<input type='checkbox' id='"+rec+"' />";
}},
{text: 'Primary', dataIndex:'isPrimary', renderer: function() {
return "<input type='radio' />";
}},
],
columnLines: false,
selModel: selModel,
// inline buttons
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
ui: 'footer',
layout: {
pack: 'center'
},
items: []
}, {
xtype: 'toolbar',
items: []
}],
width: 600,
height: 300,
frame: true,
title: 'Available Libraries',
iconCls: 'icon-grid',
renderTo: Ext.get('library-grid')
});
UPDATE:
The ID's are now incrementing, thank you!
Now, I have one other question:
I am not seeing the checked:checked flag being set when I check an item in the EXT grid, how would I do something like the code below. I want to check to see if the element is checked
if(document.getElementById("#isFull-"+record['index']+"").checked == true){
var myVar = true;
}
The renderer takes a bunch of arguments automatically, one of which is the rowIndex. You should be able to do this to give the unique ID you want:
{
text: 'Full',
dataIndex:'isFull',
renderer: function(value, meta, record, rowIndex, colIndex)
{
return '<input type="checkbox" id="isFull-' + rowIndex + '" />';
}
}
See more here: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.grid.column.Column-cfg-renderer

Sencha ExtJs Grid refresh after saving store

I have an ExtJS grid with a toolbar button to save the date. The save works and the data is stored. But the grid is not refreshed. How do I reload the grid data after the save?
Ext.define('MyLodge.view.content.MemberGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.membergrid',
initComponent: function(){
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing');
var store = Ext.create('MyLodge.store.Members');
Ext.apply(this, {
height: this.height,
plugins: [rowEditing],
store: store,
stripeRows: true,
columnLines: true,
columns: [{
id :'id',
text: 'ID',
width: 40,
sortable: true,
dataIndex: 'id'
},{
text : 'Name',
flex: 1,
sortable : true,
dataIndex: 'name',
field: {
xtype: 'textfield'
}
},{
text : 'E-Mail',
width : 150,
sortable : true,
dataIndex: 'email',
field: {
xtype: 'textfield'
}
},{
text : 'Href',
width : 200,
sortable : true,
dataIndex: 'href',
field: {
xtype: 'textfield'
}
}],
dockedItems: [{
xtype: 'toolbar',
items: [{
text: 'Add',
iconCls: 'icon-add',
handler: function(){
// empty record
store.insert(0, new MyLodge.model.Member());
rowEditing.startEdit(0, 0);
}
}, {
text: 'Delete',
iconCls: 'icon-delete',
handler: function(){
var selection = grid.getView().getSelectionModel().getSelection()[0];
if (selection) {
store.remove(selection);
}
}
},'-',{
text: 'Save',
iconCls: 'icon-save',
handler: function(){
store.sync();
}
}]
}]
});
this.callParent(arguments);
}
});
You can load store in callback of sync
store.sync({
success: function( response ) {
store.load();
}
});
You will probably want to call store.reload() in a callback from store.save() (what is store.save() anyway? it is not part of Ext.data.Store interface)

How to activate listeners in renderer function in a grid column

I am using extjs 4 and I have a grid which shows a field name Approval. Here I have showed checkbox that will be checked when the grid is loaded if the value is true. But if the dataIndex value is fault only the checkbox will appear. Now I want that if I click on unchecked checkbox it will do a action using listeners. But I am not being able to do it. Can anyone please help me on this ? My codes are given below :
{
text: 'Approval',
dataIndex: 'approve',
flex: 1,
align: 'left',
renderer: function(value, metaData, record, row, col, store, gridView){
if(value == true)
{
return '<input type="checkbox" checked="true" />';
}else{
return '<input type = "checkbox" />';
listeners: {
this.approve();
}
}
}
}
approve: function(){
alert('hi');
}
Old answer
The checkbox has a change listener which will get fired after the value has changed.
{
xtype : 'checkbox'
boxLabel : 'This is my checkbox',
name : 'mycheckbox',
inputValue: true,
listeners : {
change: function(cbx, newValue, oldValue){
me.approve();
}
}
}
Note that you can't use this inside the listener because the function gets called inside another scope.
Edit:
Start using a Ext.ux.CheckColumn on your grid.
Now you can use:
{
xtype: 'checkcolumn',
text: 'Approval',
dataIndex: 'approve',
flex: 1,
align: 'left',
sortable: false,
listeners:{
checkchange:function(cc,ix,isChecked){
alert(isChecked);
}
}
}
What you are trying to archive is not possible out of the box.
I guess you want to display the checkbox all the time? Otherwise the CellEditor Plugin is already what you are looking for.
But it should anyway the point to start (I guess). Here is a example code the uses ExtJS classes & images to display a sort of fake combo in a cell along with a celleditior. There is one think you still have to fix; you need to override the cellcontent before the edits starts cause the celleditor seems to remove only default types.
Way going this way? Of course you could modify the checkbox with a unique id and fetch the Ext.Element for it which would now enable you to register events. But that approach has one downside, you need to care about render time otherwise your combos does not exist when you are trying to fetch it. Therefore I recommend you this approach. It you be quite easy to wipe the image before the rendering starts.
Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
fields:['name', 'email', 'phone'],
data:{'items':[
{"name":"Lisa", "email":"lisa#simpsons.com", "phone":true},
{"name":"Bart", "email":"bart#simpsons.com", "phone":false},
{"name":"Homer", "email":"home#simpsons.com", "phone":true},
{"name":"Marge", "email":"marge#simpsons.com", "phone":true}
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{header: 'Name', dataIndex: 'name', editor: 'textfield'},
{header: 'Email', dataIndex: 'email', flex:1},
{header: 'Phone', dataIndex: 'phone',
editor: { xtype: 'checkbox', inputValue: 'true', uncheckedValue: 'false' }, renderer: function(value){
return value ? '<span class="x-form-cb-checked"><div class="x-form-checkbox"></div></span>' : '<div class="x-form-checkbox"></div>';
}
}
],
selType: 'cellmodel',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
Here's the JSFiddle

order of rows with drag and drop in extjs grid

I am using the drag and drop function in a grid like this:
{
xtype: 'gridpanel',
id: 'editlinesGrid',
title: 'line',
forceFit: true,
store: 'gridEditlines',
region: 'center',
viewConfig: {
plugins: [
Ext.create('Ext.grid.plugin.DragDrop', {
ptype: 'gridviewdragdrop'
})],
listeners: {
drop: {
fn: me.onGriddragdroppluginDrop,
scope: me
}
}
},
columns: [{
xtype: 'rownumberer',
dataIndex: 'stopOrder'
}, {
xtype: 'gridcolumn',
dataIndex: 'stopId',
text: 'stopId',
field: {
xtype: 'combobox',
allowBlank: false,
displayField: 'stopId',
store: 'gridStops'
}
},
When i drag the row to a higher or lower position i need to send the new position to the service. What i need to send is this:
{
"stopOrder": 1, <-- here should be the new position in the grid
"stopDTO": {
"stopId" : 1
}
}
this is the eventbinding i use for the drag and drop
onGriddragdroppluginDrop: function(node, data, overModel, dropPosition, options) {
alert(data);
},
What do i need to do to send the data back to the service?
As far as question is not answered, and me also spend some time to 'find' it, this is link to main sencha doc Reorder grid rows using DnD

Resources