How to create editable grid column with few values? | Extjs - extjs

I have a grid with columns name, value, new value. New value column is combobox because there can be a few values. Admin can approve/decline new values and correct proposed these new values.
My grid columns looks like this:
columns: [
{ text: 'Name', dataIndex: 'property_name', width: 300 },
{ text: 'Value', dataIndex: 'value', width: 350 },
{
text: 'New Value',
dataIndex: 'new_value',
width: 350,
editor: { allowBlank: true },
renderer: function(value, cell, record){
return record.get('new_value') == record.get('value') ? '' : record.get('new_value');
}
},
],
So is there a way to achive functionality a described above?

The editor configuration takes any Ext.form.Field configuration (default is textfield), so for example:
editor:{
xtype:'combobox', // <- this tells
store:'MyNewValueStore',
forceSelection:true,
queryMode:'local',
...
}

Related

ExtJS 6 -- autofit grid column header text

Is there a way I can set the columns width to match the width of the column text? The user can resize the columns to see the content if needed, but I want the full header text to be showing at least, even if the column content isnt.
thanks
Yes it should be possible. You can call the method autoSize() on the column.
You can combine it with the minWidth and maxWidth.
I have found this example on the Sencha forums for Ext 4.2 so it should be very similar for Ext 6.2:
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{ text: 'Name', dataIndex: 'name', width: 150, autoSizeColumn: true },
{ text: 'Email', dataIndex: 'email', width: 150, autoSizeColumn: true, minWidth: 150 },
{ text: 'Phone', dataIndex: 'phone', width: 150 }
],
viewConfig: {
listeners: {
refresh: function(dataview) {
Ext.each(dataview.panel.columns, function(column) {
if (column.autoSizeColumn === true)
column.autoSize();
})
}
}
},
width: 450,
renderTo: Ext.getBody()
});

How to get value of other column in renderer function in Extjs?

I want to get the value of another column in the same row, in a renderer function of one column. I tried a method, but it didn't work. And here's my code:
columns: [
{id:'id',header: 'ID', width: 30, sortable: true, dataIndex: 'category_id'},
{header: 'current_level', width: 100, sortable: true, dataIndex: 'current_level'},
{header: 'complete_code', width: 100, sortable: true, dataIndex: 'complete_code'},
{header: 'parent_id', width: 100, sortable: true, dataIndex: 'parent_id'},
{header: 'parent_name', width: 100, sortable: true, dataIndex: 'parent_name'},
{
header: 'has_standards', width: 100, sortable: true, dataIndex: 'has_standards',
renderer: function(val, meta, record, rowIndex) {
if (val == 'Yes') {
console.log(record.data.category_id);
}
}
}
],
As you see, I want to get the category_id in the same row, in the renderer function of has_standards column. But my way is wrong. Could you tell me how to do it?
You want to use record.get('category_id') e.g.:
renderer: function(val, meta, record, rowIndex) {
if (val === 'Yes') {
console.log(record.get('category_id'));
}else{
console.log('Value is not "Yes"');
}
}
I am using Ext JS 6 (Sencha) and I wanted to display an image in a grid column based on whether the value of another column in the same grid was of a certain value. I followed SW4's solution with some minor changes as per the version of Ext JS I am using and it worked great. Thank you.
Ext.define('ViewLL.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'list',
requires: ['App.store.Datastore'],
store: {type: 'datastore'},
columns: [
{ text: 'Market',
renderer: function(value, metaData, record, rowIndex) {
var value = record.get('location');
if (value == NYC) {
return '<img src="resources/images/bigApple.jpg"/>';
}
else {
return null;
}
}
},
{ text: 'City', dataIndex: 'location' }
]
This displays the image file in a grid column when the City column's has a record, the value of which is NYC. For all other records it displays a blank cell.

How to achieve Live Search/Filtering on Multiple Fields in the Grid using Ext.Js?

I have done live search on grid. it is searching based on which column i mentioned filter code. But i need to filter grid records based on multiple column search. In below code only searches name column because mentioned only the name filed in filter code. I am not getting how to achieve multiple column value search? Can any one tell me how to achieve? great appreciated. Thank you .
Grid Code Here:
{
xtype: 'gridpanel',
flex: 2,
hidden: false,
store: store,
loadMask: true,
id: 'grid',
columns: [
{id:'id',header: 'ID', width: 100, sortable: true, dataIndex: 'id'},
{header: 'Name', width: 150, dataIndex: 'name'},
{header: 'Position', width: 150, dataIndex: 'position'},
{header: 'Ambition', width: 250, dataIndex: 'ambition'}
],
stripeRows: true,
title:'Straw Hats Crew',
},
liveSearch text change even Here:
onTextFieldChange: function(field, newValue, oldValue, options){
var grid = Ext.getCmp('grid');
if(newValue==''){
grid.store.clearFilter();
}
else {
grid.store.clearFilter();
grid.store.load().filter([
{id: 'name', property: "name", value: newValue, anyMatch: true}
]);
}
},
Something like this should work. You can specify an arbitrary filter function that can check all the fields in your model.
onTextFieldChange: function(field, newValue, oldValue, options){
var grid = Ext.getCmp('grid');
grid.store.clearFilter();
if (newValue) {
var matcher = new RegExp(Ext.String.escapeRegex(newValue), "i");
grid.store.filter({
filterFn: function(record) {
return matcher.test(record.get('id')) ||
matcher.test(record.get('name')) ||
matcher.test(record.get('position')) ||
matcher.test(record.get('ambition'));
}
});
}
}

In ExtJs 3.3.1, how can I show a ComboBox drop down without click in EditorGrid?

I am using ExtJs 3.3.1.
Within an EditorGrid, my "editable" column has a ComboBox as its editor. How can I have the ComboBox always showing for each row? Meaning, the user would not have to click on a cell to know there is a ComboBox there. Currently, I have clicksToEdit set to 1, but I wish I could set this to 0 (I tried that).
See some of my code below to see my current configuration.
var combo = new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',
lazyRender: true,
mode: 'local',
store: new Ext.data.ArrayStore({
id: 0,
fields: [
'statusId',
'displayText'],
data: data
}),
valueField: 'statusId',
displayField: 'displayText'
});
var cm = new Ext.grid.ColumnModel({
columns: [{
id: 'orderId',
header: 'ID',
dataIndex: 'id',
width: 50
}, {
header: 'Status',
dataIndex: 'status',
width: 130,
editor: (data.length == 1) ? null : combo,
renderer: Ext.util.Format.comboRenderer(combo)
}, {
id: 'orderSummary',
header: 'Summary',
dataIndex: 'summary',
renderer: this.renderSummary
}]
});
var orderGrid = new Ext.grid.EditorGridPanel({
store: this.getOrderStore(),
cm: cm,
autoExpandColumn: 'orderSummary',
clicksToEdit: 1
});
Here is the solution I came up with.
In my column model, I made sure that the column I am making "editable" has an id. Each cell in that column will now have a CSS class associated with it named "x-grid-col-{id}". My column id is "status" so the class was "x-grid-col-status".
I created the CSS for class "x-grid-col-status" which sets the dropdown arrow image as the background, aligned right. It also sets the cursor to pointer, so the user knows they can click on the cell.
.x-grid3-col-status
{
background-image: url(Image/trigger-single.gif);
background-position: right;
background-repeat: no-repeat;
cursor: pointer;
}
Next, I set up a listener for my ComboBox that listens for the 'focus' event. On focus, I expand the drop down. It is important that I had to add lazyInit: false to my ComboBox config, or else an empty list will appear when you expand. lazyInit - true to not initialize the list for this combo until the field is focused (defaults to true)
The code:
Ext.util.Format.comboRenderer = function (combo) {
return function (value, metaData, record, rowIndex, colIndex, store) {
var record = combo.findRecord(combo.valueField, value);
return record ? record.get(combo.displayField) : combo.valueNotFoundText;
}
}
var combo = new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',
lazyInit: false,
lazyRender: true,
mode: 'local',
editable: false,
store: new Ext.data.ArrayStore({
id: 0,
fields: [
'statusId',
'displayText'
],
data: data
}),
valueField: 'statusId',
displayField: 'displayText',
listeners: {
'focus': {
fn: function (comboField) {
comboField.doQuery(comboField.allQuery, true);
comboField.expand();
}
, scope: this
}
, 'select': {
fn: function (comboField, record, index) {
comboField.fireEvent('blur');
}
, scope: this
}
}
});
var cm = new Ext.grid.ColumnModel({
defaults: {
sortable: true
},
columns: [
{
id: 'orderId',
header: 'ID',
dataIndex: 'id',
width: 50
}, {
header: 'Status',
id: 'status',
dataIndex: 'status',
width: comboColumnWidth,
editor: combo,
renderer: Ext.util.Format.comboRenderer(combo)
}, {
id: 'orderSummary',
header: 'Summary',
dataIndex: 'summary',
renderer: this.renderSummary
}
]
});
var orderGrid = new Ext.grid.EditorGridPanel({
store: this.getOrderStore(),
cm: cm,
autoExpandColumn: 'orderSummary',
title: title,
clicksToEdit: 1
});
I think you'll need to add a special css to the combo box that displays the drop down icon. This is natively not supported by Ext JS. Here's an example of how it can be done:
var companyColumn = {
header: 'Company Name',
dataIndex: 'company',
renderer: function(value, metaData, record, rowIndex, colIndex, store) {
// provide the logic depending on business rules
// name of your own choosing to manipulate the cell depending upon
// the data in the underlying Record object.
if (value == 'whatever') {
//metaData.css : String : A CSS class name to add to the TD element of the cell.
//metaData.attr : String : An html attribute definition string to apply to
// the data container element within the table
// cell (e.g. 'style="color:red;"').
metaData.css = 'name-of-css-class-you-will-define';
}
return value;
}
}
Or you could use the Ext.grid.TemplateColumn and specify the tpl config. This will automatically generate a renderer for the cells in the column and apply the tpl.

extjs apply formatting to grid column

In extjs, if I have a grid definition like this:
xtype: 'grid',
store: 'someStore',
flex: 1,
frame: true,
loadMask: true,
titleCollapse: true,
cls: 'vline-on',
ref: '../someGrid',
id: 'someGrid',
columns: [
{
xtype: 'gridcolumn',
header: 'ID',
dataIndex: 'someID',
sortable: true,
width: 100
}
Is there a way to apply some formatting to this column? For example, this field is a number and if i wish to set a decimal precision..can I do it? Or do I need to apply formatting when the store is being loaded in my java file?
My guess is the latter??
Use "renderer" option. You can define you function there. For example i want to show someID wrapped in some tag:
columns: [
{
xtype: 'gridcolumn',
header: 'ID',
dataIndex: 'someID',
sortable: true,
width: 100,
renderer: function(value) {
// your logic here
return "<b>" + value + "</b>";
}
}
If you want to show decimal precision inside a grid column you should define the dataindex in your store of "float" type:
...
, {name: 'column_data_name', type: 'float'}
...
Then inside the grid column definition you should specify a renderer, as suggested by KomarSerjio, and use it.
function floatRenderer(value) {
if (value) {
var val = value.toFixed(2);
return addSeparatorsNF(val, '.', ',', '.');
}
else return "";
}
...
, { id:'column_data_name', header: 'label', dataIndex: 'column_data_name' , renderer: floatRenderer , align: 'right' }
...
The function addSeparatorsNF has been suggested here.
For formatting your grid decimal value to restrict after point to two number or till you want simply use below code to your column :
renderer: Ext.util.Format.numberRenderer('00.00')
I tried the renderer config KomarSerjio suggested and it worked brilliantly for me when using Sencha Ext JS 6. I used it to zero fill some time data I was receiving which was missing the prefix zero to make it a 24 hour time. So I tried the following and it worked great! Thank you.
Ext.define('ViewLL.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'mainlist',
reference: 'mainList',
flex: 1,
requires: [
'ViewLL.store.Datastore'
],
title: 'Records',
store: {
type: 'datastore'
},
columns:
{ text:'Pln On Site Time',
dataIndex:'plnOnSiteTime',
renderer: function (number) {
if (number<=2400) { number = ("000"+number).slice(-4); }
return number;
}
}
});
Prior to renderer config my grid was displaying values e.g. 926, 800, 1000.
Post adding function via renderer config my grid displayed values e.g. 0926, 0800, 1000

Resources