Several issues about OnBeforeStoreChanged application within Ext.net 2.2

  1. #1

    Several issues about OnBeforeStoreChanged application within Ext.net 2.2

    Hi Ext support team, recently I confronted several issues on OnBeforeStoreChanged applied within Ext.net 2.2.0.40838 for GridPanel grid data add&edit saving, the implementation was based on the example in Ext.net page (https://examples2.ext.net/#/GridPane...reCustomLogic/).

    Since there is few reference illustration about OnBeforeStoreChanged can be found from internet, open this thread to ask your kindly help.

    Below are the detail issue specifications.

    ISSUE 1. Refresh button click will result in the gridpanel become blank. Is it OK invoke store.Reload() to refresh the gridpanel? If not, how can I implement the refresh function?

    ISSUE 2. Once a new record added and click Save button, an exception will pop up each time whose content is

    {serviceResponse:{success:false,message:"System.Ex ception: Key value is not defined for inserted record ---> System.Exception: Key value is not defined for inserted record\r\n at Ext.Net.Store.InsertCallback(Int32 recordsAffected, Exception exception)\r\n at Ext.Net.Store.MakeInsertes(IDataSource ds, JArray data)\r\n at Ext.Net.Store.MakeChanges()\r\n at Ext.Net.Store.DoSaving(String action, String jsonData, JToken parameters)\r\n --- End of inner exception stack trace ---\r\n at Ext.Net.Store.DoSaving(String action, String jsonData, JToken parameters)\r\n at Ext.Net.Store.RaiseAjaxPostBackEvent(String eventArgument)"}}
    But the new item is added in the DB. How to fix this exception?
    Click image for larger version. 

Name:	Ext-01.png 
Views:	33 
Size:	86.7 KB 
ID:	6427

    ISSUE 3. The Clear button cannot work expectedly

    ISSUE 4. If some check on the submitted item, such as empty text, unaccepted characters and so on. Where it should be added?

    ************************************************** ******************************
    DB table definition:
    NewTestDB.designer.cs
    [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Department")]
        public partial class Department : INotifyPropertyChanging, INotifyPropertyChanged
        {
            
            private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
            
            private int _ID;
            
            private string _Name;
            
        #region
        partial void OnLoaded();
        partial void OnValidate(System.Data.Linq.ChangeAction action);
        partial void OnCreated();
        partial void OnIDChanging(int value);
        partial void OnIDChanged();
        partial void OnNameChanging(string value);
        partial void OnNameChanged();
        #endregion
            
            public Department()
            {
                OnCreated();
            }
            
            [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
            public int ID
            {
                 ...
            }
            
            [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Name", DbType="VarChar(40) NOT NULL", CanBeNull=false)]
            public string Name
            {
                 ...
            }
    ************************************************** *******************************
    Test.aspx
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="DMS.pages.Test" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    
    <html>
    <head id="Head1" runat="server">
        <title>A Test Page</title>
    </head>
    <body>
        <ext:ResourceManager ID="ResourceManager1" runat="server" />
        <ext:Viewport ID="Viewport1" runat="server">
            <LayoutConfig>
                <ext:VBoxLayoutConfig Align="Center" Pack="Center" />
            </LayoutConfig>
            <Items>
                <ext:Container ID="Container1" 
                    runat="server"
                    StyleSpec="background:transparent;"
                    Margins="0 0 10 0">
                    <LayoutConfig>
                        <ext:TableLayoutConfig Columns="4" />
                    </LayoutConfig>
                    <Defaults>
                        <ext:Parameter Name="Width" Value="265" Mode="Raw" />
                        <ext:Parameter Name="Height" Value="370" Mode="Raw" />
                        <ext:Parameter Name="Margin" Value="10" Mode="Raw" />
                    </Defaults>
                    <Items>
                        <%-- Panel1 --%>
                        <ext:Panel runat="server" Collapsible="true" Width="450" ColSpan="2" Title="Panel1" Layout="FitLayout"/>
    
    
                        <%-- Panel2 --%>
                        <ext:Panel runat="server" Collapsible="true" Width="450" ColSpan="2" Title="Panel2" Layout="FitLayout"/>                    
    
    
                        <%-- Panel3 --%>
                        <ext:Panel runat="server" Collapsible="true" Title="Panel3" TitleAlign="Left" Layout="FitLayout"/>                                      
    
    
                        <%-- Panel4 --%>
                        <ext:Panel ID="pSSPlatfom" runat="server" Collapsible="true" Title="Panel4" TitleAlign="Left" Layout="FitLayout"/>
    
    
                        <%-- Department --%>
                        <ext:Panel ID="pSSDepartment" runat="server" Collapsible="true" Title="Department" TitleAlign="Left" Layout="FitLayout">
                            <TopBar>
                                <ext:Toolbar runat="server">
                                    <Items>
                                        <ext:Button runat="server" Icon="Add" Text="Insert">
                                            <Listeners>
                                                <Click Handler="#{storeDepartment}.insert(0, {}); #{gridpanelDepartment}.editingPlugin.startEditByPosition({row:0, column:1});" />
                                            </Listeners>
                                        </ext:Button>                                    
                                        <ext:ToolbarSeparator runat="server" />
                                        <ext:Button runat="server" ID="btnSave" Icon="Disk" Text="Save">
                                            <Listeners>
                                                <Click Handler="#{storeDepartment}.sync();" />
                                            </Listeners>
                                        </ext:Button>
                                        <ext:ToolbarSeparator runat="server" />
                                        <ext:Button runat="server" Icon="Cancel" Text="Clear">
                                            <Listeners>
                                                <Click Handler="#{gridpanelDepartment}.getSelectionModel().deselectAll();" />
                                            </Listeners>
                                        </ext:Button>
                                        <ext:ToolbarSeparator runat="server" />
                                        <ext:Button runat="server" Icon="ArrowRefresh" Text="Refresh">
                                            <DirectEvents>
                                                <Click OnEvent="Refresh">
                                                    <ExtraParams>
                                                        <ext:Parameter Name="Type" Value="Department" Mode="Value" />
                                                    </ExtraParams>
                                                </Click>
                                            </DirectEvents>
                                        </ext:Button>
                                    </Items>
                                </ext:Toolbar>
                            </TopBar>
                            <Items>
                                <ext:GridPanel runat="server" ID="gridpanelDepartment" AutoScroll="true">
                                    <Store>
                                        <ext:Store runat="server" ID="storeDepartment" OnBeforeStoreChanged="Dept_BeforeChange">
                                            <Model>
                                                <ext:Model ID="Model4" runat="server" IDProperty="ID">
                                                    <Fields>
                                                        <ext:ModelField Name="ID" Type="Int" />
                                                        <ext:ModelField Name="Name" Type="String" />
                                                    </Fields>
                                                </ext:Model>
                                            </Model>
                                            <Sorters>
                                                <ext:DataSorter Property="ID" Direction="ASC" />
                                            </Sorters>
                                            <Listeners>
                                                <Write Handler="Ext.Msg.alert('Success', 'Data have been saved');" />
                                            </Listeners>
                                        </ext:Store>
                                    </Store>
                                    <ColumnModel ID="ColumnModel4" runat="server">
                                        <Columns>
                                            <ext:RowNumbererColumn runat="server" />
                                            <ext:Column runat="server" ID="Column4" DataIndex="Name" Flex="1">
                                                <Editor>
                                                    <ext:TextField runat="server" MinLength="2" />
                                                </Editor>
                                            </ext:Column>
                                        </Columns>
                                    </ColumnModel>
                                    <View>
                                        <ext:GridView ID="GridView4" runat="server" StripeRows="true" TrackOver="true" LoadMask="true" LoadingText="Department data loading..."/>
                                    </View>
                                    <SelectionModel>
                                        <ext:RowSelectionModel ID="RowSelectionModel4" runat="server" Mode="Single" />
                                    </SelectionModel>
                                    <Plugins>
                                        <ext:CellEditing runat="server" />
                                    </Plugins>
                                </ext:GridPanel>
                                <ext:ToolTip ID="ToolTip1" runat="server" Target="={#{gridpanelDepartment}.getView().el}" Html="Double click to edit" TrackMouse="true"/>
                            </Items>                                       
                        </ext:Panel>
                    </Items>
                </ext:Container>
            </Items>
        </ext:Viewport>
    </body>
    </html>
    Test.aspx.cs
    protected void Dept_BeforeChange(object sender, BeforeStoreChangedEventArgs e)
            {
                string json = e.DataHandler.JsonData;
                NewDMSDBDataContext db = new NewDMSDBDataContext();
                System.Data.Common.DbTransaction trans = null;
                StoreDataHandler dataHandler = new StoreDataHandler(json);
                List<Department> data = dataHandler.ObjectData<Department>();
                try
                {
                    if (db.Connection.State != System.Data.ConnectionState.Open)
                    {
                        db.Connection.Open();
                    }
                    trans = db.Connection.BeginTransaction();
                    db.Transaction = trans;
    
    
                    foreach (Department dept in data)
                    {
                        switch (e.Action)
                        {
                            case StoreAction.Destroy:
                                db.Department.Attach(dept);
                                db.Department.DeleteOnSubmit(dept);
                                break;
                            case StoreAction.Update:
                                db.Department.Attach(dept);
                                db.Refresh(RefreshMode.KeepCurrentValues, dept);
                                break;
                            case StoreAction.Create:
                                db.Department.InsertOnSubmit(dept);
                                break;
                        }
                    }
                    db.SubmitChanges(System.Data.Linq.ConflictMode.FailOnFirstConflict);
                    trans.Commit();
                    trans.Dispose();
                    db.Connection.Close();
                    if (e.Action != StoreAction.Destroy)
                    {
                        foreach (Department dept in data)
                        {
                            e.ResponseRecords.Add(dept);
                        }
                    }
                }
                catch (Exception exp)
                {
                    if (trans != null)
                    {
                        trans.Rollback();
                        X.Msg.Show(new MessageBoxConfig
                        {
                            Title = "Error",
                            Message = exp.Message,
                            Buttons = MessageBox.Button.OK,
                            Icon = MessageBox.Icon.ERROR
                        });
                    }
                    trans.Dispose();
                    db.Connection.Close();
                }
            }
            [DirectMethod]
            protected void Refresh(object sender, DirectEventArgs e)
            {
                string sType = e.ExtraParams["Type"];
                switch (sType)
                { 
                    case "Department":
                        storeDepartment.Reload();
                        break;
                    case "Panel1":
                        storePanel1.Reload();
                        break;
                }
            }
    Last edited by kfc427; Jun 21, 2013 at 6:24 AM.
  2. #2
    Hi @kfc427,

    Quote Originally Posted by kfc427 View Post
    ISSUE 1. Refresh button click will result in the gridpanel become blank. Is it OK invoke store.Reload() to refresh the gridpanel? If not, how can I implement the refresh function?
    A Store's OnReadData should be implemented to get a PagingToolbar's refresh button working.
    https://examples2.ext.net/#/GridPane...rayWithPaging/

    A Store's Reload method should also work if the above handler is implemented. By the way it can be called client side without a DirectEvent.
    store.reload();
    Quote Originally Posted by kfc427 View Post
    ISSUE 2. Once a new record added and click Save button, an exception will pop up each time whose content is
    But the new item is added in the DB. How to fix this exception?
    Click image for larger version. 

Name:	Ext-01.png 
Views:	33 
Size:	86.7 KB 
ID:	6427
    You should add this line:
    e.Cancel = true;
    You can see this line in the example that you mentioned. In this example it cancels the default logic of populating a save request's response (in particular, e.ResponseRecords). It is why the example is named "StoreCustomLogic".

    Quote Originally Posted by kfc427 View Post
    ISSUE 3. The Clear button cannot work expectedly
    According to
    <Click Handler="#{gridpanelDepartment}.getSelectionModel().deselectAll();" />
    it should just clear the current selection. Does it not clear?

    Quote Originally Posted by kfc427 View Post
    ISSUE 4. If some check on the submitted item, such as empty text, unaccepted characters and so on. Where it should be added?
    You can use validation on ModelFields level. Please see "Validations" here:
    http://docs.sencha.com/extjs/4.2.1/#!/guide/data
  3. #3
    Quote Originally Posted by Daniil View Post
    Hi @kfc427,



    A Store's OnReadData should be implemented to get a PagingToolbar's refresh button working.
    https://examples2.ext.net/#/GridPane...rayWithPaging/

    A Store's Reload method should also work if the above handler is implemented. By the way it can be called client side without a DirectEvent.
    store.reload();


    You should add this line:
    e.Cancel = true;
    You can see this line in the example that you mentioned. In this example it cancels the default logic of populating a save request's response (in particular, e.ResponseRecords). It is why the example is named "StoreCustomLogic".



    According to
    <Click Handler="#{gridpanelDepartment}.getSelectionModel().deselectAll();" />
    it should just clear the current selection. Does it not clear?



    You can use validation on ModelFields level. Please see "Validations" here:
    http://docs.sencha.com/extjs/4.2.1/#!/guide/data
    Hi Daniil,

    Thanks a lot for your detail illustration.

    Issue 1, the root cause was found out finally. The grid view does not refreshed results from Linq DB reading issues instead of Ext stuff. And the solution you presented works fine.

    Issue 2, other sample solutions in Ext.net official was adopted, so this issue is over.

    Issue 3, this function is not applied in new solution. So this issue is over as well.

    Issue 4, Add ValidateEdit in CellEditing section to validate the input texts. It meet my expectations, but I still want to know your solution (add Validation on the model of store) in more details. Could you please make an instance to specify data uniqueness checking? Thank you!
  4. #4
    Quote Originally Posted by kfc427 View Post
    Ibut I still want to know your solution (add Validation on the model of store) in more details. Could you please make an instance to specify data uniqueness checking?
    It cannot do such kind of validation. A validation function has access to a field's value only, not to all records.

    So, validating in ValidateEdit is nice for your case.
  5. #5
    Quote Originally Posted by Daniil View Post
    It cannot do such kind of validation. A validation function has access to a field's value only, not to all records.

    So, validating in ValidateEdit is nice for your case.
    Thanks Daniil!!
    all issues are clear now. Please close this thread.

Similar Threads

  1. [CLOSED] OnBeforeStoreChanged not firing
    By dheeraj_us in forum 1.x Legacy Premium Help
    Replies: 3
    Last Post: Aug 13, 2012, 6:05 PM
  2. Replies: 1
    Last Post: Jan 15, 2010, 12:55 PM
  3. [CLOSED] OnBeforeStoreChanged event problem
    By majestic in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Dec 25, 2009, 2:28 AM
  4. [CLOSED] OnBeforeStoreChanged and the Parameters collection.
    By tdracz in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Feb 05, 2009, 8:30 AM
  5. grid store OnBeforeStoreChanged event
    By [WP]joju in forum 1.x Help
    Replies: 5
    Last Post: Jan 08, 2009, 8:54 AM

Posting Permissions