New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store's OnBeforeStoreChanged event breaks itself after first trigger #1526

Closed
fabriciomurta opened this Issue Aug 9, 2017 · 0 comments

Comments

Projects
None yet
1 participant
@fabriciomurta
Contributor

fabriciomurta commented Aug 9, 2017

Found: 4.3.0
Ext.NET forum thread: Store's OnBeforeStoreChanged only fires once on first edit of Gridpanel, all other edits are "stuck" dirty

The store's OnBeforeStoreChanged server-side event handler does not trigger a second time when more than one changes are made by the cell editing plug in. At the second time it is called, client-side code at Ext.data.writer.Writer.getRecordData(), the call to me.getAllDataOptions() returns null instead of an empty object, which then triggers an error, interrupting further JavaScript code execution so the server-side call never completes.

A C# test case for this would be:

<%@ Page Language="C#" %>

<script runat="server">
    public class testClass
    {
        public int idProperty { get; set; }
        public string item1 { get; set; }
        public string item2 { get; set; }
        public string item3 { get; set; }

        public testClass(int idP, string i1, string i2, string i3)
        {
            idProperty = idP;
            item1 = i1;
            item2 = i2;
            item3 = i3;
        }
    }

    public static List<testClass> database;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!X.IsAjaxRequest)
        {
            // cleanup our "mockup" database when the page is loaded
            database = null;
        }
    }

    public void buildRows(object sender, DirectEventArgs e)
    {
        if (database == null)
        {
            database = new List<testClass>();
        }

        var lineList = database;
        var currentRows = lineList.Count;

        int newRows;

        if (!int.TryParse(nmbLines.Text, out newRows))
        {
            throw new Exception("Number of lines must be specified as an integer value.");
        }

        if (newRows > currentRows)
        {
            for (var i = currentRows+1; i <= newRows; i++)
            {
                var i_s = i.ToString();
                lineList.Add(new testClass(i, "thing1." + i_s, "thing2." + i_s, "thing3." + i_s));
            }
        }
        else if (newRows < currentRows)
        {
            lineList.RemoveRange(newRows, currentRows - newRows);
        }

        if (currentRows != lineList.Count)
        {
            database = lineList;
            storMain.DataSource = lineList;
            storMain.DataBind();
            grdMain.DataBind();
            updateRawRepost(lineList);
        }
    }

    public void handleChanges(object sender, BeforeStoreChangedEventArgs e)
    {
        var newlines = e.DataHandler.ObjectData<testClass>();

        if (e.Action == StoreAction.Update)
        {
            var listToUpdate = database;
            foreach (var updated in newlines)
            {
                foreach (var l in listToUpdate)
                {
                    if (l.idProperty == updated.idProperty)
                    {
                        l.item1 = updated.item1;
                        l.item2 = updated.item2;
                        l.item3 = updated.item3;
                    }
                }
            }

            database = listToUpdate;
            storMain.CommitChanges();
            grdMain.Refresh();
            updateRawRepost(listToUpdate);
        }
    }

    public void updateRawRepost(List<testClass> list)
    {
        if (list.Count > 0)
        {
            var rawDataText = "";
            foreach (var entry in list)
            {
                rawDataText = rawDataText + "line " + entry.idProperty.ToString() +
                    ", " + entry.item1 + ", " + entry.item2 + ", " + entry.item3 +
                    "<br />\n";
            }
            rawDataPnl.Html = rawDataText;
        } else
        {
            rawDataPnl.Html = "empty";
        }
    }
</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 runat="server">
    <ext:ResourceManager ID="ResourceManager1" runat="server" />
    <title>Ext.Net Test</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <ext:Viewport runat="server" >
            <Items>
                <ext:GridPanel runat="server" ID="grdMain" AutoDataBind="true" >
                    <Store>
                        <ext:Store runat="server" ID="storMain" AutoSync="true" OnBeforeStoreChanged="handleChanges">
                            <Model>
                                <ext:Model runat="server" >
                                    <Fields>
                                        <ext:ModelField Name="idProperty" Type="Int" />
                                        <ext:ModelField Name="item1" Type="String" />
                                        <ext:ModelField Name="item2" Type="String" />
                                        <ext:ModelField Name="item3" Type="String" />
                                    </Fields>
                                </ext:Model>
                            </Model>
                        </ext:Store>
                    </Store>
                    <TopBar>
                        <ext:Toolbar runat="server" >
                            <Items>
                                <ext:ToolbarFill runat="server" />
                                <ext:NumberField runat="server" ID="nmbLines" FieldLabel="# of Lines" Text="5" />
                                <ext:ToolbarSpacer Width="10" />
                                <ext:Button runat="server" Text="Add/Subtract Lines" >
                                    <DirectEvents>
                                        <Click OnEvent="buildRows" />
                                    </DirectEvents>
                                </ext:Button>
                            </Items>
                        </ext:Toolbar>
                    </TopBar>
                    <ColumnModel>
                        <Columns>
                            <ext:Column runat="server" DataIndex="idProperty" />
                            <ext:Column runat="server" DataIndex="item1" >
                                <Editor>
                                    <ext:TextField runat="server" ID="editItem1" />
                                </Editor>
                            </ext:Column>
                            <ext:Column runat="server" DataIndex="item2" >
                                <Editor>
                                    <ext:TextField runat="server" ID="editItem2" />
                                </Editor>
                            </ext:Column>
                            <ext:Column runat="server" DataIndex="item3" >
                                <Editor>
                                    <ext:TextField runat="server" ID="editItem3" />
                                </Editor>
                            </ext:Column>
                        </Columns>
                    </ColumnModel>
                    <Plugins>
                        <ext:CellEditing runat="server" >
                        </ext:CellEditing>
                    </Plugins>
                </ext:GridPanel>
                <ext:Panel runat="server" ID="rawDataPnl" Title="raw data" Html="empty" />
            </Items>
        </ext:Viewport>
    </div>
    </form>
</body>
</html>

To reproduce the issue:

  1. click the Add/Subtract Lines button,
  2. edit any record.
  3. as soon as editing completes (click other record, hit , click somewhere else) the raw data panel below is updated with the changed values
  4. edit another record (may be the same)
  5. JavaScript error will trigger due to null reference at the described method above.

@fabriciomurta fabriciomurta modified the milestones: 4.5.0, 4.4.0 Aug 9, 2017

@fabriciomurta fabriciomurta self-assigned this Aug 10, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment