[CLOSED] Store DataChanged listener doesn't fire on record removed

  1. #1

    [CLOSED] Store DataChanged listener doesn't fire on record removed

    Hi,

    This thread is related to the closed http://forums.ext.net/showthread.php...ogrammatically.
    What's the right listener to implement for a Store to capture both the record added and removed event? I've been trying to use the DataChanged but it only fires when a new record is added to the store. I need to observe the situation whereby the store is left empty to disable the Move All button. If there's a better way to achieve it, please suggest.

    Please refer to the code sample below.

    <%@ 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.Store1;
                object[] objLeft = new object[1000];
                object[] objRight = new object[10];
    
                for (int i = 0; i < 1000; i++)
                {
                    objLeft[i] = new object[] { i + 1, "Item " + (i + 1).ToString() };
                }
                store.DataSource = objLeft;
                store.DataBind();
    
                store = this.Store2;
                for (int i = 0; i < 10; i++)
                {
                    objRight[i] = new object[] { i + 5000, "Item " + (i + 5000).ToString() };
                }
                store.DataSource = objRight;
                store.DataBind();
    
                if (objLeft.Length == 0)
                {
                    this.ButtonAllLeft.Disabled = true;
                }
    
                if (objRight.Length == 0)
                {
                    this.ButtonAllRight.Disabled = true;
                }
    
                this.ButtonOneRight.Disabled = true;
                this.ButtonOneLeft.Disabled = true;
    
                //            this.Store1.Listeners.DataChanged.Handler = @"if(!#{Store2}) return;
                //                                if(#{Store2}.getTotalCount()==0)
                //                                    #{ButtonAllRight}.disable();";
                //            this.Store2.Listeners.DataChanged.Handler = @"if(!#{Store1}) return;
                //                                if(#{Store2}.getTotalCount()==0)
                //                                    #{ButtonAllRight}.disable();";
    
            }
        }
    </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>Overview of MultiSelect - Ext.NET Examples</title>
        <style type="text/css">
            .label
            {
                font: bold 11px tahoma,arial,sans-serif;
                width: 298px;
                height: 15px;
                padding: 5px 0;
                border: 1px dotted #99bbe8;
                color: #15428b;
                cursor: default;
                margin: 10px;
                background: #dfe8f6;
                text-align: center;
                margin-left: 0px;
            }
        </style>
        <ext:XScript ID="XScript1" runat="server">
        <script type="text/javascript" language="javascript">          
            var fromLeftToRight = function () {
                fromTo(#{LeftMultiSelect}, #{RightMultiSelect});
                #{ButtonOneRight}.disable();
                #{ButtonAllLeft}.enable();
    
                if(#{LeftMultiSelect}.view.store.getTotalCount()==0)
                    #{ButtonAllRight}.disable();
            };
                   
            var fromRightToLeft = function () {
                fromTo(#{RightMultiSelect}, #{LeftMultiSelect});
                #{ButtonOneLeft}.disable();
                #{ButtonAllRight}.enable();
    
                if(#{RightMultiSelect}.view.store.getTotalCount()==0)
                    #{ButtonAllLeft}.disable();
            };
                   
            var allFromLeftToRight = function () {
                moveAll(#{LeftMultiSelect}, #{RightMultiSelect});
                #{RightMultiSelect}.deselectAll();
                #{ButtonOneRight}.disable();
                #{ButtonAllRight}.disable();
                #{ButtonAllLeft}.enable();
            };
     
            var allFromRightToLeft = function () {
                moveAll(#{RightMultiSelect}, #{LeftMultiSelect});
                #{LeftMultiSelect}.deselectAll();
                #{ButtonOneLeft}.disable();
                #{ButtonAllLeft}.disable();
                #{ButtonAllRight}.enable();
            };
     
            var moveAll = function (fromMultiS, toMultiS) {
                if (toMultiS.disabled) return;
                var selectionsArray = fromMultiS.view.getSelectedIndexes();
                var records = fromMultiS.store.getAllRange();
                
                fromMultiS.view.store.suspendEvents(true);
                toMultiS.view.store.suspendEvents(true);
                  
                fromMultiS.view.store.remove(records);
                toMultiS.view.store.add(records);
                  
                fromMultiS.view.store.resumeEvents();
                toMultiS.view.store.resumeEvents();
                  
                toMultiS.view.refresh();
                fromMultiS.view.refresh();
                
                if (toMultiS.sortField)
                    toMultiS.store.sort(toMultiS.sortField, toMultiS.sortDir);
                
                if (toMultiS.allowDup)
                    fromMultiS.view.select(selectionsArray);
                else
                    toMultiS.view.select(selectionsArray);
            }
                   
            var fromTo = function (fromMultiS, toMultiS) {
                if (toMultiS.disabled) return;
                var selectionsArray = fromMultiS.view.getSelectedIndexes();
     
                var storeFrom = fromMultiS.view.store,
                    storeTo = toMultiS.view.store,
                    records = fromMultiS.view.getSelectedRecords();
     
                storeFrom.suspendEvents(true);
                storeFrom.remove(records);
                storeFrom.resumeEvents();
     
                storeTo.suspendEvents(true);
                storeTo.add(records);
                storeTo.resumeEvents();
    
                if (toMultiS.sortField)
                    toMultiS.store.sort(toMultiS.sortField, toMultiS.sortDir);
    
                if (toMultiS.allowDup)
                    fromMultiS.view.select(selectionsArray);
            };
        </script>
        </ext:XScript>
    </head>
    <body>
        <form id="Form1" runat="server">
        <ext:ResourceManager ID="ResourceManager1" runat="server" />
        <ext:Store ID="Store1" runat="server">
            <Reader>
                <ext:ArrayReader IDProperty="id">
                    <Fields>
                        <ext:RecordField Name="id" />
                        <ext:RecordField Name="value" />
                    </Fields>
                </ext:ArrayReader>
            </Reader>
            <Listeners>
                <DataChanged Handler="alert('Left changed');" />
            </Listeners>
        </ext:Store>
        <ext:Store ID="Store2" runat="server">
            <Reader>
                <ext:ArrayReader IDProperty="id">
                    <Fields>
                        <ext:RecordField Name="id" />
                        <ext:RecordField Name="value" />
                    </Fields>
                </ext:ArrayReader>
            </Reader>
            <Listeners>
                <DataChanged Handler="alert('Right changed');" />
            </Listeners>
        </ext:Store>
        <ext:Panel ID="Panel13" runat="server" Title="Drag/Drop (Insert Mode)" Padding="10">
            <Items>
                <ext:TableLayout ID="TableLayout5" runat="server" Columns="3">
                    <Cells>
                        <ext:Cell ColSpan="2">
                            <ext:Label ID="Label9" runat="server" Html="<div class='label'>Available Items</div>" />
                        </ext:Cell>
                        <ext:Cell>
                            <ext:Label ID="Label10" runat="server" Html="<div class='label'>Selected Items</div>" />
                        </ext:Cell>
                        <ext:Cell>
                            <ext:Panel ID="Panel14" runat="server" Border="false" BodyStyle="height: 260px;">
                                <Items>
                                    <ext:MultiSelect ID="LeftMultiSelect" runat="server" StoreID="Store1" DragGroup="grp1"
                                        DropGroup="grp2,grp1" DataIndex="id" DisplayField="value" Width="300" Height="250"
                                        KeepSelectionOnClick="WithCtrlKey" SortField="id">
                                        <Listeners>
                                            <Click Handler="if(this.view.getSelectedIndexes().length!=0)
                                                                #{ButtonOneRight}.enable();
                                                            else
                                                                #{ButtonOneRight}.disable();
                                                            #{ButtonAllRight}.enable();" />
                                        </Listeners>
                                    </ext:MultiSelect>
                                </Items>
                            </ext:Panel>
                        </ext:Cell>
                        <ext:Cell>
                            <ext:Panel ID="Panel1" runat="server" Border="false" Layout="VBoxLayout" BodyStyle="height: 260px;">
                                <Defaults>
                                    <ext:Parameter Name="margins" Value="5 0 5 0" Mode="Value" />
                                </Defaults>
                                <LayoutConfig>
                                    <ext:VBoxLayoutConfig Padding="5" Align="Center" Pack="Center" />
                                </LayoutConfig>
                                <Items>
                                    <ext:Button ID="ButtonOneRight" runat="server" Icon="ResultsetNext" Width="30" ToolTip="Select item(s)">
                                        <Listeners>
                                            <Click Handler="fromLeftToRight();" />
                                        </Listeners>
                                    </ext:Button>
                                    <ext:Button ID="ButtonAllRight" runat="server" Icon="ForwardBlue" Width="30" ToolTip="Select all items">
                                        <Listeners>
                                            <Click Handler="allFromLeftToRight();" />
                                        </Listeners>
                                    </ext:Button>
                                    <ext:Button ID="ButtonOneLeft" runat="server" Icon="ResultsetPrevious" Width="30"
                                        ToolTip="Deselect item(s)">
                                        <Listeners>
                                            <Click Handler="fromRightToLeft();" />
                                        </Listeners>
                                    </ext:Button>
                                    <ext:Button ID="ButtonAllLeft" runat="server" Icon="RewindBlue" Width="30" ToolTip="Deselect all items">
                                        <Listeners>
                                            <Click Handler="allFromRightToLeft();" />
                                        </Listeners>
                                    </ext:Button>
                                </Items>
                            </ext:Panel>
                        </ext:Cell>
                        <ext:Cell>
                            <ext:Panel ID="Panel15" runat="server" Border="false" BodyStyle="height: 260px;">
                                <Items>
                                    <ext:MultiSelect ID="RightMultiSelect" runat="server" StoreID="Store2" DragGroup="grp2"
                                        DropGroup="grp1,grp2" Width="300" Height="250" KeepSelectionOnClick="WithCtrlKey"
                                        DataIndex="id" DisplayField="value" SortField="id">
                                        <Listeners>
                                            <Click Handler="if(this.view.getSelectedIndexes().length!=0)
                                                                #{ButtonOneLeft}.enable();
                                                            else
                                                                #{ButtonOneLeft}.disable();
                                                            #{ButtonAllLeft}.enable();" />
                                        </Listeners>
                                    </ext:MultiSelect>
                                </Items>
                            </ext:Panel>
                        </ext:Cell>
                    </Cells>
                </ext:TableLayout>
            </Items>
        </ext:Panel>
        </form>
    </body>
    </html>
    Last edited by Daniil; Nov 07, 2012 at 12:54 PM. Reason: [CLOSED]
  2. #2
    Hi,

    I've found a pretty ugly workaround to achieve the needful behavior. I don't like this approach to say the least so if you have anything better to suggest, you'd be quite welcome :). The modifications are in the Store DataChanged listeners.

    <%@ 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.Store1;
                object[] objLeft = new object[1000];
                object[] objRight = new object[10];
    
                for (int i = 0; i < 1000; i++)
                {
                    objLeft[i] = new object[] { i + 1, "Item " + (i + 1).ToString() };
                }
                store.DataSource = objLeft;
                store.DataBind();
    
                store = this.Store2;
                for (int i = 0; i < 10; i++)
                {
                    objRight[i] = new object[] { i + 5000, "Item " + (i + 5000).ToString() };
                }
                store.DataSource = objRight;
                store.DataBind();
    
                if (objLeft.Length == 0)
                {
                    this.ButtonAllLeft.Disabled = true;
                }
    
                if (objRight.Length == 0)
                {
                    this.ButtonAllRight.Disabled = true;
                }
    
                this.ButtonOneRight.Disabled = true;
                this.ButtonOneLeft.Disabled = true;
            }
        }
    </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>Overview of MultiSelect - Ext.NET Examples</title>
        <style type="text/css">
            .label
            {
                font: bold 11px tahoma,arial,sans-serif;
                width: 298px;
                height: 15px;
                padding: 5px 0;
                border: 1px dotted #99bbe8;
                color: #15428b;
                cursor: default;
                margin: 10px;
                background: #dfe8f6;
                text-align: center;
                margin-left: 0px;
            }
        </style>
        <ext:XScript ID="XScript1" runat="server">
        <script type="text/javascript" language="javascript">          
            var fromLeftToRight = function () {
                fromTo(#{LeftMultiSelect}, #{RightMultiSelect});
                #{ButtonOneRight}.disable();
                #{ButtonAllLeft}.enable();
    
                if(#{LeftMultiSelect}.view.store.getTotalCount()==0)
                    #{ButtonAllRight}.disable();
            };
                   
            var fromRightToLeft = function () {
                fromTo(#{RightMultiSelect}, #{LeftMultiSelect});
                #{ButtonOneLeft}.disable();
                #{ButtonAllRight}.enable();
    
                if(#{RightMultiSelect}.view.store.getTotalCount()==0)
                    #{ButtonAllLeft}.disable();
            };
                   
            var allFromLeftToRight = function () {
                moveAll(#{LeftMultiSelect}, #{RightMultiSelect});
                #{RightMultiSelect}.deselectAll();
                #{ButtonOneRight}.disable();
                #{ButtonAllRight}.disable();
                #{ButtonAllLeft}.enable();
            };
     
            var allFromRightToLeft = function () {
                moveAll(#{RightMultiSelect}, #{LeftMultiSelect});
                #{LeftMultiSelect}.deselectAll();
                #{ButtonOneLeft}.disable();
                #{ButtonAllLeft}.disable();
                #{ButtonAllRight}.enable();
            };
     
            var moveAll = function (fromMultiS, toMultiS) {
                if (toMultiS.disabled) return;
                var selectionsArray = fromMultiS.view.getSelectedIndexes();
                var records = fromMultiS.store.getAllRange();
                
                fromMultiS.view.store.suspendEvents(true);
                toMultiS.view.store.suspendEvents(true);
                  
                fromMultiS.view.store.remove(records);
                toMultiS.view.store.add(records);
                  
                fromMultiS.view.store.resumeEvents();
                toMultiS.view.store.resumeEvents();
                  
                toMultiS.view.refresh();
                fromMultiS.view.refresh();
                
                if (toMultiS.sortField)
                    toMultiS.store.sort(toMultiS.sortField, toMultiS.sortDir);
                
                if (toMultiS.allowDup)
                    fromMultiS.view.select(selectionsArray);
                else
                    toMultiS.view.select(selectionsArray);
            }
                   
            var fromTo = function (fromMultiS, toMultiS) {
                if (toMultiS.disabled) return;
                var selectionsArray = fromMultiS.view.getSelectedIndexes();
     
                var storeFrom = fromMultiS.view.store,
                    storeTo = toMultiS.view.store,
                    records = fromMultiS.view.getSelectedRecords();
     
                storeFrom.suspendEvents(true);
                storeFrom.remove(records);
                storeFrom.resumeEvents();
     
                storeTo.suspendEvents(true);
                storeTo.add(records);
                storeTo.resumeEvents();
    
                if (toMultiS.sortField)
                    toMultiS.store.sort(toMultiS.sortField, toMultiS.sortDir);
    
                if (toMultiS.allowDup)
                    fromMultiS.view.select(selectionsArray);
            };
        </script>
        </ext:XScript>
    </head>
    <body>
        <form id="Form1" runat="server">
        <ext:ResourceManager ID="ResourceManager1" runat="server" />
        <ext:Store ID="Store1" runat="server">
            <Reader>
                <ext:ArrayReader IDProperty="id">
                    <Fields>
                        <ext:RecordField Name="id" />
                        <ext:RecordField Name="value" />
                    </Fields>
                </ext:ArrayReader>
            </Reader>
            <Listeners>
                <DataChanged Handler="if(typeof #{Store2} === 'undefined' || typeof #{ButtonAllRight} === 'undefined' || typeof #{ButtonAllLeft} === 'undefined') return;
                                    #{ButtonAllRight}.enable();
                                    if(#{Store2}.getTotalCount()==0)
                                        #{ButtonAllLeft}.disable();
                                    else
                                        #{ButtonAllLeft}.enable();" />
            </Listeners>
        </ext:Store>
        <ext:Store ID="Store2" runat="server">
            <Reader>
                <ext:ArrayReader IDProperty="id">
                    <Fields>
                        <ext:RecordField Name="id" />
                        <ext:RecordField Name="value" />
                    </Fields>
                </ext:ArrayReader>
            </Reader>
            <Listeners>
                <DataChanged Handler="if(typeof #{Store1} === 'undefined' || typeof #{ButtonAllRight} === 'undefined' || typeof #{ButtonAllLeft} === 'undefined') return;
                                    #{ButtonAllLeft}.enable();
                                    if(#{Store1}.getTotalCount()==0)
                                        #{ButtonAllRight}.disable();
                                    else
                                        #{ButtonAllRight}.enable();" />
            </Listeners>
        </ext:Store>
        <ext:Panel ID="Panel13" runat="server" Title="Drag/Drop (Insert Mode)" Padding="10">
            <Items>
                <ext:TableLayout ID="TableLayout5" runat="server" Columns="3">
                    <Cells>
                        <ext:Cell ColSpan="2">
                            <ext:Label ID="Label9" runat="server" Html="<div class='label'>Available Items</div>" />
                        </ext:Cell>
                        <ext:Cell>
                            <ext:Label ID="Label10" runat="server" Html="<div class='label'>Selected Items</div>" />
                        </ext:Cell>
                        <ext:Cell>
                            <ext:Panel ID="Panel14" runat="server" Border="false" BodyStyle="height: 260px;">
                                <Items>
                                    <ext:MultiSelect ID="LeftMultiSelect" runat="server" StoreID="Store1" DragGroup="grp1"
                                        DropGroup="grp2,grp1" DataIndex="id" DisplayField="value" Width="300" Height="250"
                                        KeepSelectionOnClick="WithCtrlKey" SortField="id">
                                        <Listeners>
                                            <Click Handler="if(this.view.getSelectedIndexes().length!=0)
                                                                #{ButtonOneRight}.enable();
                                                            else
                                                                #{ButtonOneRight}.disable();
                                                            #{ButtonAllRight}.enable();" />
                                        </Listeners>
                                    </ext:MultiSelect>
                                </Items>
                            </ext:Panel>
                        </ext:Cell>
                        <ext:Cell>
                            <ext:Panel ID="Panel1" runat="server" Border="false" Layout="VBoxLayout" BodyStyle="height: 260px;">
                                <Defaults>
                                    <ext:Parameter Name="margins" Value="5 0 5 0" Mode="Value" />
                                </Defaults>
                                <LayoutConfig>
                                    <ext:VBoxLayoutConfig Padding="5" Align="Center" Pack="Center" />
                                </LayoutConfig>
                                <Items>
                                    <ext:Button ID="ButtonOneRight" runat="server" Icon="ResultsetNext" Width="30" ToolTip="Select item(s)">
                                        <Listeners>
                                            <Click Handler="fromLeftToRight();" />
                                        </Listeners>
                                    </ext:Button>
                                    <ext:Button ID="ButtonAllRight" runat="server" Icon="ForwardBlue" Width="30" ToolTip="Select all items">
                                        <Listeners>
                                            <Click Handler="allFromLeftToRight();" />
                                        </Listeners>
                                    </ext:Button>
                                    <ext:Button ID="ButtonOneLeft" runat="server" Icon="ResultsetPrevious" Width="30"
                                        ToolTip="Deselect item(s)">
                                        <Listeners>
                                            <Click Handler="fromRightToLeft();" />
                                        </Listeners>
                                    </ext:Button>
                                    <ext:Button ID="ButtonAllLeft" runat="server" Icon="RewindBlue" Width="30" ToolTip="Deselect all items">
                                        <Listeners>
                                            <Click Handler="allFromRightToLeft();" />
                                        </Listeners>
                                    </ext:Button>
                                </Items>
                            </ext:Panel>
                        </ext:Cell>
                        <ext:Cell>
                            <ext:Panel ID="Panel15" runat="server" Border="false" BodyStyle="height: 260px;">
                                <Items>
                                    <ext:MultiSelect ID="RightMultiSelect" runat="server" StoreID="Store2" DragGroup="grp2"
                                        DropGroup="grp1,grp2" Width="300" Height="250" KeepSelectionOnClick="WithCtrlKey"
                                        DataIndex="id" DisplayField="value" SortField="id">
                                        <Listeners>
                                            <Click Handler="if(this.view.getSelectedIndexes().length!=0)
                                                                #{ButtonOneLeft}.enable();
                                                            else
                                                                #{ButtonOneLeft}.disable();
                                                            #{ButtonAllLeft}.enable();" />
                                        </Listeners>
                                    </ext:MultiSelect>
                                </Items>
                            </ext:Panel>
                        </ext:Cell>
                    </Cells>
                </ext:TableLayout>
            </Items>
        </ext:Panel>
        </form>
    </body>
    </html>
  3. #3
    Hi Vadym,

    Here is a doc article for the DataChanged event.
    http://docs.sencha.com/ext-js/3-4/#!...nt-datachanged

    Fires when the data cache has changed in a bulk manner (e.g., it has been sorted, filtered, etc.) and a widget that is using this Store as a Record cache should refresh its view.
    Not sure why it is triggered on adding a record. I guess sorting occurs.

    There are Add and Remove events you could use.
    http://docs.sencha.com/ext-js/3-4/#!...tore-event-add
    http://docs.sencha.com/ext-js/3-4/#!...e-event-remove
  4. #4
    Quote Originally Posted by Daniil View Post
    Hi Vadym,

    Here is a doc article for the DataChanged event.
    http://docs.sencha.com/ext-js/3-4/#!...nt-datachanged



    Not sure why it is triggered on adding a record. I guess sorting occurs.

    There are Add and Remove events you could use.
    http://docs.sencha.com/ext-js/3-4/#!...tore-event-add
    http://docs.sencha.com/ext-js/3-4/#!...e-event-remove
    Thanks Daniil, I've implemented the Remove listener since it seems much cleaner than DataChanged. On a related note, could you please explain what's the expected behavior of the KeepSelectionOnClick attribute? I've noticed that if it's set to WithCtrlKey, which is what I need, if one clicks on an empty area of the MultiSelect list (space below the last item), the selection disappears but the Click listener doesn't fire. Is there any good way to suppress this sequence or at least somehow catch this event? I'm trying to examine the length of selected items on MultiSelect click in order to toggle a button:

                                    
    <ext:MultiSelect ID="RightMultiSelect" runat="server" StoreID="StoreRight" DragGroup="grp2"
                                        DropGroup="grp1,grp2" Width="300" Height="250" KeepSelectionOnClick="WithCtrlKey"
                                        DataIndex="id" DisplayField="value" SortField="id">
             <Listeners>
                        <Click Handler="if(this.view.getSelectedIndexes().length!=0)
                                                       #{ButtonOneLeft}.enable();
                                                else
                                                       #{ButtonOneLeft}.disable();" />
             </Listeners>
    </ext:MultiSelect>
  5. #5
    Please set up this AfterRender listener for the MultiSelect.
    <AfterRender Handler="this.view.on('containerclick', function () { return false; });" />
  6. #6
    Quote Originally Posted by Daniil View Post
    Please set up this AfterRender listener for the MultiSelect.
    <AfterRender Handler="this.view.on('containerclick', function () { return false; });" />
    Thanks Daniil, that was it! Please mark this thread as closed.

Similar Threads

  1. [CLOSED] ToolTip Listener doesn't fire the event
    By sisa in forum 2.x Legacy Premium Help
    Replies: 5
    Last Post: Sep 10, 2012, 9:56 AM
  2. Save store doesn't fire CommitFailed event
    By Greg44 in forum 1.x Help
    Replies: 1
    Last Post: Apr 13, 2012, 4:15 PM
  3. Replies: 2
    Last Post: Mar 15, 2012, 12:57 AM
  4. Replies: 1
    Last Post: Nov 19, 2011, 8:32 AM

Tags for this Thread

Posting Permissions