[CLOSED] DropDownField as GridPanel column editor issues

  1. #1

    [CLOSED] DropDownField as GridPanel column editor issues

    Hi,

    I'm trying to assign an editor to a GridPanel column in the form of dynamically created DropDownField with an embedded TextField as follows:

                        column.setEditor(new Ext.grid.GridEditor(
    						Ext.apply({
    						    field: {
    						        id: "DropDownField1",
    						        xtype: "netdropdown",
                                    triggersConfig:[{iconCls:"x-form-clear-trigger"}],
                                    editable:false,
                                    component:{
                                        id:"ComponentPanel1",
                                        xtype:"panel",
                                        items:{
                                            id:"Editor1",
                                            xtype:"textfield",
                                            enableKeyEvents:true,
                                            selectOnFocus:true
                                        },
                                        layout:"fit"
                                    },
                                    listeners:{
                                        expand:{
                                            fn:function(item){
                                                Editor1.setValue(gridRecord.get('DisplayValue'));
                                                Editor1.focus();
                                            }
                                        },
                                        triggerclick:{
                                            fn:function(item,trigger,index,tag,e){
                                                this.setValue(null);
                                                gridRecord.set("DisplayValue", null);
                                                #{ButtonReset}.enable();
                                                #{ButtonSave}.enable();
                                            }
                                        }
                                    }
    						    }
    						},
                            {})));
    The code above works for the most part with a few issues. To begin with, I can't get the focus into the underlying TextField control. Secondly, I'm getting a client side error after clicking the "Clear" trigger button and exiting the cell (the gridRecord object is valid). Lastly, I'm not sure how to have the grid record value updated automatically after editing the text in the TextField. One would think of a TextField change or keyup listener, is that correct?

    Please advise or let me know if more info is needed here.
    Last edited by Baidaly; Nov 25, 2012 at 9:52 PM. Reason: [CLOSED]
  2. #2
    Quote Originally Posted by vadym.f View Post
    Hi,
    The code above works for the most part with a few issues. To begin with, I can't get the focus into the underlying TextField control. Secondly, I'm getting a client side error after clicking the "Clear" trigger button and exiting the cell (the gridRecord object is valid). Lastly, I'm not sure how to have the grid record value updated automatically after editing the text in the TextField. One would think of a TextField change or keyup listener, is that correct?

    Please advise or let me know if more info is needed here.
    Hello, Vadym!
    I don't quite understand why do you want to get the focus into the TextField because you made your editor non-editable.
    You are receiving this error because you didn't assign value to gridRecord, to do this you should initialize when you are creating your editor:

    Ext.apply({
    	field: {
    		id: "DropDownField1",
    		xtype: "netdropdown",
    		triggersConfig:[{iconCls:"x-form-clear-trigger"}],
    		editable:true,
    		component:{
    			id:"ComponentPanel1",
    			xtype:"panel",
    			items:{
    				id:"Editor1",
    				xtype:"textfield",
    				enableKeyEvents:true,
    				selectOnFocus:true
    			},
    			layout:"fit"
    		},
    		gridRecord: e.record,
    		listeners:{
    			expand:{
    				fn:function(item){
    					Editor1.setValue(this.gridRecord.get('DisplayValue'));
    					Editor1.focus();
    				}
    			},
    			triggerclick:{
    				fn:function(item,trigger,index,tag,e){
    					this.setValue(null);
    					this.gridRecord.set("DisplayValue", null);
    				}
    			}
    		}
    	}
    },{})));
    I think it's better to listen blur event.
  3. #3
    Hi Daulet,

    I need the focus in the TextField area because it's the component where the end user will be modifying the input. DropDownField's function is to provide the initial container with the dropdown trigger button. I want it to be read-only. When the user clicks on the dropdown button, I want the focus to move right into the editor saving a mouse click or tab key stroke.
    As I mentioned, consider the gridRecord initialized and valid, as it is in reality. I'm able to modify the value of the field and move away from the cell OK. The error occurs only after the trigger button has been hit.

    Here's the offending line in the native code:

    if(a.length<1||a===this.emptyText)
    SCRIPT5007: Unable to get value of the property 'length': object is null or undefined 
    ext.axd?v=0, line 11 character 50450
    Do you have enough info or do you need more?
  4. #4
    Quote Originally Posted by vadym.f View Post
    I can't get the focus into the underlying TextField control.
    Please try this in the "expand" listener.
    TextField1.focus.defer(1, TextField1);
    Example
    <ext:DropDownField runat="server">
        <Component>
            <ext:Panel runat="server">
                <Items>
                    <ext:TextField ID="TextField1" runat="server" />
                </Items>
            </ext:Panel>
        </Component>
        <Listeners>
            <Expand Handler="TextField1.focus.defer(1, TextField1);" />
        </Listeners>
    </ext:DropDownField>
    Quote Originally Posted by vadym.f View Post
    Secondly, I'm getting a client side error after clicking the "Clear" trigger button and exiting the cell (the gridRecord object is valid).
    Please use an empty string instead of null.
    this.setValue("");
    Quote Originally Posted by vadym.f View Post
    Lastly, I'm not sure how to have the grid record value updated automatically after editing the text in the TextField. One would think of a TextField change or keyup listener, is that correct?
    Well, you can try them. Please note that the change event occurs on blur if the value has been change since focusing. So, if you need to update on typing then you should try with the keyup event.

    I would also consider a possibility to update the record when the DropDownField's collapse event occurs.
  5. #5
    Hi Daniil,

    Thanks for the helpful directions! Setting value to empty string works if the initial record value was non-null. Otherwise, I'm getting a client error clicking and leaving the cell. Is there anything incorrectly set up here?

                        column.setEditor(new Ext.grid.GridEditor(
    						Ext.apply({
    						    field: {
    						        id: "DropDownField1",
    						        xtype: "netdropdown",
                                    triggersConfig:[{iconCls:"x-form-clear-trigger"}],
                                    editable:false,
                                    component:{
                                        id:"ComponentPanel1",
                                        xtype:"panel",
                                        items:{
                                            id:"Editor1",
                                            xtype:"textarea",
                                            listeners:{
                                                change:{
                                                    fn:function(item,e){
                                                        DropDownField1.setValue(this.getValue());
                                                        gridRecord.set('DisplayValue', this.getValue());
                                                        gridRecord.set('LongStringValue', this.getValue());
                                                    }
                                                },
                                                keyup:{
                                                    fn:function(item,e){
                                                        #{ButtonReset}.enable();
                                                        #{ButtonSave}.enable();
                                                    }
                                                },
                                            },
                                            enableKeyEvents:true,
                                            selectOnFocus:true
                                        },
                                        layout:"fit"
                                    },
                                    listeners:{
                                        expand:{
                                            fn:function(item){
                                                Editor1.setValue(gridRecord.get('DisplayValue'));
                                                Editor1.focus.defer(1, Editor1);
                                            }
                                        },
                                        triggerclick:{
                                            fn:function(item,trigger,index,tag,e){
                                                this.setValue("");
                                                gridRecord.set("DisplayValue", null);
                                                #{ButtonReset}.enable();
                                                #{ButtonSave}.enable();
                                            }
                                        }
                                    }
    						    }
    						},
                            {})
    						));
  6. #6
    Quote Originally Posted by vadym.f View Post
    I'm getting a client error clicking and leaving the cell.
    What is the error? It is always very helpful for us to get more details about any errors and exceptions.
  7. #7
    Quote Originally Posted by Daniil View Post
    What is the error? It is always very helpful for us to get more details about any errors and exceptions.
    I posted it in #3
  8. #8
    Hello, Vadym!

    As I said in #2, your problem that you didn't set a value to the gridRecord.

    You said in #3:
    As I mentioned, consider the gridRecord initialized and valid, as it is in reality. I'm able to modify the value of the field and move away from the cell OK. The error occurs only after the trigger button has been hit.
    But I don't see this and for this reason you see this errors. If you are setting value in gridRecord you have to check that it works correctly.

    My example:

    <%@ Page Language="C#" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e) {
            if (!X.IsAjaxRequest) {
                Store store = this.GridPanel1.GetStore();
                store.DataSource = new object[]
                {
                    new object[] { "id1", "DateField", "Nov 01, 2011" },
                    new object[] { "id2", "ComboBox" },
                    new object[] { "id3", "DateField", "Dec 12, 2011" },
                    new object[] { "id4", "ComboBox" },
                };
                store.DataBind();
            }
        }
    
        protected void ComboBoxStore_RefreshData(object sender, StoreRefreshDataEventArgs e) {
            Store store = sender as Store;
            string id = e.Parameters["id"];
            store.DataSource = new object[]
                {
                new object[] { id + "_" + DateTime.Now.Second, "1" },
                new object[] { id + "_" + DateTime.Now.Second, "2" }
                };
            store.DataBind();
        }
    </script>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>Ext.NET Example</title>
        <ext:XScript runat="server">
            <script type="text/javascript">
                var setEditor = function(e) {
                    var column = e.grid.getColumnModel().columns[e.column], ed = column.getCellEditor(e.row);
                    if (ed) {
                        ed.destroy();
                    }
                    column.setEditor(new Ext.grid.GridEditor(
                        Ext.apply({
                                field: {
                                    id: "DropDownField1",
                                    xtype: "netdropdown",
                                    triggersConfig: [{ iconCls: "x-form-clear-trigger" }],
                                    editable: false,
                                    gridRecord: e.record,
                                    component: {
                                        id: "ComponentPanel1",
                                        xtype: "panel",
                                        items: {
                                            id: "Editor1",
                                            xtype: "textarea",
                                            listeners: {
                                                change: {
                                                    fn: function(item, e) {
                                                        DropDownField1.setValue(this.getValue());
                                                        this.gridRecord.set('DisplayValue', this.getValue());
                                                        this.gridRecord.set('LongStringValue', this.getValue());
                                                    }
                                                },
                                                keyup: {
                                                    fn: function(item, e) {
    //                                #{ButtonReset}.enable();
    //                                #{ButtonSave}.enable();
                                                    }
                                                }
                                            },
                                            enableKeyEvents: true,
                                            selectOnFocus: true
                                        },
                                        layout: "fit"
                                    },
                                    listeners: {
                                        expand: {
                                            fn: function(item) {
                                                Editor1.setValue(this.gridRecord.get('DisplayValue'));
                                                Editor1.focus.defer(1, Editor1);
                                            }
                                        },
                                        triggerclick: {
                                            fn: function(item, trigger, index, tag, e) {
                                                this.setValue("");
                                                this.gridRecord.set("DisplayValue", null);
    //                                            #{ButtonReset}.nable();
    //                                            #{ButtonSave}.enable();
                                            }
                                        }
                                    }
                                }
                            },
                            { })
                    ));
                };
                var testRenderer = function (value) {
                    var record = ComboBoxStore.getById(value);
                    if (record) {
                        value = record.data.text;
                    } else {
                        value = Ext.util.Format.date(value, "Y-m-d");
                    }
                    return value;
                };
            </script>
        </ext:XScript>
    </head>
    <body>
        <form id="Form1" runat="server">
        <ext:ResourceManager ID="ResourceManager1" runat="server" Locale="en" ScriptMode="Debug"
            SourceFormatting="True" />
        <ext:Store ID="ComboBoxStore" runat="server" OnRefreshData="ComboBoxStore_RefreshData"
            AutoLoad="false">
            <Proxy>
                <ext:PageProxy />
            </Proxy>
            <Reader>
                <ext:ArrayReader IDProperty="value">
                    <Fields>
                        <ext:RecordField Name="text" />
                        <ext:RecordField Name="value" />
                    </Fields>
                </ext:ArrayReader>
            </Reader>
            <Listeners>
                <BeforeLoad Handler="this.removeAll();" />
                <Load Handler="" />
            </Listeners>
        </ext:Store>
        <ext:GridPanel ID="GridPanel1" runat="server" AutoHeight="true" ClicksToEdit="1" AutoExpandColumn="test"
            Width="600">
            <Store>
                <ext:Store ID="Store1" runat="server">
                    <Reader>
                        <ext:ArrayReader>
                            <Fields>
                                <ext:RecordField Name="id" />
                                <ext:RecordField Name="editor" />
                                <ext:RecordField Name="test" />
                            </Fields>
                        </ext:ArrayReader>
                    </Reader>
                </ext:Store>
            </Store>
            <ColumnModel ID="ColumnModel1" runat="server">
                <Columns>
                    <ext:Column Header="ID" DataIndex="id" />
                    <ext:Column Header="Editor" DataIndex="editor" />
                    <ext:Column Header="Test" DataIndex="test">
                        <Renderer Fn="testRenderer" />
                    </ext:Column>
                </Columns>
            </ColumnModel>
            <Listeners>
                <BeforeEdit Fn="setEditor" />
                <Render Handler="this.getColumnModel().setEditable(2, true);" />
            </Listeners>
        </ext:GridPanel>
        </form>
    </body>
    </html>
  9. #9
    Thanks for help Daulet, Daniil!

    Frankly, I'm now not sure what caused the client side error. Probably, a combination of several factors. When I modified my code sample implementing your suggestions, the error is not reproducible any more. The working code sample is below. You can mark this thread as closed.

    <%@ Page Language="C#" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                Store store = this.GridPanel1.GetStore();
                store.DataSource = new object[]
                {
                      new object[] { "id1", "DateField", "Nov 01, 2011" },
                      new object[] { "id2", "ComboBox" },
                      new object[] { "id3", "DateField", "Dec 12, 2011" },
                      new object[] { "id4", "ComboBox" },
                      new object[] { "id5", "TextArea" }
                };
                store.DataBind();
    
                new TriggerField().RegisterIcon(TriggerIcon.Clear);
            }
        }
    
        protected void ComboBoxStore_RefreshData(object sender, StoreRefreshDataEventArgs e)
        {
            Store store = sender as Store;
            string id = e.Parameters["id"];
            store.DataSource = new object[]
            {
               new object[] { id + "_" + DateTime.Now.Second, "1" },
               new object[] { id + "_" + DateTime.Now.Second, "2" }
            };
            store.DataBind();
        }
    </script>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>Ext.NET Example</title>
        <script type="text/javascript">
            var setEditor = function (e) {
                var column = e.grid.getColumnModel().columns[e.column], ed = column.getCellEditor(e.row);
                if (ed) {
                    ed.destroy();
                }
    
                var gridRecord=e.record;
                switch (e.record.get("editor")) {
                    case "DateField":
                        column.setEditor(new Ext.form.DateField({ altFormats: 'm/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j|M d, Y' }));
                        break;
                    case "TextArea":
                        column.setEditor(new Ext.grid.GridEditor(
    				        Ext.apply({
    					        field: {
    						        id: "DropDownField1",
    						        xtype: "netdropdown",
                                    triggersConfig:[{iconCls:"x-form-clear-trigger"}],
                                    editable:false,
                                    component:{
                                        id:"ComponentPanel1",
                                        xtype:"panel",
                                        items:{
                                            id:"Editor1",
                                            xtype:"textarea",
                                            listeners:{
                                                change:{
                                                    fn:function(item,e){
                                                        DropDownField1.setValue(this.getValue());
                                                        gridRecord.set("value", this.getValue());
                                                    }
                                                },
                                                keyup:{
                                                    fn:function(item,e){
    
                                                    }
                                                },
                                            },
                                            enableKeyEvents:true,
                                            selectOnFocus:true
                                        },
                                        layout:"fit"
                                    },
                                    listeners:{
                                        expand:{
                                            fn:function(item){
                                                Editor1.setHeight(column.width*0.625);
                                                Editor1.setValue(gridRecord.get("value"));
                                                Editor1.focus.defer(1, Editor1);
                                            }
                                        },
                                        triggerclick:{
                                            fn:function(item,trigger,index,tag,e){
                                                this.setValue("");
                                                gridRecord.set("value", "");
                                            }
                                        }
                                    }
    					        }
    				        },
                            {})
    				        ));
                        break;
                    case "ComboBox":
                        column.setEditor(new Ext.form.ComboBox({
                            displayField: "text",
                            valueField: "value",
                            triggerAction: "all",
                            store: ComboBoxStore,
                            listeners: {
                                select: {
                                    fn: function (item, record, index) {
    
                                    }
                                }
                            }
                        }));
                        ComboBoxStore.on("beforeload", function (store, options) {
                            options.params = {
                                id: e.record.data.id
                            }
                        }, null, {
                            single: true
                        });
                        break;
                }
            };
    
            var testRenderer = function (value) {
                var record = ComboBoxStore.getById(value);
                if (record) {
                    value = record.data.text;
                } else if(value instanceof Date) {
                    value = Ext.util.Format.date(value, "Y-m-d");
                }
                return value;
            };
        </script>
    </head>
    <body>
        <form id="Form1" runat="server">
        <ext:ResourceManager ID="ResourceManager1" runat="server" Locale="en" ScriptMode="Debug"
            SourceFormatting="True" />
        <ext:Store ID="ComboBoxStore" runat="server" OnRefreshData="ComboBoxStore_RefreshData"
            AutoLoad="false">
            <Proxy>
                <ext:PageProxy />
            </Proxy>
            <Reader>
                <ext:ArrayReader IDProperty="value">
                    <Fields>
                        <ext:RecordField Name="text" />
                        <ext:RecordField Name="value" />
                    </Fields>
                </ext:ArrayReader>
            </Reader>
        </ext:Store>
        <ext:GridPanel ID="GridPanel1" runat="server" AutoHeight="true" ClicksToEdit="1">
            <Store>
                <ext:Store ID="Store1" runat="server">
                    <Reader>
                        <ext:ArrayReader>
                            <Fields>
                                <ext:RecordField Name="id" />
                                <ext:RecordField Name="editor" />
                                <ext:RecordField Name="test" />
                            </Fields>
                        </ext:ArrayReader>
                    </Reader>
                </ext:Store>
            </Store>
            <ColumnModel ID="ColumnModel1" runat="server">
                <Columns>
                    <ext:Column Header="ID" DataIndex="id" />
                    <ext:Column Header="Editor" DataIndex="editor" />
                    <ext:Column Header="Test" DataIndex="test">
                        <Renderer Fn="testRenderer" />
                    </ext:Column>
                </Columns>
            </ColumnModel>
            <Listeners>
                <BeforeEdit Fn="setEditor" />
                <AfterEdit Handler="if (e.record.data.editor == 'DateField' && Ext.util.Format.date(e.originalValue, 'Y-m-d') == Ext.util.Format.date(e.value, 'Y-m-d')) { 
                              e.record.reject(); 
                  }"></AfterEdit>
                <Render Handler="this.getColumnModel().setEditable(2, true);" />
            </Listeners>
        </ext:GridPanel>
        </form>
    </body>
    </html>
    Last edited by vadym.f; Nov 25, 2012 at 9:41 PM.

Similar Threads

  1. Replies: 5
    Last Post: Nov 20, 2012, 1:48 PM
  2. [CLOSED] V2.1 GridPanel Column Editor Help
    By Aurelio in forum 2.x Legacy Premium Help
    Replies: 5
    Last Post: Aug 26, 2012, 9:29 PM
  3. [CLOSED] gridpanel with combobox column editor
    By Marcelo in forum 1.x Legacy Premium Help
    Replies: 5
    Last Post: Dec 30, 2011, 6:53 PM
  4. Replies: 1
    Last Post: Jun 23, 2011, 1:20 PM
  5. Replies: 13
    Last Post: Sep 06, 2010, 7:51 PM

Tags for this Thread

Posting Permissions