I have a grid with some data (users list). For each row I have many actions such as update, delete, activate, suspend, view orders you name it.
Instead of placing so many buttons which will fill more than 400-500 pixels I want to place a combobox with an action applied to each field.
The problem is that I can't simply render a combobox in a column row just like that or I'm missing something? Can someone shed some light on this please?
new Ext.grid.GridPanel({
region: 'center',
id: 'usersGrid',
store: store,
stripeRows: true,
autoExpandColumn: 'username',
columns: [{
// username
},{
// email
},{
// last seen
},{
// actions combo, it won't show
header: '',
width: 220,
fixed: true,
hideable: false,
dataIndex: 'actions',
renderer: new Ext.form.ComboBox({
store: new Ext.data.SimpleStore({
id: 0,
fields: ['abbr', 'action'],
data: [
['suspend', 'Suspend'],
['activate', 'Activate'],
['update', 'Update'],
['delete', 'Delete']
]
}),
displayField: 'action',
valueField: 'abbr',
mode: 'local',
typeAhead: false,
triggerAction: 'all',
lazyRender: true,
emptyText: 'Select action'
})
}
]
});
Convert Grid to Editable Grid
Add editor config in columns instead of 'renderer'. Find below the altered code.
new Ext.grid.EditorGridPanel({
region: 'center',
id: 'usersGrid',
store: store,
stripeRows: true,
autoExpandColumn: 'username',
columns: [{
// username
}, {
// email
}, {
// last seen
}, {
// actions combo, it won't show
header: '',
width: 220,
fixed: true,
hideable: false,
dataIndex: 'actions',
editor: {
xtype: 'combo',
store: new Ext.data.ArrayStore({
fields: ['abbr', 'action'],
data: [
['suspend', 'Suspend'],
['activate', 'Activate'],
['update', 'Update'],
['delete', 'Delete']
]
}),
displayField: 'action',
valueField: 'abbr',
mode: 'local',
typeAhead: false,
triggerAction: 'all',
lazyRender: true,
emptyText: 'Select action'
}
}]
});
You are attempt to accomplish this is mostly correct. The way that you are adding the custom editor might need some tweaking.. Have you tried this change?
editor: new Ext.form.ComboBox({
store: new Ext.data.SimpleStore({
id: 0,
I'm unfortunately unable to determine what your code is doing and not working.
What version of ExtJS are you using? One thing of note that I'm finding is that I don't see any object called Ext.data.SimpleStore in the current ExtJS API docs. Have you tried using a different type of data store instead? You might want to try using different type of store for this combo?
Related
I have an extjs combobox whose queryMode is set to remote.
I also want the typeAhead feature in it. But typeahead doenst work in this case.
The store reloads to the original data even after typing some text in the combobox.
Here is my code:
var queryStore = Ext.create('Ext.data.Store', {
//autoLoad: true,
model: 'UserQuery',
proxy: {
type: 'ajax',
url: 'queryBuilder_getQueryList',
extraParams: {
tableId: this.title
},
reader: {
type: 'json'
}
},
listeners: {
load: function () {
var combo = Ext.getCmp('cmbQueryList');
var lst = this.last();
if (lst)combo.setValue(lst.data);
}
}
});
var queryCombo = new Ext.form.ComboBox({
width: 200,
id: 'cmbQueryList',
store: queryStore,
valueField: 'queryID',
displayField: 'queryName',
typeAhead: true,
forceSelection: true,
emptyText: 'Select Query...',
queryMode: 'remote',
triggerAction: 'query',
selectOnFocus: true,
allowBlank: false,
editable: true
});
Please suggest how do I get typeAhead and querymode remote to work together.
this code corking for me .I guess your store property autoload is true so when you going to select the combobox its going to server and reload the data. please remove the property of store auto load true. Then its working.
new Ext.form.ComboBox({
fieldLabel:'Apps',
displayField: 'name',
valueField: 'id',
typeAhead: true,
listWidth : 345,
store: myStore(),
forceSelection: true,
triggerAction: 'all',
mode:'remote',
maxLength: 50,
editable: false,
anchor : '90%',
selectOnFocus:true
}),
This following code worked at me. We have to specific the both mode and queryMode to local.
var queryCombo = new Ext.form.ComboBox({
width: 200,
id: 'cmbQueryList',
store: queryStore,
valueField: 'queryID',
displayField: 'queryName',
emptyText: 'Select Query...',
queryMode: 'local',
mode: 'local'
});
I have a combobox in a form:
{
xtype: 'combobox',
fieldLabel: 'Jurisdictions',
name: 'jurisdiction_id',
id: 'ComboboxJurisdictions',
store: Ext.create('App.store.Jurisdictions'),
queryMode: 'local',
editable: false,
displayField: 'name',
valueField: 'id',
}
Data is:
1 => Administrator
2 => User
3 => Guest
Now, if I don't touch anything when editing a user, on my server for my combobox I get "Administrator" (displayField), but when I change something in combobox I get the "id" (valueField). I really just want "id" in both cases. I was reading about hiddenName? Is that the case?
If you need any more code, feel free to ask. :)
Thank you!
EDIT (more code)
1.) There is no default value.
Here is the whole view code:
Ext.define('App.view.Suits.Update', {
extend: 'Ext.window.Window',
title: 'Suits',
width: 250,
id: 'UpdateWindowSuits',
defaultType: 'textfield',
items: [{
xtype: 'UpdateFormSuits'
}],
buttons: [
{ text: 'Save', id: 'submitUpdateFormButtonSuits'},
{ text: 'Cancel', id: 'cancelUpdateFormButtonSuits'},
]
});
Ext.define('App.view.Suits.UpdateForm', {
extend: 'Ext.form.Panel',
alias: 'widget.UpdateFormSuits',
layout: 'form',
id: 'UpdateFormSuits',
bodyPadding: 5,
defaultType: 'textfield',
items: [{
fieldLabel: 'Id',
name: 'id',
hidden: true
},{
fieldLabel: 'Name',
name: 'name',
allowBlank: false,
},{
fieldLabel: 'Status',
name: 'status',
allowBlank: false
},{
xtype: 'combobox',
fieldLabel: 'Priority',
name: 'suit_priority_id',
id: 'ComboboxSuitPriorities',
store: Ext.create('App.store.SuitPriorities'),
editable: false,
displayField: 'name',
hiddenName: 'id',
valueField: 'id'
},{
xtype: 'combobox',
fieldLabel: 'Jurisdictions',
name: 'jurisdiction_id',
id: 'ComboboxJurisdictions',
store: Ext.create('App.store.Jurisdictions'),
queryMode: 'local',
editable: false,
displayField: 'name',
valueField: 'id',
}],
});
Here is the store:
Ext.define('App.store.SuitPriorities', {
extend: 'Ext.data.Store',
// Where is the Model.
model: 'App.model.SuitPriority',
// "id" of the Store.
storeId: 'SuitPriorities',
// Autoload all data on creation.
autoLoad: true,
// Number of records in one page (for pagination).
pagesize: 20,
// Proxy for CRUD.
proxy: {
// Type of request.
type: 'ajax',
// API for CRUD.
api: {
create : 'php/suitpriorities/update',
read : 'php/suitpriorities/read',
update : 'php/suitpriorities/update',
destroy : 'php/suitpriorities/delete'
},
// Type of methods.
actionMethods: {
create : 'POST',
read : 'POST',
update : 'POST',
destroy : 'POST'
},
// Reader.
reader: {
// Which type will the reader read.
type: 'json',
// Root of the data.
root: 'suitpriorities',
rootProperty: 'data',
// One record.
record: 'SuitPriority',
// Message and success property.
successProperty: 'success',
messageProperty: 'message'
},
// Writer (when sending data).
writer: {
type: 'json',
writeAllFields: true,
root: 'data',
encode: true
},
});
As I sad, the store is getting all the data because it's already loaded when I press the combobox. It's a simple JSON with 'id' and 'name' properties.
EDIT2: I've tried this for my Jurisdictions because I wasn't getting the right data selected in combobox. This is inside my controller.
onJurisdictionComboRender: function(combobox, eOpts){
// Getting the selected row.
var record = this.grid.getSelectionModel().getSelection()[0];
// Selected jurisdiction.
var jurisdiction = record.data.jurisdiction_id;
// Select it in combobox.
combobox.select(jurisdiction);
}
That doesn't make sense... If you read out the combo the correct way, meaning let either the form doing the work or calling getSubmitValue() on your own the combo would always returning the valueField. hiddenName is used for other purposes. Please take a look at the console of this JSFiddle and recheck how you fetch the combo value.
Here's the working demo-code
// The data store containing the list of states
var roles = Ext.create('Ext.data.Store', {
fields: ['id', 'name'],
data : [
{"id":1, "name":"Administrator"},
{"id":2, "name":"User"},
{"id":3, "name":"Guest"}
//...
]
});
// Create the combo box, attached to the states data store
var combo = Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose Role',
store: roles,
queryMode: 'local',
editable: false,
displayField: 'name',
valueField: 'id',
renderTo: Ext.getBody()
});
combo.on('select', function(cb){ console.log(cb.getSubmitValue()); })
+1 for everyone for helping but the problems was here:
In my store I've put autoLoad: false and inside my combobox I've put store.load() manually and it works perfectly.
Thank you all! :)
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.
This is my combobox
{
xtype: 'combo',
fieldLabel: LANG.LOGIN_LANG,
id : 'lang',
store: [
['tr','Türkçe'],
['ru','Русский'],
['en','English']
],
mode: 'local',
triggerAction: 'all',
selectOnFocus:true
},
Generally, when I want to select the first value of a store, I use this methods:
xtype: 'combo',
fieldLabel: 'prov',
id : 'lang',
store:[['tr','Türkçe'],['ru','Русский'],['en','English']],
mode: 'local',
triggerAction: 'all',
selectOnFocus:true,
listeners: {
afterrender: function(combo) {
var recordSelected = combo.getStore().getAt(0);
combo.setValue(recordSelected.get('field1'));
}
}
{
xtype: 'combo',
fieldLabel: LANG.LOGIN_LANG,
id : 'lang',
store:[['tr','Türkçe'],['ru','Русский'],['en','English']],
mode: 'local',
triggerAction: 'all',
value: 'tr',
selectOnFocus:true
},
For remote comboboxes you need to plug into store's load event to select the value after store is loaded.
You can use the value property like so:
value : 'tr'
then it will display first value by default.
You can use this code, assigning any store element after its id to the default combobox value.
{
xtype: 'combobox',
forceSelection: true,
allowBlank: true,
typeAhead: true,
queryMode: 'local',
colspan: 3,
id: 'filter_column_c',
style: {'margin': '5px 15px 15px 30px'},
fieldLabel: 'Column',
valueField: 'column',
displayField: 'name',
store: nomStores["storeCombo"],
value: nomStores["storeCombo"].getById(1),
},
As an alternative, I faced the need to show a locally stored Store, which was just a matter of listening the afterRender method:
listeners: {
afterRender: function() {
this.select(01);
}
}
01 in this case is the id (valueField) of the element in the Store:
areasCenters: {
data: [{
id: 01,
name: 'Todas'
},
{
id: 02,
name: 'Elegir...'
}
],
autoLoad: true
}
I have an EditorGridPanel which I show via a Ext.Window.
resourcesis the Json-data I get via an Ajax-call.
Example data: {"data":[{"id":"1","allowed":"1","roleId":"0","resource":"nothing"}]}
The problem is that the displayField of the ComboBox is only shown when I click on the ComboBox. When clicked, I get the choices: "allowed", "not allowed". When I remove focus the values get shown: "1", "0".
How can I show the displayField-values even when I have not clicked?
showRoleDetails: function(resources, roleId) {
var rolesData = resources;
var store = new Ext.data.JsonStore({
url: '/plugin/Registration/admin/get-acl-resources-of-role',
baseParams: { role: roleId},
storeId: 'myStore',
root: 'data',
fields: [
{name: 'allowed'},
{name: 'resource'}
]
});
store.load();
var grid = new Ext.grid.EditorGridPanel({
title: "Edit / View permissions for resources",
store: store,
autoHeight: true,
columns: [
{
header: 'Allowed',
dataIndex: 'allowed',
editor: new Ext.form.ComboBox({
triggerAction: 'all',
frame: true,
lazyRender:true,
editable: false,
mode: 'local',
value: 'allowed',
store: new Ext.data.JsonStore({
fields : ['allowed', 'allowedLabel'],
data :
[
{
allowed: '1',
allowedLabel: 'allowed'
},
{
allowed: '0',
allowedLabel: 'not allowed'
}
]
}),
valueField: 'allowed',
displayField: 'allowedLabel'
})
},
{
header: 'Resource',
dataIndex: 'resource'
}
]
});
var window = new Ext.Window({
items: grid
});
window.show();
}
Edit: Following Narendra Kamma's response, I edited my code as such:
var comboBox = new Ext.form.ComboBox({ //Combox values need to be filled up
triggerAction: 'all',
frame: true,
lazyRender:true,
editable: false,
mode: 'local',
value: 'allowed',
store: new Ext.data.JsonStore({
fields : ['allowed', 'allowedLabel'],
data :
[
{
allowed: '1',
allowedLabel: 'allowed'
},
{
allowed: '0',
allowedLabel: 'not allowed'
}
]
}),
valueField: 'allowed',
displayField: 'allowedLabel'
}) ;
var me = this;
var grid = new Ext.grid.EditorGridPanel({
title: "Edit / View permissions for resources",
store: store,
autoHeight: true,
columns: [
{
header: 'Allowed',
dataIndex: 'allowed',
editor: comboBox,
renderer: me.comboBoxRenderer(comboBox)
},
{
header: 'Resource',
dataIndex: 'resource'
}
]
});
This works wonderfully.
you should render the display value yourself. look for renderer option in grid column spec.
configure renderer
it will supply selected value, and related store record
you can return display value basing on your logic (accepts any value literally)