Jump to content

Can Grid Editors be dynamically assigned?


misc

Recommended Posts

All my grid edit controls exist only once in a TUniHidenPanel. My Grid has a DataSource which is only known at runtime, so my columns are created at runtime as well. I then try to assign my editors like this:

 

procedure TMainForm.uniGridCellClick(Column: TUniDBGridColumn);
begin
  if Column.Field.DataType in [ftDate, ftTime, ftDateTime] then
    Column.Editor:= uniDateTimePicker1

  else if Column.Field.DataType in [ftBoolean] then begin
      Column.Editor:= uniCheckBox1

  else if Column.Field.DataType in [ftMemo, ftWideMemo, ftFmtMemo] then
    Column.Editor:= uniMemo1;
end;

 

Problem: The editors don't appear in my Grid, even when I doubleclick to enter editing.

 

Can grid editors be dynamically assigned, or do all columns with assigned fields and individual editors have to exist at design time?

 

Link to comment
Share on other sites

Hi Michael Schindler.
 
One of the solutions (I think there are other solutions). 
 
1. I think you can not use one component at a time for multiple columns (although it is possible, but will slow down, so that every time this component to assign a specific column...   uniGridCellClick (Column: TUniDBGridColumn) not the best place). 
 
2. When you change the runtime DataSet, you can use instead Column.Editor:= uniDateTimePicker1
 this code: 
uses ... uniGUIApplication ... ;
UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[8].setEditor(' + UniDateTimePicker1.JSName + ');');

3. Or whenever changes DataSet, remove all controls on TUniHidenPanel, and re-create the controls and attach to the column ... 

//... re-created components in TUniHidenPanel

UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[8].setEditor(' + UniDateTimePicker1.JSName + ');');
... 
 
 
Try ... 
 
Sincerely.
Link to comment
Share on other sites

Thank you. I tried it:


procedure TMainForm.uniGridCellClick(Column: TUniDBGridColumn);
begin
  if Column.Field.DataType in [ftDate, ftTime, ftDateTime] then
    UniSession.AddJS(
      Format(TUniDBGrid(Column.Grid).JSName + '.columnManager.columns[%d].setEditor(' + uniDateTimePicker1.JSName + ');', [Column.Index]));
end;

 

However, what I got was a short blink of a button on the right side of the cell, and then this error message:
 

image01.jpg

 

 

So, where should I create and assign editors at runtime? My users create their own SQL at runtime, so I cannot design a grid with fixed editor controls. Should I create a control for each column at runtime and assign it with the UniSession.AddJS Method BEFORE loading the grid? uniGridCellClick is obviously not the right place. But why not - can someone explain?

 

PS: As I am new to uniGUI, I guess I still don't quite get some of the concepts, and I also don't find this kind of stuff in any help file. I know a beta is an early stage to expect this information.

Link to comment
Share on other sites

Hi Michael Schindler. 
 
1. You do not need to assign each time editor for columns!
 
2. You can after opening the DataSet, attach the editor like this: 
UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[8].setEditor(' + UniDateTimePicker1.JSName + ');');

3. But, I think you can not assign for multiple columns one editor.

 

4. Or you can dynamically create the editor as follows:
procedure TMainForm.UniButton1Click(Sender: TObject);
var
  i: Integer;
begin
  //After opening DataSet
  for i := 0 to UniDBGrid1.Columns.Count - 1 do begin        
    if UniDBGrid1.Columns[i].Field.DataType in [ftDateTime] then 
    begin
      UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[' + IntToStr(i) + '].setEditor(' +
                       ' new Ext.form.field.Date({' +
                       ' id: ''' + UniDBGrid1.JSName + 'columnsEditor' + IntToStr(i) + ''', ' +
                       ' xtype: ''datefield'',' +
                       ' format: ''d/m/Y'',' +
                       ' anchor: ''100%'',' +
                       ' maxValue: new Date()' +
                       ' })' +
                       ' );');
    end
    else if UniDBGrid1.Columns[i].Field.DataType in [ftTime] then 
    begin
      UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[' + IntToStr(i) + '].setEditor(' +
                       ' new Ext.form.field.Time({' +
                       ' id: ''' + UniDBGrid1.JSName + 'columnsEditor' + IntToStr(i) + ''', ' +
                       ' format: ''H:i'',' +
                       ' anchor: ''100%'',' +
                       ' increment: 30,' +
                       ' minValue: ''8:00'',' +
                       ' maxValue: ''23:00''' +
                       ' })' +
                       ' );');
    end;
  end;
end;

http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.form.Field

 

Sincerely.
Link to comment
Share on other sites

1. You do not need to assign each time editor for columns!

 

Yes I do, because I fill my Grid.Datasource.Dataset dynamically at runtime, meaning I just don't know at designtime how many instances of UniDateTimePicker I need, i.e. how many DateTime fields there are in my query.
 
2. You can after opening the DataSet, attach the editor like this: 
UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[8].setEditor(' + UniDateTimePicker1.JSName + ');');

Then I need to create an unknown amount of UniDateTimePickers (see above) during design time. If I create 10, it will be enough most of the time, but it's not nice coding. But what if I have a table at runtime which has 11 datetime fields?

3. But, I think you can not assign for multiple columns one editor.

I know, that is why I am trying to create one for every date field I stumble upon during runtime.

 

Clear now, what I am trying to do?

Link to comment
Share on other sites

  • Administrators

All my grid edit controls exist only once in a TUniHidenPanel. My Grid has a DataSource which is only known at runtime, so my columns are created at runtime as well. I then try to assign my editors like this:

 

procedure TMainForm.uniGridCellClick(Column: TUniDBGridColumn);

begin

  if Column.Field.DataType in [ftDate, ftTime, ftDateTime] then

    Column.Editor:= uniDateTimePicker1

 

  else if Column.Field.DataType in [ftBoolean] then begin

      Column.Editor:= uniCheckBox1

 

  else if Column.Field.DataType in [ftMemo, ftWideMemo, ftFmtMemo] then

    Column.Editor:= uniMemo1;

end;

 

Problem: The editors don't appear in my Grid, even when I doubleclick to enter editing.

 

Can grid editors be dynamically assigned, or do all columns with assigned fields and individual editors have to exist at design time?

 

You can't assign or change an editor after Column is created.

 

In your scenario you must query scheme of your Dataset first then create Grid Columns and associated editors manually in runtime code.

 

That said, I have not tested it because it is a very rare scenario.

Link to comment
Share on other sites

Ok, understood.

 

But I don't think it's a rare scenario. After all, the SQL language was invented for adhoc runtime user queries. How can I populate a grid from SQL without the possibility of assigning editors to requested output columns?

Link to comment
Share on other sites

Hi Advanced member, your code actually works:

for i := 0 to UniDBGrid1.Columns.Count - 1 do begin    
if UniDBGrid1.Columns[i].Field.DataType in [ftDateTime] then 
begin
      UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[' + IntToStr(i) + '].setEditor(' +
                       ' new Ext.form.field.Date({' +
                       ' id: ''' + UniDBGrid1.JSName + 'columnsEditor' + IntToStr(i) + ''', ' +
                       ' xtype: ''datefield'',' +
                       ' format: ''d/m/Y'',' +
                       ' anchor: ''100%'',' +
                       ' maxValue: new Date()' +
                       ' })' +
                       ' );');
    end

So Farshads "You can't assign or change an editor after Column is created" seems to be false. Farshad, can you comment on that?

 

However, when I go into edit mode, the current cell value is not displayed anymore, and also the datetimepicker does not show the value. Is there any way to dynamically show the current record value in the picker?

Link to comment
Share on other sites

However, when I go into edit mode, the current cell value is not displayed anymore, and also the datetimepicker does not show the value. Is there any way to dynamically show the current record value in the picker?

 

Hi Michael Schindler. 
 
I have no problem using this code: 

  ...

   if UniDBGrid1.Columns[i].Field.DataType in [ftDateTime] then 
   begin
      UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[' + IntToStr(i) + '].setEditor(' +
                       ' new Ext.form.field.Date({' +
                       ' id: ''' + UniDBGrid1.JSName + 'columnsEditor' + IntToStr(i) + ''', ' +
                       ' xtype: ''datefield'',' +
                       ' format: ''d/m/Y'',' +
                       ' anchor: ''100%'',' +
                       ' maxValue: new Date()' +
                       ' })' +
                       ' );');
   end
   ...
Maybe you need to separately specify certain types of fields? 
for example:
 

   if Column.Field.DataType in [ftDate, ftTime, ftDateTime] then

   if Column.Field.DataType in [ftTime] then

    if UniDBGrid1.Columns[i].Field.DataType in [ftDate, ftDateTime] then 
    begin
      UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[' + IntToStr(i) + '].setEditor(' +
                       ' new Ext.form.field.Date({' +
                       ' id: ''' + UniDBGrid1.JSName + 'columnsEditor' + IntToStr(i) + ''', ' +
                       ' xtype: ''datefield'',' +
                       ' format: ''d/m/Y'',' +
                       ' anchor: ''100%'',' +
                       ' maxValue: new Date()' +
                       ' })' +
                       ' );');
    end
    else if UniDBGrid1.Columns[i].Field.DataType in [ftTime] then 
    begin
      UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[' + IntToStr(i) + '].setEditor(' +
                       ' new Ext.form.field.Time({' +
                       ' id: ''' + UniDBGrid1.JSName + 'columnsEditor' + IntToStr(i) + ''', ' +
                       ' format: ''H:i'',' +
                       ' anchor: ''100%'',' +
                       ' increment: 30,' +
                       ' minValue: ''8:00'',' +
                       ' maxValue: ''23:00''' +
                       ' })' +
                       ' );');
    end;
Best regards.
Link to comment
Share on other sites

  • Administrators

Hi Advanced member, your code actually works:

for i := 0 to UniDBGrid1.Columns.Count - 1 do begin    
if UniDBGrid1.Columns[i].Field.DataType in [ftDateTime] then 
begin
      UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[' + IntToStr(i) + '].setEditor(' +
                       ' new Ext.form.field.Date({' +
                       ' id: ''' + UniDBGrid1.JSName + 'columnsEditor' + IntToStr(i) + ''', ' +
                       ' xtype: ''datefield'',' +
                       ' format: ''d/m/Y'',' +
                       ' anchor: ''100%'',' +
                       ' maxValue: new Date()' +
                       ' })' +
                       ' );');
    end

So Farshads "You can't assign or change an editor after Column is created" seems to be false. Farshad, can you comment on that?

 

However, when I go into edit mode, the current cell value is not displayed anymore, and also the datetimepicker does not show the value. Is there any way to dynamically show the current record value in the picker?

 

 

What I said is that you can not change Editors directly using Delphi code.  By using JavaScript and Ext JS functions you may achieve this. That's another story.

 

You may add a Feature Request for this so we can add this capability in future.

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...