MenuSelected event gets called twice in 5.1

Page 1 of 2 12 LastLast
  1. #1

    MenuSelected event gets called twice in 5.1

    I will put the code at the bottom so it's easier to read. In EXT 2.5, the MenuSelected event was always hit just once when the user clicked on a menu item. Now it is hit twice, causing the user to see a complete grid filled, then a flicker and a blank screen before seeing it filled a second time.

    I realize you might be in the dark somewhat as to how this is occurring, and the app is too large and complex to create a "simple" example of the issue as simple examples usually don't misbehave. I'm just hoping you might have an educated guess as to where we should look, or that this code is not compliant with EXT 5.1.

    Thanks, code below:

    Ext.define('Spotlight.controller.Menu', {
        extend: 'Spotlight.controller.Base',
    
        refs: [
           {
               ref: 'menuTree',
               selector: 'treepanel#panel-menu'
           },
        ],
    
        init: function () {
            
            
            this.listen({
    
                controller: {},
    
                component: {
    
                    '#panel-menu': {
                        afterrender: this.expandMenu,
    
                        afteritemexpand: this.selectDefault,
                        
                        select: this.menuSelected,
    
                        itemclick: this.menuSelected,
    
                        beforeselect: this.beforeselection,
                    }
                }
            })
        },
    
    
        /* UI Component Events */
    
        expandMenu: function (menu, eOpts) {
            menu.expandAll();
        },
    
        selectDefault: function (node, index, item, eOpts) {
            debugger;
            if (node.data.id == 8 || node.data.text == 'MRP Actions') {
                if (App.txtDept.getValue() == 'SUPPLIER') {
                    var defaultNode = this.getMenuTree().getStore().getRootNode().findChild("id", "31", true);
                    this.getMenuTree().getSelectionModel().select(defaultNode, true);
                }
                else {
                    var defaultNode = this.getMenuTree().getStore().getRootNode().findChild("id", "8", true);
                    this.getMenuTree().getSelectionModel().select(defaultNode, true);
                }
            }
        },
    
        menuSelected: function (menu, record, index, eOpts) {
            
            if (!record.data.leaf) return;
            //this.fireEvent('ViewSelected', record.data);
            //this.application.getPurchasingController().fireEvent('viewSelected', record.data)
            localStorage.removeItem('metachange'
            );
            //Event bus is not working. calling directly
            this.application.getPurchasingController().ViewSelected(record.data);
        },
    
        beforeselection: function (menu, record, index, eOpts) {
            if (record.data.leaf)
                return true;
    
            return false;
    }
    
    });
  2. #2
    Thanks for letting us know. We will investigate and try to reproduce the issue.
    Geoffrey McGill
    Founder
  3. #3
    Hello, rgraham!

    It fires twice because you have the event bound to both itemClick and select events. Bind the method to either event to have it hit once.

    This is the obvious guess I can make out of the example, and it makes sense if there's a "picker" like a picker component (like generic pickers, or form field date pickers). That particularity is due to a recent report of dual select event triggering from such components according to #1651 and #1673.

    What I mean with the above, is that the select event now fires in a more broad range of situations, and this might just be the case. In 2.x probably some situations where an item click did not result in a select event triggering now does it.

    Other than that, there's not much I can think about; I can hardly tell what component the code you shared below is extending, could be a multiselect box, combo box, grid view, and so on... Just don't bind the function to multiple events and it should stop firing multiple times.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  4. #4
    Hi Fabricio (and Geff),

    Yes, I noticed that there were two events calling the MenuSelected method, and I tried removing one of them. This did not fix the problem.

    I believe the problem actually stems from a DirectMethod function that one of our more ExtJs-experienced developers added to get our FilterHeaders working in EXT.NET 5.x. (Code at bottom). Strangely, the duplicate call problem does not occur on the original call to MenuSelected, only on subsequent calls.

    This is called from the js file for the Store connected with the grid. You'll see in the Proxy of the Spotlight.store.MRPActions definition that the URL for the grid is specified. I'm trying to find where this might be specified elsewhere, effectively calling the back-end twice. NOTE that this GenerateColumns direct method was not present or necessary in the EXT 2.5 version of our application. I will also attach an image of the grid and menu. Ignore the upper left grid in that image, it is only to show related data for the selected row in the main grid and is working fine.

    Below is the store definition first, which includes the call to the GenerateColumns DirectMethod. After that is the DirectMethod which is at the top of the Index.aspx page where this grid and it's associated Menu panel are.

    Ext.define('Spotlight.store.MRPActions', {
        //extend: 'Ext.data.Store',
        extend: 'Ext.data.BufferedStore',
        alias: 'store.MRPActions',
    
        requires: [
            'Spotlight.model.MRPAction',
        ],
    
        storeId: 'MRPActions',
    
        model: 'Spotlight.model.MRPAction',
        
        sorters: [
            {
                property: 'part_no',
                direction: 'ASC'
            }],
    
        //buffered: true,
        leadingBufferZone: 200,
        trailiningBufferZone: 200,
        pageSize: 50,
        autoSync: true,
        autoLoad: false,
        //remotePaging: true,
        remoteFilter: true,
        purgePageCount: 5,
        showWarningOnFailure: false,
      
        //plugins: {
        //    gridfilters: true
        //},
        listeners: {
            metachange: function (store, meta) {
                
                if (localStorage.getItem('metachange') == null) {
                  var grid = Ext.getCmp("mrpActionGrid");
                    localStorage.setItem('metachange', true);
               
                  App.direct.GenerateColumn(meta.columns);
                    //Ext.suspendLayouts();
    
                    //grid.reconfigure(null, meta.columns);
    
                    //Ext.resumeLayouts(true);
                    //var columns = meta.columns;
                    //var fields = meta.fields;
                    //for (var i = 0; i < columns.length; i++) {
                    //    for (var j = 0; j < fields.length; j++) {
                    //        if (columns[i].dataIndex == fields[j].name) {
    
                    //            var type = null;
                    //            if (fields[j].type == 'float' || fields[j].type == "int") {
                    //                type = 'number';
                    //            } else {
                    //                type = fields[j].type;
                    //            }
                    //            if (columns[i].dataIndex =='part_no')
                    //                grid.filters.addFilter({ dataIndex: columns[i].dataIndex, type: type,value:'BIO' });
                    //            else
                    //                grid.filters.addFilter({ dataIndex: columns[i].dataIndex, type: type });
    
                    //            break;
                    //        }
                    //    }
                    }
    
    
                  
            }
            //single: true
            },
            beforesort: function () {
                console.log("beforesort");
                Ext.getCmp('mrpActionGrid').getSelectionModel().deselectAll(true);
            },
            beforeprefetch: function () {
                Ext.getCmp('mrpActionGrid').getSelectionModel().deselectAll(true);
            },
        
        proxy: {
            type: 'ajax',
            url: '../../api/MrpAction',
            timeout: 60000,
            reader: {
                type: 'json',
                rootProperty: 'data',
                totalProperty: 'total'
            }
        },
    
    
    });
    Now the DirectMethod in the index.aspx page:
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <script runat="server">
        [DirectMethod]
        public void GenerateColumn(List<object> meta)
        {
            List<ColumnBase> columnBase = new List<ColumnBase>();
    
            var mrpActionGrid = (GridPanel)this.mrpActionControl.Controls[1].FindControl("mrpActionGrid");
            foreach (var columns in meta)
            {
                dynamic colProp = columns;
                string dataIndex = colProp.dataIndex;
                string text = colProp.text;
                string id = colProp.id;
                bool hidden = colProp.hidden;
                string width = colProp.width;
                string align = colProp.align;
                string xtype = colProp.xtype;
                bool locked = colProp.locked == null ? false : colProp.locked;
    
                switch (xtype)
                {
                    case "checkcolumn":
                        var checkCol = new BooleanColumn
                        {
                            Text = text,
                            ID = id,
                            DataIndex = dataIndex,
                            Hidden = hidden,
                            Width = new Unit(width),
                            TdCls = "x-cell",
                            Locked = locked,
                            Lockable = true
                        };
                        columnBase.Add(checkCol);
                        break;
                    case "numbercolumn":
                        var numCol = new NumberColumn
                        {
                            Text = text,
                            ID = id,
                            DataIndex = dataIndex,
                            Hidden = hidden,
                            Width = new Unit(width),
                            TdCls = "x-cell",
                            Lockable = true
                            // Locked  = locked
                        };
                        if (dataIndex.Equals("stdcost") || dataIndex.Equals("po_price") || dataIndex.Equals("tg_price"))
                        {
                            numCol.Format = "0.00000";
                        }
                        columnBase.Add(numCol);
                        break;
                    case "datecolumn":
                        var dtcol = new DateColumn
                        {
                            Text = text,
                            ID = id,
                            DataIndex = dataIndex,
                            Hidden = hidden,
                            Width = new Unit(width),
                            TdCls = "x-cell",
                            Locked  = locked,
                            Lockable = true
                        };
                        columnBase.Add(dtcol);
                        break;
                    default:
                        var col = new Column
                        {
                            Text = text,
                            ID = id,
                            DataIndex = dataIndex,
                            Hidden = hidden,
                            Width = new Unit(width),
                            TdCls = "x-cell",
                            Locked = locked,
                            Lockable = true
                        };
                        columnBase.Add(col);
                        break;
                }
    
            }
    
            //X.Js.Call("Ext.suspendLayouts");
            mrpActionGrid.Reconfigure(null, columnBase.ToArray());
            //X.Js.Call("Ext.resumeLayouts", true);
            X.Js.Call("applyFilter");
    
        }
    </script>
    Click image for larger version. 

Name:	Picture of grid and menu.jpg 
Views:	59 
Size:	101.5 KB 
ID:	25309
  5. #5
    Hi again gentlemen,

    I'm not sure if this is related to the issue, but at this line in the ext.axd code (see attached image), it seems to re-fire the menuSelected event. Perhaps after this two parallel event tracks are continuing on, resulting in the grid being cleared and reloaded at the end.

    I am new to ExtJs and EXT.NET so any help would be greatly appreciated. One of our remote developers who worked on the original, 2.5 version of this app fixed the missing FilterHeader functionality that we discovered when upgrading to EXT 5.x, but it's up to me to get the app ready for release and I am currently really stuck here.

    I have tried setting a localStorage item, and, if the view being called by the menu is the same as the current view, using a "return" line to exit the menuSelected event, but, while it does exit the event, the grid still reloads a second time after about a one second delay.

    Is there any official guidance on how to debug this application? It gets confusing trying to step through the ext code as I think sometimes I am seeing things being called on a timer, other times things that are the next operation in sequence.

    Currently I am using F10 and F8 when stepping through our code, and Shift + F11 to step out of ext.axd code that I have little idea how to read and have no power to alter.

    Do you ever do web meetings with screen sharing for paying customers?

    I also have an issue with a TreePanel nested deeply in a multi-tab dialog not fuctioning properly. I will open a separate thread for that...

    Click image for larger version. 

Name:	When the MenuSelected is called a second time.jpg 
Views:	44 
Size:	68.4 KB 
ID:	25310
  6. #6
    Hello @rgraham!

    Sorry you are still stuck with this issue. It is also hard for us to give you proper guidance given the clues are far from a runnable test case, so all we can do is try to help with guesses given our experience in Ext.NET and Ext JS altogether.

    As a piece of advice you might just be missing, there are two settings that would help you a lot to debug Ext.NET at client-side, where it seems you issue lies:

    Specify the ResourceManager with the SourceFormatting as true and ScriptMode as Debug.

    You can do this in a per-page scope (or master-page scope if you define your resource manager in the master page for WebForms code), or you can do this on a per-application scope in Web.config, within the extnet tag therein.

    If you've not been using it, I believe this will help a lot for you to unveil the ext.axd mystery. To "read" what an ext.axd resource is, read the URL before it; sometimes it read as /extnet-init-js/ (for t he page's "initialization" script run on page load), /extnet-all-js/ for extnet-specific client-side code; and /ext-all-js/ for Ext JS original code. This is all embedded resources dynamically linked by the very Ext.NET's ResourceManager I pointed above; for instance the ScriptMode="Debug" bit would transform, say /extnet-all-js/ AXD resource into /extnet-all-debug-js/; then it'd be much better when you step into those resources. CSS, images and javascript for further (on-demand) code is also added by the ResourceManager likewise.

    I hope this information is new to you and helps you to get into the issue troubleshooting. For the time being I'm afraid this is as much as I can say about the issue, but keep us posted on your findings, and we might get just what it takes to solve your issue.

    Maybe if you take the time to "shrink" the scenario to a smaller case wound not only help we help you, but better show you the reason it does not happen in the bigger picture. For instance, you mentioned FilterHeader feature not working in 5.1; we are not aware of the issue in hand; so maybe you wouldn't even need that override and it could be affecting how whatever you have triggering the select/itemClick event.

    Furthermore, to help you get the context where the event is being fired twice, you can add the method a debugger; line; this causes developer tools' debugger to stop at that line (you must have F12 developer tools open when running the page) once the event triggers, be it once, be it twice, it will stop each and every time the code is hit. Then you can compare the stack trace to see where the event is coming from!

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  7. #7
    Thank you. I am very familiar (10 years ++) with using Developer tools in all the major browsers, and putting debugger lines in the code.

    Please see the attached attachment, it shows dozens of lines of this each time the grid clears and reloads the second time.

    I'll be back with more details shortly.

    Click image for larger version. 

Name:	Error when reload.jpg 
Views:	38 
Size:	59.3 KB 
ID:	25311
  8. #8
    Hi again,

    I've located *when* the problem happens, it is immediately at the end of the DirectMethod below, when it hits the line "mrpActionGrid.Reconfigure(columnBase.ToArray( ));"

    We don't have an explicit "Reconfigure" method on our grid. Formerly this line was "mrpActionGrid.Reconfigure(null, columnBase.ToArray());" but I gather the "null" is not necessary or relevant.

    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <script runat="server">
        [DirectMethod]
        public void GenerateColumn(List<object> meta)
        {
            List<ColumnBase> columnBase = new List<ColumnBase>();
    
            var mrpActionGrid = (GridPanel)this.mrpActionControl.Controls[1].FindControl("mrpActionGrid");
            foreach (var columns in meta)
            {
                dynamic colProp = columns;
                string dataIndex = colProp.dataIndex;
                string text = colProp.text;
                string id = colProp.id;
                bool hidden = colProp.hidden;
                string width = colProp.width;
                string align = colProp.align;
                string xtype = colProp.xtype;
                bool locked = colProp.locked == null ? false : colProp.locked;
    
                switch (xtype)
                {
                    case "checkcolumn":
                        var checkCol = new BooleanColumn
                        {
                            Text = text,
                            ID = id,
                            DataIndex = dataIndex,
                            Hidden = hidden,
                            Width = new Unit(width),
                            TdCls = "x-cell",
                            Locked = locked,
                            Lockable = true
                        };
                        columnBase.Add(checkCol);
                        break;
                    case "numbercolumn":
                        var numCol = new NumberColumn
                        {
                            Text = text,
                            ID = id,
                            DataIndex = dataIndex,
                            Hidden = hidden,
                            Width = new Unit(width),
                            TdCls = "x-cell",
                            Lockable = true
                            // Locked  = locked
                        };
                        if (dataIndex.Equals("stdcost") || dataIndex.Equals("po_price") || dataIndex.Equals("tg_price"))
                        {
                            numCol.Format = "0.00000";
                        }
                        columnBase.Add(numCol);
                        break;
                    case "datecolumn":
                        var dtcol = new DateColumn
                        {
                            Text = text,
                            ID = id,
                            DataIndex = dataIndex,
                            Hidden = hidden,
                            Width = new Unit(width),
                            TdCls = "x-cell",
                            Locked  = locked,
                            Lockable = true
                        };
                        columnBase.Add(dtcol);
                        break;
                    default:
                        var col = new Column
                        {
                            Text = text,
                            ID = id,
                            DataIndex = dataIndex,
                            Hidden = hidden,
                            Width = new Unit(width),
                            TdCls = "x-cell",
                            Locked = locked,
                            Lockable = true
                        };
                        columnBase.Add(col);
                        break;
                }
    
            }
    
            //X.Js.Call("Ext.suspendLayouts");
            mrpActionGrid.Reconfigure(columnBase.ToArray());
            //X.Js.Call("Ext.resumeLayouts", true);
            //X.Js.Call("applyFilter");
    
        }
    </script>
  9. #9
    Hello again,

    Sorry the debugging tips didn't help at all, it was the only thing I could think about at the time.

    Now, I'm not really sure we are still in the problem originally reported. Is your issue still about the direct method that reconfigures the grid panel being called twice? I don't see anything that, just by reading, would suggest an error or an approach that should have been used in previous version and changed to Ext.NET 5 series.

    I will try to quote your statements from the recent posts you made and give a feedback for each. Let us know if I missed something you really wanted a feedback from.

    From post #4:

    Quote Originally Posted by rgraham
    Yes, I noticed that there were two events calling the MenuSelected method, and I tried removing one of them. This did not fix the problem.
    If this did not resolve the problem, which one of the two events is firing the MenuSelected() method twice? You could simply remove one for good, then, as they are quite redundant per se; and probably one of them is just ignored, totally?

    Quote Originally Posted by rgraham
    I believe the problem actually stems from a DirectMethod function that one of our more ExtJs-experienced developers added to get our FilterHeaders working in EXT.NET 5.x. (Code at bottom). Strangely, the duplicate call problem does not occur on the original call to MenuSelected, only on subsequent calls.
    This indicates a side effect of whatever is done in the direct method could be registering the event again.

    From post #5:

    Quote Originally Posted by rgraham
    I'm not sure if this is related to the issue, but at this line in the ext.axd code (see attached image), it seems to re-fire the menuSelected event. Perhaps after this two parallel event tracks are continuing on, resulting in the grid being cleared and reloaded at the end.
    That is a generic wrapper to fire events; you should look at the call stack for who's calling that. It is further up the call stack from what I can see in the screenshot (dispatch(), callParent(), dispatch()).

    Quote Originally Posted by rgraham
    One of our remote developers who worked on the original, 2.5 version of this app fixed the missing FilterHeader functionality that we discovered when upgrading to EXT 5.x
    I don't know of removing the FilterHeader feature since Ext.NET 2. We still have running examples using the feature in Ext.NET 5 Examples Explorers, so I can't see how a fix to the missing FilterHeader functionality could happen.

    Quote Originally Posted by rgraham
    I have tried setting a localStorage item, and, if the view being called by the menu is the same as the current view, using a "return" line to exit the menuSelected event, but, while it does exit the event, the grid still reloads a second time after about a one second delay.
    This looks like the doing of an Ext.defer() call coming somewhere. Does this mean the method is not being called twice, but the grid is still being "flashed" twice due to reloads/reconfigurements?

    Quote Originally Posted by rgraham
    Is there any official guidance on how to debug this application? It gets confusing trying to step through the ext code as I think sometimes I am seeing things being called on a timer, other times things that are the next operation in sequence.
    I believe all we could tell about debugging tips was shared in our last post.

    Quote Originally Posted by rgraham
    Currently I am using F10 and F8 when stepping through our code, and Shift + F11 to step out of ext.axd code that I have little idea how to read and have no power to alter.
    You do have power to override whatever you suspect as being the culprit, if just breaking within the code doesn't help. In general terms:

    Ext.define('my_override_name', {
        override: 'Full.Class.Name.To.Override',
        member1: value1,
        member2: value2
    }
    Once run, this would immediately take over code that would be called from within the ext.axd embedded javascript. You can just copy-paste the function code from the original into the new, and then make modifications as you feel fit.

    Quote Originally Posted by rgraham
    Do you ever do web meetings with screen sharing for paying customers?
    No, we don't. Historically this led to no progress and much frustration from the customers who we tried; very similar to this forum thread where many pages are consumed and little solution is reached; when we can't have the problem reduced to a test case, we can't simply learn the full stack solution implemented by the customer and identify therein the issue; our expertise lies in Ext.NET and the involved technology, we are also legally unable to look at proprietary code. Usually all we can look at is all that can be shared in a public forum thread like this. I sincerely hope you understand all involved.

    Quote Originally Posted by rgraham
    I also have an issue with a TreePanel nested deeply in a multi-tab dialog not fuctioning properly. I will open a separate thread for that...
    Yes, opening a new thread for another issue is the way to go, thanks! :)

    Now down to post #7:

    Quote Originally Posted by rgraham
    I am very familiar (10 years ++) with using Developer tools in all the major browsers, and putting debugger lines in the code.
    We didn't mean to suggest you were a bad developer, the post had as a base your claim from being "new to ExtJs and EXT.NET so any help would be greatly appreciated.", but both sharing some guidelines on debugging Ext.NET / Ext JS code, with an Ext.NET beginner in mind.

    Quote Originally Posted by rgraham
    Please see the attached attachment, it shows dozens of lines of this each time the grid clears and reloads the second time.
    The image related to the quote above shows a warning, and it may indicate that a similar action (not logged as warning though) may be re-registering the event that triggered the direct method originally reported when the grid gets reconfigured. In the specific warning, it may mean that two header items are present at a given time, for the same grid panel; this may mean at least a memory leak, if not a visual glitch. The header is an internal component of the grid panel -- that top bar that shows the column titles, where it is possible to interact with the grid, like sorting, reordering, filtering, etc; and may be related to the fix to said "missing feature related to FilterHeader" on previous posts).

    Going forward to your post #8:

    Quote Originally Posted by rgraham
    I've located *when* the problem happens, it is immediately at the end of the DirectMethod below, when it hits the line "mrpActionGrid.Reconfigure(columnBase.ToArray( ));"
    I personally can't see, with the information given and known context, how this could be the moment the issue triggers. This code doesn't immediately interacts with the client side code. A DirectMethod prepares a set of commands to be run at client-side when the method returns, and I am not sure how calling reconfigure will make it call the same direct method again and not make it call itself recursively and endlessly. I mean, if a call from the DirectMethod were making it re-call itself again, it should then call it once again, and again, and again, in an infinite loop, unless some kind of "loop guard" was present.

    Quote Originally Posted by rgraham
    We don't have an explicit "Reconfigure" method on our grid. Formerly this line was "mrpActionGrid.Reconfigure(null, columnBase.ToArray());" but I gather the "null" is not necessary or relevant.
    Ext.Net.GridPanel.Reconfigure(IEnumerable<ColumnBase> columns) is an overload that calls Ext.Net.GridPanel.Reconfigure((Ext.Net.AbstractStore)null, columns).

    This will make a client-side call to the Ext.grid.Panel.reconfigure() method in the returned script you can see if you watch the Network tab in your developer tools.

    I don't see anything clearly guilty of the issue by the code block you shared, nor I have means to run it given the missing context.

    snip

    This should be the best feedback I could give about the shared information so far in this thread. Hope you can make any usefulness of at least one of the responses.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  10. #10
    Hi Fabricio,

    Thanks for your reply.

    I will reply to your comments in a linear fashion, except for this first comment: The grid we are using has the infinite scrolling feature being used, it is only in this scenario that we have seen issues with the filter header not showing.

    Regarding your thoughts on Post # 4:
    I don't think the ItemClick event was necessary, so I removed it and kept only the Select event. The menu items are sometimes selected in code, such as in the expand event of a menu branch, so I thought it best to keep this one. This is working fine.

    Regarding Post #5:
    The direct method seems to break things after it calls this line: mrpActionGrid.Reconfigure(columnBase.ToArray());

    Does this mean the method is not being called twice, but the grid is still being "flashed" twice due to reloads/reconfigurements?
    Yes, I wonder if our code is not causing the duplicate load, but rather something internal to the ExtJS code. The question is how do we cause it to perhaps skip the first load pending the final Reconfigure?

    Yes, I knew about the ScriptMode="debug" option but the SourceFormatting="true" option helped to accelerate seeing the code "pretty" formatted.

    You do have power to override whatever you suspect as being the culprit, if just breaking within the code doesn't help. In general terms:

    Ext.define('my_override_name', {
    override: 'Full.Class.Name.To.Override',
    member1: value1,
    member2: value2
    }
    Is there an example of this on the EXT site? It might be easiest to cancel the line that originally loads the data the first time, though I would need to locate the exact line first.

    I do understand that screen sharing may not work for the reasons you outline.

    NEW THOUGHT: Is there any way for you to pinpoint the particular line that fills the grid once the data comes back from the server?

    I have mostly been using the Sources tab in Developer Tools but perhaps I need to be looking more closely at the Network tab or the Console

    Thanks, please do continue to help me!
Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 0
    Last Post: Apr 12, 2017, 11:49 AM
  2. Codebehind event called from Task
    By aluna in forum 1.x Help
    Replies: 1
    Last Post: May 12, 2016, 6:34 PM
  3. Replies: 3
    Last Post: Sep 26, 2014, 7:32 PM
  4. Replies: 2
    Last Post: Aug 30, 2012, 9:37 PM
  5. JavaScript has been called twice
    By harshad.jadhav in forum 1.x Help
    Replies: 3
    Last Post: Apr 21, 2010, 11:36 AM

Posting Permissions