Currently, I am populating the data for my grid using XML file.
My XML file is something like this
<property>
<category>Email</category>
<name>To-address</name>
<value>abc#xyz.com</value>
</property>
<property>
<category>Email</category>
<name>From-address</name>
<value>abc#xyz.com</value>
</property>
<property>
<category>Email</category>
<name>Email-body</name>
<value>My Body</value>
</property>
<property>
<category>Email</category>
<name>Password</name>
<value>1234</value>
</property>
And I am populating my grid like this:
{
xtype: 'grid',
columns: [{
text: 'Name',
width: 100,
dataIndex: 'name'
}, {
text: 'Value',
dataIndex: 'value',
flex: 1,
getEditor: function(record) {
if (record.get('name') === 'password') {
return Ext.create('Ext.grid.CellEditor', {
field: Ext.create('Ext.form.field.Text', {
inputType: 'password'
})
})
else if (record.get('name') === 'Content') {
return Ext.create('Ext.grid.column.Action', {
width: 50,
items: [{
iconCls: 'x-fa fa-cog',
tooltip: 'Edit',
handler: function(grid, rowIndex, colIndex) {
alert('Hello World');
}
}]
});
} else {
return Ext.create('Ext.grid.CellEditor', {
field: Ext.create('Ext.form.field.Text', {})
})
},
renderer: function(value, meta, rec) {
if (record.get('name') === 'password') {
value = '***';
}
return value;
}
}
}
],
selType: 'cellmodel',
plugins: {
ptype: 'cellediting',
}
}
}
I want to add a button to the Content row as value, which will be going to pop up a window to add email body to the user on click.
This is what I tried. It is able to add a button with handler working fine, but it is hiding other grid value column data
if (record.get('name') === 'Content') {
var id = Ext.id();
Ext.defer(function() {
Ext.widget('button', {
renderTo: id,
text: 'Edit',
width: 100,
handler: function(record) {
alert("Hello world");
}
});
}, 50);
return Ext.String.format('<div id="{0}"></div>', id);
}
As a preliminary step, I want to check an alert box for the action column I am adding the content. But it is not showing up in the row.
What I am missing here to add a button to the grid row?
An editor is defined on a column, in your case, the column is of type gridcolumn (the default column type) and implicitly defined through
text: 'Value',
dataIndex: 'value',
flex: 1,
The function getEditor() of a column should return an editor component with a field derived from Ext.form.field.Base.
However, you are sometimes returning a column component from the getEditor:
getEditor: function(record){
...
else if(record.get('name') === 'Content') {
return Ext.create('Ext.grid.column.Action', {
...
This cannot work because it is the wrong component type. Also, your column has a fixed type and you cannot get a single cell of the column to behave like a different column type, except by manually overriding the renderer. I don't see a quick fix for this. You could possibly return an editor with a textfield with a trigger button inside.
However, I would recommend that you use a form for your data, which is far more suitable. In that form, you can place buttons wherever you want.
Related
I have grid with a column that has an editor configured as text field.
var grid = Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
itemId: 'gridPanel123',
store: store,
plugins: {
ptype: 'cellediting',
clicksToEdit: 1
},
columns: [{
text: 'Name',
dataIndex: 'name',
editor: {
xtype: 'textfield'
}
}]
});
Say the column looks something like this,
Clearly the value of the column is ABCDE.
Now when the user clicks on the column, the editor mode pops up something like this :
Now my question is, is there any kind of renderer that would change the content of the editor based on the value of the column.
Considering my example, column value is "ABCDE", so the editor value is also coming as "ABCDE".
But what if I want to replace all 'A' in the column with 'Z' in the editor .So the editor value for me should have been 'ZBCDE'. How is this possible in extjs?
You can do it by setting value in beforeEdit event in cell editing plugin.
cellediting: {
listeners: {
beforeEdit: function (editor, context) {
context.value = context.value.replace("A", "Z");
}
}
}
To determine which column should be replaced just add check:
if(context.column.dataIndex == 'name'){
context.value = context.value.replace("A", "Z");
}
To reverse replace try :
validateEdit: function (editor, context){
context.record.set('name', context.value.replace("Z", "A"));
context.record.commit();
}
Example on fiddle: https://fiddle.sencha.com/#view/editor&fiddle/2thq.
I have a problem for hide/remove action column Item on record condition in grid view.
let see bellow code. there is action column code I did. I want to hide delete Icon shown in image. this delete icon hide/remove on record condition.
{
xtype: 'actioncolumn',
flex: 1,
align: 'center',
scope: this,
renderer: function (n, t, rec) {
/* if (rec.get('companyId') == 23) {
console.log('Distributor Account List');
}
else {
console.log('Distributor Client user List');
} */
},
items: [
{
icon: FLEET_SERVER_URL + 'images/edit2.png',
tooltip: fleet.Language.get('_FLEET_USER_USERLIST_EDIT_'),
handler: function (grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
this.fireEvent('showUserDetails', rec);
}
},
{
xtype: 'spacer'
},
{
icon: (Ext.getStore('userStore').first().get('issuperadmin') == 1 || Ext.getStore('userStore').first().get('isadmin') == 1 || Ext.getStore('userStore').first().get('isadmin') == 3) ?
FLEET_SERVER_URL + 'images/vehicles/van-icon.png' : '', // Use a URL in the icon config
tooltip: fleet.Language.get('_FLEET_USER_USERLIST_VEHICLE_'),
handler: function (grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
this.fireEvent('assignvehicles', rec);
}
},
{
xtype: 'spacer'
},
{
icon: FLEET_SERVER_URL + 'images/del.png',
tooltip: fleet.Language.get('_FLEET_USER_USERLIST_DELETE_'),
handler: function (grid, rowIndex, colIndex) {
Me = this;
var rec = grid.getStore().getAt(rowIndex);
Ext.Msg.show({
title: fleet.Language.get('_FLEET_USER_USERLIST_REMOVETITLE_'),
msg: fleet.Language.get('_FLEET_USER_USERLIST_REMOVEMSG_'),
buttons: Ext.Msg.YESNO,
icon: Ext.Msg.QUESTION,
callback: function (button) {
if (button == fleet.Language.get('_FLEET_USER_USERLIST_YESBTN_')) {
Me.removeUser(rec);
}
}
});
}
}
]
}
There are 4 items in action column (Edit icon, spacer, spacer, and delete Icon) please see Attached image.
In above code there is Action column render event. e.g. I want to check record having company ID=23. I use this condition for testing. Main problem is that I want to hide that delete Icon on condition. Any proper solution for this?
What you want to do is not use the icon property, but you want to put the icons into the corresponding CSS in a class. E.g.
.someIcon {
background-image: path/to/icon.png no-repeat center center !important;
width:20px;
height:20px;
}
and then you can add a getClass config instead of the icon config, and provide the CSS classes as needed, e.g. if you want to switch icon on or off:
getClass: function(v, meta, rec) {
if(rec.get('companyId')==23) return 'someIcon';
else return '';
}
or, if you want to have different icons, e.g.:
getClass: function(v, meta, rec) {
if(rec.get('isImportant')) return 'redIcon';
else return 'greyIcon';
}
Please note that you have to recompile your project in Sencha Cmd if you add classes through SCSS.
Situation : My app carries out an AJAX request and the data received is displayed in the following JQgrid . listData(data) is a function that is called in success call back of this ajax request ,
data is the JSON data received from request .
buildJqGrid is a custom function that calls the .jqgrid() on a table and div html element .
buttonFormatter is my custom formatter for the column named Action
function listData(data) {
var containerName = 'datatablea3',
columnNames = ["Name",
"Email",
"Language",
"Office",
"alter email",
"Action"
],
columnModels = [{
name: 'Name',
index: 'Name',
width: '200px'
},{
name: 'Email',
index: 'Email',
width: '200px'
}, {
name: 'Language',
index: 'Language',
width: '200px'
}, {
name: 'Office',
index: 'Office',
width: '200px'
}, {
name: 'AlterEmail',
index: 'AlterEmail',
width: '200px'
}, {
name: 'action',
width: '200px',
formatter: buttonFormatter
}],
sortColumnName = 'Name',
caption = "Employees",
rowNum = 25,
pager = '#pager2a3',
grouping = false,
groupingView = {},
rowList = [25, 50, 100];
buildJqGrid(containerName, data, columnNames, columnModels,
sortColumnName, caption, rowNum, pager, grouping,
groupingView, rowList, true, 'asc');
}
Problem : When this jsp is run data is successfully displayed in the jqgrid with view button in each record , but when i click on the view button nothing happens !.
I checked in console it shows "control in formatter" but on clicking view button it doesn't show "control in click function".
i also tried using editLink formatter but still same error there ,
Can anyone please tell me why my button's onclick event is not firing ?
"click" is already a function, and therefore you override it, and nothing fires.
Try this
function buttonFormatter(cellvalue, options, rowObject)
{
console.log("control in button formatter");
return '<button onclick=\"clickFunction();\">View</button>';
}
function clickFunction()
{
console.log("control in click function");
alert("hello");
}
Simple fiddle : https://jsfiddle.net/virginieLGB/5e5LL5po/1/
try like this, I also use same functionality(JQ Grid) in my project, try HTML input type rather than the button,
When using your code, click event was firing but the whole web page is reloading.
function buttonFormatter(cellvalue, options, rowObject) {
if (rowObject.Status != "Not Started") {
console.log("Zumbaa");
var edit = "<input class='Viewbtn' type='button' value='View' onclick=\"ShowMigrationProcess(" + cellvalue + ");\" />";
return edit;
}
return '';
}
This is a follow up question that I got answered here: How can I programmatically set column filters?
I have a 188 line Ext.js view. In this view I extend Ext.grid.Panel and in this grid I have set the selModel like so ...
selModel: {
cellSelect: false, // Only support row selection.
type: 'spreadsheet' // Use the new "spreadsheet" style grid selection model.
},
On one of the columns, the Status column, I am programmatically setting the filter so that only rows that have the Status of Ready will appear when the page firsts renders. I have been doing this here in the code:
columns: [
...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
var filter = this.up('panel').down('#status').filter;
if (!filter.menu) {
filter.createMenu();
filter.menu
.down('menuitem[value="Ready"]')
.setChecked(true);
}
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
filter: 'list',
flex: 1,
},
... more columns ...
A helpful SO member pointed out that is not the most efficient place for the code that sets the filter as the code will be executed for each row in the grid.
I have tried adding an afterrender function like so ...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
filter: 'list',
flex: 1,
listeners: {
afterrender: function(value) {
Ext.Msg.alert('We have been rendered value is ' + value );
var filter = this.up('panel').down('#status').filter;
if (!filter.menu) {
filter.createMenu();
filter.menu
.down('menuitem[value="Ready"]')
.setChecked(true); //Uncaught TypeError: Cannot read property 'setChecked' of null
}
}},
... but that results in this error message, //Uncaught TypeError: Cannot read property 'setChecked' of null.
What am I doing wrong here? Do I need the listeners:? Am I not getting passed the data I think I am getting passed to my afterrender function? Should I defining a initComponent function?
UPDATE:
I changed my code to what DrakeES suggested, ...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
flex: 1,
filter: {
type: 'list',
value: 'Ready'
}
... but the result is this:
Where the animated loading image just sits there and spins. This prevents the user from be able to change the filter interactively. I wonder what it is I am doing wrong here?
I am programmatically setting the filter so that only rows that have
the Status of Ready will appear when the page firsts renders
What checking the filter's checkbox effectively does is setting filter on the store. Because you want the filter to be applied initially, it would be better to have it in the store config right away:
filters: [
{
id: 'x-gridfilter-status',
property: 'status',
value: 'Ready'
}
]
That way the grid view appear filtered in the first place — instead of initially showing all rows and only then filtering them out once the column menu renders and applies the filter. Note that having id: 'x-gridfilter-status' on the store's filter is required so that the column's filter picks it up instead of creating a duplicate.
Setting filter on the store, however, will not send feedback to the column filter menu, so the latter will remain unchecked unless you explicitly check it. Therefore, you still need an afterrender handler on either the grid or the column to make things look in sync.
A simple and elegant solution without listeners and stuff:
filter: {
type: 'list',
value: 'Ready'
}
Full working example: https://fiddle.sencha.com/#fiddle/prp
Hi I have the code below my my enter event is never triggering, any help will be appreciated.
items: [{
xtype: 'textfield',
id: 'idhere',
name: 'namehere',
fieldLabel: 'lablehere:',
width: 500,
handler: {
key:13,
fn : function () {
if (e.getKey() == e.ENTER) {
alert("You pressed an enter button in text field.");
}
}
}
},{
xtype: 'button',
text: 'texttodisplay',
handler: function() {
//my function.
}
}]
I actually solved this by using:
listeners: {
specialkey: function (f,e) {
if (e.getKey() == e.ENTER) {
loadData();
}
}
}
I am not sure why Sencha never included Ext.ux.form.SearchField in the API docs but the component has been included in all versions of the framework I've used. It is set-up to fire a submit and a cancel event and includes the appropriate search and cancel buttons attached to the field.
You can find it in your framework files at: [extjs-root]\examples\ux\form\SearchField.js
I would recommend using that component instead of trying to create your own searchfield. I usually override the default search function to fit my own needs but there have been a few scenarios where I did not need to also.
If you add a requires statement at the top of your component JS you can create it like any other (non-UX) component:
E.g:
Requires statement:
Ext.define('MyApp.view.SomeComponent', {
extend: 'Ext.grid.Panel',
alias: 'widget.mycomponent',
requires: [
'Ext.ux.form.SearchField'
],
...
Creating a search field in the panel's bottom toolbar:
bbar: {
items: [{
text: 'A Button'
}, {
text: 'Another Button'
}, '-', {
xtype: 'searchfield', // <- can use this xtype with requires stmt
itemId: 'search',
width: 250,
emptyText: 'Enter first and last name to search...'
}]
},
...
If you have trouble with the requires statement you could also just create it like this:
var search = Ext.create('Ext.ux.form.SearchField', {
itemId: 'search',
width: 250,
emptyText: 'Enter first and last name to search...'
});
Just to supply how to add such a listener. There is a specialkey event that can be used for such a case
fieldinstance.on('specialkey', function(f, e){
if (e.getKey() == e.ENTER) {
// your action
}
});
Anyway I recommend to use the ux component that #Geronimo mentioned