how to escape html entities in grid? - extjs

I have grid column:
{
header: "",
sortable: false,
id: 'value',
dataIndex: 'value',
hidden: false,
editor: {
xtype: 'textfield',
allowBlank: false
}
}
How to escape html entities only in renderer function for this column ?

The renderer property of a column definition can take either a function or the string name of one of Ext.util.Format's methods. In this case you can use the htmlEncode method by declaring the column as:
{
header: "",
sortable: false,
id: 'value',
dataIndex: 'value',
hidden: false,
editor: {
xtype: 'textfield',
allowBlank: false
},
renderer: 'htmlEncode'
}

There is a autoEncode property on the EditorGridPanel.
"True to automatically HTML encode and decode values pre and post edit (defaults to false)."
Just set it to true.
autoEncode: true

hi write this code in app.js file
//code for grid xss
Ext.override(Ext.grid.column.Column, {
defaultRenderer: Ext.util.Format.htmlEncode
});

Related

dynamic store in column grid editable

In a grid column editable (ExtJs v4.2.2), how to change the store dynamically ?
The point is to load store with different params by type of movement(movementTypeId):
the field with diffrent list to be attached is 'Reason', columns are:
this.columns = [
{
text: 'id',
dataIndex: 'movementId',
sortable: false,
hideable: true,
sortableColumn: false,
hidden: true,
flex : 1,
scope:this
},
{
text: 'TypeId',
dataIndex: 'movementTypeId',
sortable: false,
sortableColumn: false,
hideable: true,
sortableColumns: false,
hidden: true,
flex : 2,
scope:this
},
{
text: 'Reason',
dataIndex: 'movementReasonId',
sortable: false,
hideable: true,
sortableColumn: false,
field: {
xtype: 'combobox',
align: 'center',
typeAhead: true,
triggerAction: 'all',
//selectOnTab: true,
store: this.storeMovementReasonType,
displayField: 'label'
},
flex : 3,
scope:this
},
];
So for every row, when store is on load wanted to set extra param like:
if(movementTypeId === 89){
storeMovementReasonType.getProxy().setExtraParam('dictionaryTypeId',11);
}
if(movementTypeId === 94){
storeMovementReasonType.getProxy().setExtraParam('dictionaryTypeId',8);
}
is it possible ?
Thanks for your time :)
You want to implement the beforeedit listener on your rowediting plugin:
listeners:{
beforeedit:function(editor , context , eOpts) {
var movementTypeId = context.record.get("movementTypeId");
if(movementTypeId === 89){
storeMovementReasonType.getProxy().setExtraParam('dictionaryTypeId',11);
}
if(movementTypeId === 94){
storeMovementReasonType.getProxy().setExtraParam('dictionaryTypeId',8);
}
storeMovementReasonType.load();
}
}

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

Combo box in Extjs editor grid not displaying initally

I am trying to edit an information using editor grid. I have three fields, Interview By (combo), Date (date) and Performance (number), I get the date and the performance column, but the combo is not displaying the value initially. But when I click, then it shows the correct value. I am new to extjs and googled it for a solution, but could not find it. Kindly help me with a solution. Thanks in advance.
MY CODE:
initComponent: function() {
this.createTbar();
this.columns = [
{ xtype:'numbercolumn',
hidden:true,
dataIndex:'interview_id',
hideable:false
},
{ xtype: 'gridcolumn',
dataIndex: 'interview_by_employee_id',
header: 'Interview By',
sortable: true,
width: 290,
editor: {
xtype: 'combo',
store: employee_store,
displayField:'employee_first_name',
valueField: 'employee_id',
hiddenName: 'employee_first_name',
hiddenValue: 'employee_id',
mode: 'remote',
triggerAction: 'all',
forceSelection: true,
allowBlank: false ,
editable: false,
listClass : 'x-combo-list-small',
style: 'font:normal 11px tahoma, arial, helvetica, sans-serif'
},
renderer: function(val){
index = employee_store.findExact('employee_id',val);
if (index != -1){
rs = employee_store.getAt(index).data;
return rs.employee_first_name;
}
}
},
{ xtype: 'gridcolumn',
dataIndex: 'interview_date',
header: 'Date',
sortable: true,
readOnly: true,
width: 100,
editor: {
xtype: 'datefield'
}
},
{ xtype: 'numbercolumn',
header: 'Performance',
format:'0',
sortable: true,
width: 100,
align: 'right',
dataIndex: 'interview_performance',
editor: {
xtype: 'numberfield'
}
}
];
candidate_grid_interview.superclass.initComponent.call(this);
}
and the screen shots,
I faced the same problem and found my solution somewhere. Here is a reduced version of what I'm using. I think the key was the renderer property on the column. If your combo uses remote data, it might be loading its content after the grid is done loading - but I'm not sure it will cause the problem you're describing.
Try this concept:
var myStore = new Ext.data.JsonStore({
autoLoad: false,
...
fields: [
{ name: 'myID', type: 'int' },
{ name: 'myName', type: 'string' }
],
listeners: {
load: function () {
// Load my grid data.
},
scope: this
}
});
var myCombo = new Ext.form.ComboBox({
...
displayField: 'myName',
valueField: 'myID',
store: myStore
});
var grid = new Ext.grid.EditorGridPanel({
store: new Ext.data.ArrayStore({
...
fields: [
...
{ name: 'myID', type: 'int' },
...
]
}),
...
cm: new Ext.grid.ColumnModel({
columns: [
...
{
header: 'Header',
dataIndex: 'myID',
editor: myCombo,
renderer: function (value) {
var record = myCombo.findRecord(myCombo.valueField, value);
return record ? record.get(myCombo.displayField) : myCombo.valueNotFoundText;
}
}]
})
});
myStore.load();
Store loading is asynchronous, so it might be loading itself after rendering the grid. I recommend you render your grid within the store onload event. Also, datatypes can be painfull if you don't pay enough attention. Be sure that your grid store and combo store types match.

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