PDA

View Full Version : Custom Cell Editors



griffiti93
30 Apr 2007, 2:00 PM
I have found various threads pertaining to this topic. I even found one thread mentioning Jack would be adding this feature to an upcoming release. Unfortunately, I am in need of this feature now, so I am journeying into the code trying to roll my own.


Problem
How to apply a different editor to grid cells by criteria.


Forces
Let's look at an order entry example. The grid rows represents each product being ordered. One field is the product lookup, rendered by a GridEditor::Combo widget. The next field might be options for that selected product. Here too a GridEditor::Combo widget is desired. However, the list of options change based on the selected product in the previous cell. If I pick a Treo 680, then my options would perhaps be colors. But the next row I might select a DVD, so my options my be full screen or widescreen.


Solution
I don't have a solution just yet. I have looked at how the column model stores editors per column, considering how to extend this for a list of cell index based editors. I also looked at the onRender() of the Ext.Editor class, considering how that might be modified.

I have created a MixedCollection of custom selects I've built to use with my customer renderer. It works too! But the problem is the actually combo widget displays the list mapped in the config passed into the constructor.

If anyone has attempted this mod with success, let me know. Or if you have some ideas, let's work on it together?

jsakalos
30 Apr 2007, 3:37 PM
You can override function getCellEditor of ColumnModel and test inside your new function your criteria.

Look at the source code of EditorGrid and PropertyGrid. Property grid overrides this function.

griffiti93
1 May 2007, 9:11 AM
I thought I would provide an update on my progress so far. I have my custom column model in place. Upon reviewing the way the PropertyColumnModel was built, I had to roll a custom Editor for including a grid reference. So far I have my editor+cm in place and everything is working correctly. My custom getCellEditor() is being called. I am pushing it to the default CM for now.

All I have left is to add my custom logic for custom on the fly editors. It should work. :-?

griffiti93
1 May 2007, 11:12 AM
Well I am pleased to say ... it worked!!! :D

It was cool extending the EditorGrid similarly to the PropertyGrid. My implementation is definitely proprietary to the business problem I'm solving. It's not generic enough for normal use. Once I get out from under this project deadline, I might perhaps extract some things and make it more customizable. But then I might just wait, since rumor has it Jack will be adding custom cell editors to a future release.

For those who might need something similar, here's what I did. I followed jsakalos' advice and modeled my implementation after the PropertyGrid. I setup a custom column model. This allowed me to store a reference to the grid, and provide for custom editors. Then I overrode the getCellEditor() method from ColumnModel. I was only concerned with the column index 3, so all other columns get served up the editor defined in the object meta definition on instantiation. But when column index 3 is passed in, I access the value of another column in that record to serve up an custom combo box editor with a list that goes with the other column selection.

Piece of cake, right! LOL /:) It only took me all day yesterday to get my head around it, and last night and this morning to get it working. Jack I appreciate your work even more. You are awesome!

Custom ColumnModel


CellEditorColumnModel = function(config, grid) {
// Call parent constructor
CellEditorColumnModel.superclass.constructor.call(this, config);



/** PRIVELEGED PROPERTIES */
this.config = config;
this.grid = grid;
this.editors = new Ext.util.MixedCollection(true);



/** PRIVELEGED METHODS */
this.addEditor = function(label, editor) {
this.editors.add(label, editor);
};
};

Ext.extend(CellEditorColumnModel, Ext.grid.ColumnModel, {
getCellEditor : function(colIndex, rowIndex) {
if (colIndex == 3) {
var record = this.grid.getDataSource().getAt(rowIndex);
var editor = this.editors.item(record.get('material'));
return editor;
} else {
return this.config[colIndex].editor; // same code as ColumnModel
}
}
});


Custom Editor


CellEditorGrid = function(container, config, columns, editors) {
if (typeof columns == 'undefined') { throw 'Columns not defined for CellEditorGrid.'; }
var cm = new CellEditorColumnModel(columns, this);

if (typeof editors != 'undefined') {
for (var i = 0; i < editors.length; i++) {
cm.addEditor(editors[i].name, editors[i].editor);
}
}

CellEditorGrid.superclass.constructor.call(this, container, Ext.apply({cm: cm}, config));
};

Ext.extend(CellEditorGrid, Ext.grid.EditorGrid, {});

griffiti93
1 May 2007, 11:28 AM
Screenshots
Here are some screenshots of this code in action. You will notice that FINISH column combo box editor serves up a different list, based on the selection in the SVC/MATERIAL column. Some options are shared across lists, but you'll notice some options vary.

http://www.objectworx.com/images/extexamples/custom_editor_1.png

http://www.objectworx.com/images/extexamples/custom_editor_2.png

http://www.objectworx.com/images/extexamples/custom_editor_3.png

jsakalos
1 May 2007, 12:17 PM
Nice job!

I'm glad I helped.

andreas.linde
24 Jul 2007, 7:19 AM
I have a similar problem, I want to create a selection list in a cell, where the content of the values depend on the initialized value of the same cell.

Your code seems to scope some of my problems, but I have problems on using it currently. Could you by chance post an example on how to build an editorgrid with your code?

I was also looking if Jack is going to include custom cell editors into a future build, but sadly found no reference.

deitch
27 Nov 2007, 8:08 AM
// enable custom cell editing
Ext.apply(Ext.grid.ColumnModel.prototype,{
getCellEditor : function(colIndex,rowIndex) {
var editor = this.config[colIndex].editor;
if (typeof(editor) == 'function') {
editor = editor(colIndex,rowIndex);
}
return(editor);
}
});

/* now you can use it with any grid column model, just make the editor a function that takes colIndex,rowIndex rather than an object */
var grid = new Ext.grid.EditorGridPanel({
// lots of stuff
columns: [{...},{
editor: function(colIndex,rowIndex) {
if (rowIndex == someNumber) {return myDatePickerObject;};
}
}]

deitch
27 Nov 2007, 8:17 AM
Sorry, my slip.



// enable custom cell editing
Ext.apply(Ext.grid.ColumnModel.prototype,{
getCellEditor : function(colIndex,rowIndex) {
var editor = this.config[colIndex].editor;
if (typeof(editor) == 'function') {
editor = editor(colIndex,rowIndex);
if (editor && editor.isFormField) {
editor = new Ext.grid.GridEditor(editor);
}
}
return(editor);
}
});

Kjeldahl
3 Dec 2007, 2:30 AM
Hi

I cannot make this work correctly. It works the first time I edit a cell. But each time thereafter the editor is not shown.

This is the code I use in the columns model for the editor:


....
editor: function(colIndex,rowIndex) {

if (rowIndex == 1) {
return comboBoxEditor1;
}
else {
return comboBoxEditor2;
}
}
...

randygo
19 Dec 2007, 12:07 PM
I like ditech's idea, but as noted by the poster above, it doesn't quite work.

There seems to be a problem trying to reuse instances of the fields. One way I made it work is to instantiate a new field each time. I'm not sure if there are any memory issues to worry about with this approach:



editor: function(colIndex,rowIndex) {

if (rowIndex == 1) {
return new Ext.form.DateField();
}
else {
return new Ext.form.TextField({allowBlank: false});
}
// etc...
}


Cheers,

Randy

naga_cit
25 Feb 2008, 3:43 PM
Sorry, my slip.



// enable custom cell editing
Ext.apply(Ext.grid.ColumnModel.prototype,{
getCellEditor : function(colIndex,rowIndex) {
var editor = this.config[colIndex].editor;
if (typeof(editor) == 'function') {
editor = editor(colIndex,rowIndex);
if (editor && editor.isFormField) {
editor = new Ext.grid.GridEditor(editor);
}
}
return(editor);
}
});


Is this possible to get the content of that particular row and assign different editors? meaning I want to change the cell editor type based on the previous column value.

like if column2.content type is so and so
then column3 editor is so?

brikonwall
19 Mar 2008, 1:38 PM
naga_cit, I am trying to accomplish the same. Have been looking around for a while, but couldn't find anything yet. It would very good see a good example about it.

brikonwall
20 Mar 2008, 9:01 PM
Anyone have any idea about this? I will really appreciate. I am newbie to ext, hence I have no clue how to change editor type of a cell based on value of another cell.

mjlecomte
21 Mar 2008, 8:28 AM
Have you checked the grid FAQ (see #7)? It's good that you're searching the forums, but you're posting in an old version of ext, which hopefully you're using ext2 now and not ext1.

brikonwall
21 Mar 2008, 8:34 AM
Thanks for the reply, yes I am using Ext2, not Ext1. I will look in FAQ #7 and hopefully that will give me a good indication.

brikonwall
21 Mar 2008, 8:57 AM
Ok, read grid FAQ #7 but that talks about modifying appearance, behavior of specific rows or columns, but I need to change the modify appearance/behavior of specific cell. Let me ellaborate what I am trying to do.

I am trying to set the editor type to (textfield or numberfield or datefield) of a cell in EditorGridPanel based on value of previous cell. The grid has 3 columns. The first column will always be a textfield. Second field is a combo box with options "Number", "Alphanumeric" and "Date". The third column starts without any set editor. Following is what I am trying to achieve.

1stColumn 2ndColumn 3rdColumn
some value Number [NumberField]
some value Date [DateField]
some value Alphanumeric [TextField]
some value Number [NumberField]
some value Date [DateField]
some value Alphanumeric [TextField]

mjlecomte
21 Mar 2008, 9:45 AM
Yes, but you work with a given record (row). FAQ uses the example of looking at a particular field, I think it was SEVERITY or something. Based on that you can render the column of that record accordingly.

#28 is another variation on this, where it shows how to deny editing to a particular cell that depends on another.

Look it over again, and post your question in the 2.0 forums with a link back here. Post the code you're working with, etc., that way anyone responding can be more specific with suggestions.

Also note the last bullet is an example of rendering particular cells only, as shown in the picture of the example....(see the risk column here: http://extjs.com/learn/Tutorial:Ext20_Grid_Editor_PHP_MySQL). Yes, slightly different because it renders based on value of cell that it's rendering. You're only suggesting something slightly different, working with the row ie. record) and checking field X to render field Y.

Sorry, just re-read your post. You want to do something different than what I'm talking about. There are several threads on dependent combo boxes. You may want to search for that. The comboBox / Forms FAQ (http://extjs.com/forum/showthread.php?p=135406#post135406)in my thread may have something as well. You may not want a grid, but use a form instead. I recall seeing someone else asking about this same thing quite recently.

brikonwall
21 Mar 2008, 10:23 AM
I have posted this in 2.0 forum. The link is
http://extjs.com/forum/showthread.php?t=29853