[CLOSED] GridPanel - "select all" feature?

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] GridPanel - "select all" feature?

    Hi, Ext.NET

    Our users need to be able to manually select all the data from a GridPanel. And then paste the results somewhere else.

    Below is an example of a GridPanel ... the problem is that we can't ever get the "header row" to be selected.
    This is basically the column object's "text" property, which is the user friendly verbiage for the column's "dataindex".

    Is there a plugin or some configuration or JS logic that can achieve this? Thanks

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>
    <script runat="server">    
    
        protected void Page_Load(object sender, EventArgs e){
            if (!Page.IsPostBack && !X.IsAjaxRequest)
            {
                var gridCM = FPHGridPanel.ColumnModel;
                    gridCM.Add(new Column() { DataIndex = "LOCATION", Text = "LOCATION", Sortable = true, CellWrap = true, Align = ColumnAlign.Center });
                    var gridSummary = new Renderer() { Fn = "custSumRender" };
                    gridCM.Add(new Column() { DataIndex = "Healthy", Text = "Healthy", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Expiring (>3 but <= 6 months remaining)", Text = "Expiring (>3 but <= 6 months remaining)", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Expiring within 3 months", Text = "Expiring within 3 months", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Inactive Rep Qty", Text = "Inactive Rep Qty", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Completed", Text = "Completed", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Not Completed", Text = "Not Completed", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Ahead of Projected Burn Rate", Text = "Ahead of Projected Burn Rate", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "StatusTotal", Text = "", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = new Renderer() { Fn = "custGrandTotal" }, CellWrap = true, Align = ColumnAlign.Center, Renderer = new Renderer() { Fn= "sumColumnRender" } });
    
                var FPHStore2 = new Store();
                var FPHDataModel2 = new Model();
                FPHDataModel2.Fields.Add(new ModelField() { Name = "LOCATION", Type = ModelFieldType.String, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Healthy", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Expiring (>3 but <= 6 months remaining)", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Expiring within 3 months", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Inactive Rep Qty", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Completed", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Not Completed", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Ahead of Projected Burn Rate", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "StatusTotal", Type = ModelFieldType.Int });
    
    
                FPHStore2.Model.Add(FPHDataModel2);            
    
                var table = new DataTable();                        
    
                table.Columns.Add("LOCATION", typeof(string));
                table.Columns.Add("Healthy", typeof(int));
                table.Columns.Add("Expiring (>3 but <= 6 months remaining)", typeof(int));
                table.Columns.Add("Expiring within 3 months", typeof(int));
                table.Columns.Add("Inactive Rep Qty", typeof(int));
                table.Columns.Add("Completed", typeof(int));
                table.Columns.Add("Not Completed", typeof(int));
                table.Columns.Add("Ahead of Projected Burn Rate", typeof(int));            
    
                table.Rows.Add(new object[8] { "Samples in the Field at Risk", 100, 200, 300, 400, 500, 600, 700 });
                table.Rows.Add(new object[8] { "New Trained Rep", 200, 300, 300, 400, 500, 100, 200 });
                table.Rows.Add(new object[8] { "Zero Lctn", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn2", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn3", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn4", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn5", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn6", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Returning Product", 100, 200, 300, 400, 500, 600, 700 });
                table.Rows.Add(new object[8] { "Rep to Rep Transfers in Last 90 Days", 25, 200, 300, 77, 500, 489, 0 });
                table.Rows.Add(new object[8] { "Ahead of Projected Burn Rate", 25, 200, 300, 77, 500, 489, 0 });
                
                table.Columns.Add("StatusTotal", typeof(int));
                foreach (DataRow r in table.Rows)
                {
                    int statusTotal = 0;
    
                    for (int i= 0; i < table.Columns.Count; i++)
                    {
                        if (r[i].GetType() == typeof(int))
                        {
                            statusTotal += (int) r[i];
                        }
                    }                
                    r["StatusTotal"] = statusTotal;
                }
    
                FPHStore2.Data = table;
    
                FPHStore2.DataBind();
                //FPHStore2.FilterBy(new JFunction() { Fn = "custFilter" });
                FPHGridPanel.Store.Add(FPHStore2);
            }
            
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Select all from Grid Panel</title>    
    
        <script>
    
            var sumColumnRender = function (value, metadata, record, rowIndex, colIndex, store, gridView) {         
                return store.data.items[rowIndex].data["LOCATION"] + " Total:<br/>" + value;
            }
    
            var custSumRender = function (value, cols, colHeader, metadata) {
                return ('Total ' + colHeader + ':<br/>' + value);
            }
    
            var custGrandTotal = function (value, cols, colHeader, metadata) {
                return ('<b><i>Grand Total</i></b>:<br/>(<i>' + value + '</i>)');
            }
    
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />        
    
            <ext:GridPanel ID="FPHGridPanel" runat="server" 
                Border="false" 
                Title="TEST GRIDPANEL - user needs to select all (including header row) " 
                ForceFit="true">
                
                <Features>
                    <ext:Summary runat="server" ShowSummaryRow="true" />
                </Features>
    
                <View>
                    <ext:GridView EnableTextSelection="true" Selectable="true"></ext:GridView>
                </View>             
            </ext:GridPanel>
            
        </form>
    </body>
    </html>
    Last edited by fabricio.murta; May 17, 2019 at 5:42 PM.
  2. #2
    Hello @Caleb!

    Before we go to the actual example, in general terms, here's a couple ways you have to select all entries in a grid panel:

    - using the checkbox selection, you have a "select/deselect all" checkbox in the checkbox column's header.
    - using the selection model's selectAll() method.

    The first approach suggested above would allow for user interaction without further coding. The second allows you to programatically design your UI interface to select (and deselect) the rows in a grid, like clicking a button, or mapping a key combination.

    I'll review your example now, if something else shows up, I'll post again.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Hello again, @Caleb!

    After a shallow analysis of your sample, it seems you want to copy the whole grid, columns included, maybe like in CSV format.

    Fact is, if you just select the whole grid and ctrl+c, it does not really copies anything.

    There is, actually, a plug in to implement this, I believe the exact way you want it: The Clipboard grid plugin. And as you would see in the linked example, it needs to use the Spreadsheet Selection Model in order to enable the Clipboard plugin.

    The means to select all records in the last post is still actual, except you may trigger the selection by clicking the pivot header (top-left header cell).

    But if you want to keep the current selection model, you could fairly easy implement a logic to get the current selection, add the column names (rather, the fields' names) and then copy it to the clipboard with some available tricks.

    To get the currently selected records, you do, in javascript: App.FPHGridPanel.getSelectionModel().getSelection();

    This will give you an array of records, in which you can then get the fields' values within its data field:

    var sel = App.FPHGridPanel.getSelectionModel().getSelection();
    
    console.log(Object.keys(sel[0].data).join(","));
    
    for (var x in sel) {
        console.log(Object.values(sel[x].data).join(","));
    }
    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  4. #4
    Hi Fabricio,

    I think the spreadhsheet plugin that you mentioned is closest to what we're looking for. However, playing around with it I'm still not seeing the user friendly verbiage for each column's header.

    It seems to me that its only getting the data inside of the gridPanel's backing store. Which is 85% of what we need.
    I think I have implemented the Ext.NET code correctly.

    The last 15%, is the header text on top of each column.

    Try and click on the copy button in this demo. Paste into a notepad. It has all the data in the backing store, but not the header verbiage on top of the columns.

    Click image for larger version. 

Name:	MissingHeaders.png 
Views:	4 
Size:	46.2 KB 
ID:	25262

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>
    <script runat="server">    
    
        protected void Page_Load(object sender, EventArgs e){
            if (!Page.IsPostBack && !X.IsAjaxRequest)
            {
                var gridCM = FPHGridPanel.ColumnModel;
                    gridCM.Add(new Column() { DataIndex = "LOCATION", Text = "LOCATION", Sortable = true, CellWrap = true, Align = ColumnAlign.Center });
                    var gridSummary = new Renderer() { Fn = "custSumRender" };
                    gridCM.Add(new Column() { DataIndex = "Healthy", Text = "Healthy", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Expiring (>3 but <= 6 months remaining)", Text = "Expiring (>3 but <= 6 months remaining)", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Expiring within 3 months", Text = "Expiring within 3 months", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Inactive Rep Qty", Text = "Inactive Rep Qty", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Completed", Text = "Completed", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Not Completed", Text = "Not Completed", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "Ahead of Projected Burn Rate", Text = "Ahead of Projected Burn Rate", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = gridSummary, CellWrap = true, Align = ColumnAlign.Center });
                    gridCM.Add(new Column() { DataIndex = "StatusTotal", Text = "", Sortable = true, SummaryType = SummaryType.Sum, SummaryRenderer = new Renderer() { Fn = "custGrandTotal" }, CellWrap = true, Align = ColumnAlign.Center, Renderer = new Renderer() { Fn= "sumColumnRender" } });
    
                var FPHStore2 = new Store();
                var FPHDataModel2 = new Model();
                FPHDataModel2.Fields.Add(new ModelField() { Name = "LOCATION", Type = ModelFieldType.String, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Healthy", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Expiring (>3 but <= 6 months remaining)", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Expiring within 3 months", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Inactive Rep Qty", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Completed", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Not Completed", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "Ahead of Projected Burn Rate", Type = ModelFieldType.Int, });
                FPHDataModel2.Fields.Add(new ModelField() { Name = "StatusTotal", Type = ModelFieldType.Int });
    
    
                FPHStore2.Model.Add(FPHDataModel2);            
    
                var table = new DataTable();                        
    
                table.Columns.Add("LOCATION", typeof(string));
                table.Columns.Add("Healthy", typeof(int));
                table.Columns.Add("Expiring (>3 but <= 6 months remaining)", typeof(int));
                table.Columns.Add("Expiring within 3 months", typeof(int));
                table.Columns.Add("Inactive Rep Qty", typeof(int));
                table.Columns.Add("Completed", typeof(int));
                table.Columns.Add("Not Completed", typeof(int));
                table.Columns.Add("Ahead of Projected Burn Rate", typeof(int));            
    
                table.Rows.Add(new object[8] { "Samples in the Field at Risk", 100, 200, 300, 400, 500, 600, 700 });
                table.Rows.Add(new object[8] { "New Trained Rep", 200, 300, 300, 400, 500, 100, 200 });
                table.Rows.Add(new object[8] { "Zero Lctn", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn2", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn3", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn4", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn5", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Zero Lctn6", 0, 0, 0, 0, 0, 0, 0 });
                table.Rows.Add(new object[8] { "Returning Product", 100, 200, 300, 400, 500, 600, 700 });
                table.Rows.Add(new object[8] { "Rep to Rep Transfers in Last 90 Days", 25, 200, 300, 77, 500, 489, 0 });
                table.Rows.Add(new object[8] { "Ahead of Projected Burn Rate", 25, 200, 300, 77, 500, 489, 0 });
                
                table.Columns.Add("StatusTotal", typeof(int));
                foreach (DataRow r in table.Rows)
                {
                    int statusTotal = 0;
    
                    for (int i= 0; i < table.Columns.Count; i++)
                    {
                        if (r[i].GetType() == typeof(int))
                        {
                            statusTotal += (int) r[i];
                        }
                    }                
                    r["StatusTotal"] = statusTotal;
                }
    
                FPHStore2.Data = table;
    
                FPHStore2.DataBind();
                //FPHStore2.FilterBy(new JFunction() { Fn = "custFilter" });
                FPHGridPanel.Store.Add(FPHStore2);
            }
            
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Select all from Grid Panel</title>    
    
        <script>
    
            var sumColumnRender = function (value, metadata, record, rowIndex, colIndex, store, gridView) {         
                return store.data.items[rowIndex].data["LOCATION"] + " Total:<br/>" + value;
            }
    
            var custSumRender = function (value, cols, colHeader, metadata) {
                return ('Total ' + colHeader + ':<br/>' + value);
            }
    
            var custGrandTotal = function (value, cols, colHeader, metadata) {
                return ('<b><i>Grand Total</i></b>:<br/>(<i>' + value + '</i>)');
            }
    
            var copyClipboardData = function () {            
    
                if (!App.Spreadsheet_SelectionModel.hasSelection()) {
                    Ext.Msg.alert("No selection", "There is no selection");
                    return;
                }
    
                //cache X-clipboard plugin selection into temporary <textarea> -> so we can copy into OS clipboard
                const el = document.createElement('textarea');
                el.value = App.Clipboard_Plugin.getTextData("cell");
                el.setAttribute('readonly', '');
                el.style.position = 'absolute';
                el.style.left = '-9999px';
                document.body.appendChild(el);
                el.select();
                document.execCommand('copy');
                document.body.removeChild(el);                         
            };
    
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />        
    
            <ext:Button runat="server" Text="Explicit copy button" Handler="copyClipboardData"/>                    
    
            <ext:GridPanel ID="FPHGridPanel" runat="server" 
                Border="false" 
                Title="TEST GRIDPANEL - user needs to select all (including header row) " 
                ForceFit="true">
                
                <Features>
                    <ext:Summary runat="server" ShowSummaryRow="true" />
                </Features>
    
                <View>
                    <ext:GridView EnableTextSelection="true" Selectable="true"></ext:GridView>
                </View>             
    
                <SelectionModel>
                    <ext:SpreadsheetSelectionModel ID="Spreadsheet_SelectionModel" runat="server" />
                </SelectionModel>
                <Plugins>
                    <ext:Clipboard ID="Clipboard_Plugin" runat="server" />
                </Plugins>
    
            </ext:GridPanel>
            
        </form>
    </body>
    </html>
  5. #5
    also ... ideally when we click on the top left corner to perform the "select all" ... I'd like to be able to hook into that event, and add in the logic wired to the explicit copy button so everything implicitly copies into the user's clipboard.
    It's cleaner than having an extra button ...
  6. #6
    Hello @caleb!

    Thanks for the sample, I ran it and I believe I understand your issue well.

    Unfortunately that's a double no to your requests. Including the header in the copy is not possible (out of the box), was already asked in Sencha forums and is logged as a feature to be done. There's no builtin event you can tie to the top-left header cell, to make it do something else out of the ordinary.

    This does not mean it is impossible to do so, though.

    As for the first line, one way is just fetching the field names from the selected records and merging it with the copied text:

    el.value = Object.keys(App.FPHGridPanel.getStore().getAt(0).data).join("\t") + "\n" + App.Clipboard_Plugin.getTextData("cell");
    This would fail if there's no records in the store -- but you only want to trigger it when a selection is made, so at least one item should be in the store. It could be more elegant to fetch the column reference fields from the grid's view, which would also allow grabbing a handle of the number column in the spreadsheet view. But would need at least one explicit loop to get thru the columns to fetch their handles.

    As for capturing the click event in the top-left cell, I'll ask you a little time to figure out how it could be done (or better understand why it's not feasible to and share here).

    Hope this helps!
    Last edited by fabricio.murta; May 07, 2019 at 6:33 PM.
  7. #7
    Hello once again, @Caleb!

    Here's what you can do to tamper in the header click. In the code below, the toast will only be displayed when you click the top-left "toggle all" cell, and the action performed results in all cells selected.

    You can then replace that code with anything, like a dialog to confirm copy to clipboard. But I couldn't find any point in the code that would allow a proper event handling, this looks like the least intrusive approach, extending the selection model class with an override.

    Ext.define("spreadsheet_head_click", {
        override: "Ext.grid.selection.SpreadsheetModel",
        onHeaderClick: function (headerCt, header) {
            var me = this,
                isSelectAllCell = header === me.numbererColumn || header === me.checkColumn,
                sel;
    
            me.callParent(arguments);
    
            sel = me.selected;
            if (isSelectAllCell && sel && sel.isAllSelected()) {
                Ext.toast("Copy me!");
            }
        }
    });
    This will replace the behavior on all grids using spreadsheet model in your page, but you could just add a test against the owning grid's ID if that was the case.

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

    Thanks; everything almost works the way we need it to. One thing odd though, is the last summary row, which is dynamically calculated by a JS summary function, does not get picked up by the Clipboard plugin. So I tried to add it manually into our clipboard results, but the data from getSummaryRecord() is all 0. This ExtJS helper function must not be retrieving the record I'd expect.

    Is there another function I should be using to get the final summary row? Thanks.

    Here's the code section:

    Ext.define("spreadsheet_head_click", {
                override: "Ext.grid.selection.SpreadsheetModel",
                onHeaderClick: function (headerCt, header) {
                    var me = this,
                        isSelectAllCell = header === me.numbererColumn || header === me.checkColumn,
                        sel;
    
                    me.callParent(arguments);
    
                    sel = me.selected;
                    if (isSelectAllCell && sel && sel.isAllSelected()) {
                        Ext.toast("Flowpath Health Details Copied.");
                        copyClipboardData();
                    }
                }
            });
    
    
            var copyClipboardData = function () {            
    
                if (!App.Spreadsheet_SelectionModel.hasSelection()) {
                    Ext.Msg.alert("No selection", "There is no selection");
                    return;
                }
    
                //cache X-clipboard plugin selection into temporary <textarea> -> so we can copy into OS clipboard
                const el = document.createElement('textarea');
                el.value = Object.keys(App.FPHGridPanel.getStore().getAt(0).data).join("\t") + "\n" + App.Clipboard_Plugin.getTextData("cell") + "\n" + Object.values(App.FPHGridPanel.getStore().getSummaryRecord().data).join("\t"); ///somehow the summary record has all 0 values?
                el.setAttribute('readonly', '');
                el.style.position = 'absolute';
                el.style.left = '-9999px';
                document.body.appendChild(el);
                el.select();
                document.execCommand('copy');
                document.body.removeChild(el);                         
            };
  9. #9
    Hello @caleb!

    The query you made was to the model-level summary subsystem, using the Store's getSummaryRecord() method. You are instead using the grid's summary feature, which is bound to the grid only, affecting the grid and its view and not touching the store itself. Albeit the similar interface, they are not the same and are set up and triggered differently. Not disagreeing that this is easily confused, as even the summary record concept is retained between both.

    The right path to query the summary record from the grid panel's feature would then be either:

    App.FPHGridPanel.getView().summaryFeature.summaryRecord.data
    App.FPHGridPanel.features[0].summaryRecord.data
    This is going a little off the main topic of the thread (which is being able to copy data from a grid to clipboard), so if we need to further discuss issues with the summary, would you consider opening a new thread?

    Hope this helps, nonetheless!

    p.s.: notice in both approaches, accessing members not documented in Ext JS has no guarantee of working across updates, and won't list up as breaking change between releases if it becomes unavailable. I couldn't find a path to the summary record involving only documented methods and configs, or get-methods, so this may stop working in future releases without warning. The good news is that this is not very common, and if you keep up-to-date with Ext.NET releases, you are likely to get minimal impact when -- if ever -- this happens.
    Fabrício Murta
    Developer & Support Expert
  10. #10
    Hi Fabricio,

    Please feel free to close this ticket. The last insight you gave about the Grid's View property helped immensely. It was necessary to not only access the summary results of the grid. But also the best way to get the column headers. It had a getColumn() function that would read the collection of columns, according to whatever active order the user had placed their grid into. So if they re-shuffled the columns, this reflected that. But of course the order of the key-values did not change in the grid's actual record; which also ended up have some extraneous technical properties that don't show up in the grid. Thanks.
Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 0
    Last Post: Aug 09, 2016, 6:23 AM
  2. Replies: 4
    Last Post: Sep 14, 2015, 6:06 AM
  3. Replies: 2
    Last Post: Sep 12, 2015, 11:04 AM
  4. Replies: 1
    Last Post: Nov 12, 2012, 2:29 PM
  5. Replies: 4
    Last Post: Oct 11, 2011, 2:42 AM

Posting Permissions