[CLOSED] getRowsValues and getRecordsValues always return id column even when visibleOnly = true

  1. #1

    [CLOSED] getRowsValues and getRecordsValues always return id column even when visibleOnly = true

    Hello,

    The store.getRecordsValues( { visibleOnly: true, grid: gridPanel }) and gridPanel.getRowsValues( { visibleOnly: true }) always shows the id column, even if it is not visible.

    Steps to reproduce (using sample code further below):
    1) Hide a column
    2) Press one of the buttons to get the values
    3) Look in firebug console for the values retrieved
    4) Note that the column that was hidden as step 1) is correctly not returned
    5) Note that the internal id column is returned.

    Why this is a problem for me:

    I am using this to export date to excel/csv etc, and don't want the internal id column showing up.

    Code:
    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            var data = new List<object>();
            
            for (int i = 0; i < 20; i++)
            {
                data.Add(new{ _internalId=i, Name="Rec "+i, Column1=i.ToString(), Column2=i.ToString()});
            }
    
            Store1.DataSource = data;
            Store1.DataBind();
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="HtmlForm" runat="server">
        <div>
            <ext:ResourceManager ID="ResourceManager1" runat="server" />
            
            <ext:Store ID="Store1" runat="server">
                <Reader>
                    <ext:JsonReader IDProperty="_internalId">
                        <Fields>
                            <ext:RecordField Name="Name" />
                            <ext:RecordField Name="Column1" />
                            <ext:RecordField Name="Column2" />
                            <ext:RecordField Name="_internalId" />
                        </Fields>
                    </ext:JsonReader>
                </Reader>
            </ext:Store>
            
            <ext:GridPanel 
                ID="GridPanel1" 
                runat="server" 
                StoreID="Store1"
                Width="500" 
                Height="400"
                Title="Hide a column and press one of the buttons">
                <ColumnModel>
                    <Columns>
                        <ext:Column Header="Record Name" DataIndex="Name" />
                        <ext:Column Header="Column 1" DataIndex="Column1" />
                        <ext:Column Header="Column 2" DataIndex="Column2" />
                    </Columns>
                </ColumnModel>
                <TopBar>
                    <ext:Toolbar ID="Toolbar" runat="server">
                        <Items>
                            <ext:Button ID="GetRows" runat="server" Text="getRecordsValues (view in firebug console)">
                                <Listeners>
                                    <Click Handler="console.log(#{Store1}.getRecordsValues({visibleOnly:true, grid:#{GridPanel1}}));" />
                                </Listeners>
                            </ext:Button>
                            <ext:Button ID="Button1" runat="server" Text="getRowsValues (view in firebug console)">
                                <Listeners>
                                    <Click Handler="console.log(#{GridPanel1}.getRowsValues({visibleOnly:true}));" />
                                </Listeners>
                            </ext:Button>
                        </Items>
                    </ext:Toolbar>
                </TopBar>
            </ext:GridPanel>
        </div>
        </form>
    </body>
    </html>
    Workaround
    Once I've got the data, I could loop through each row and remove the internal id column, but it would be nice if the getRecordsValues() and getRowsValues() does this instead.
    Last edited by Daniil; Jan 11, 2011 at 4:45 PM. Reason: [CLOSED]
  2. #2
    Hi,

    You can pass filterRecord and filterField functions to the config
    - filterRecord - function (record) - return false to exclude the record
    - filterField - function (record, fieldName, value) - return false to exclude the field for particular record
    grid.getRowsValues({
          visibleOnly : true,
          filterField : function (record, fieldName, value) {
                return record.store.metaId() != fieldName;
          }
    });
    Here is full list of that config
    // config :
    // - selectedOnly
    // - visibleOnly
    // - dirtyCellsOnly
    // - dirtyRowsOnly
    // - currentPageOnly
    // - filterRecord - function (record) - return false to exclude the record
    // - filterField - function (record, fieldName, value) - return false to exclude the field for particular record
  3. #3
    Many thanks for your swift response.

    I forgot to add in my original post that this is the area of code that I think is the issue:

    extnet-data-debug.js:

        getRecordsValues : function (options) {
            options = options || {};
    
            var records = (options.records ? options.records : (options.currentPageOnly ? this.getRange() : this.getAllRange())) || [],
                values = [],
                i;
    
            for (i = 0; i < records.length; i++) {
                var obj = {}, dataR;
                
                dataR = Ext.apply(obj, records[i].data);
    
                if (this.metaId()) {
                    obj[this.metaId()] = records[i].id;
                }
                            
                dataR = this.prepareRecord(dataR, records[i], options);
    
                if (!Ext.isEmptyObj(dataR)) {
                    values.push(dataR);
                }
            }
    
            return values;
        },
    In particular the bit that says
                if (this.metaId()) {
                    obj[this.metaId()] = records[i].id;
                }
    While your filtering suggestion is great and will work, it doesn't feel right that the id is added to the list of records when the option to only show visible is set to true (and the id is not visible)? It is also an extra bit of code for each row that may not be needed if there is a way to not add the id to the "obj".

    I was going to suggest that as well as doing if (this.metaId()) to also add that if visible option is true only then add it, but I can see in many cases the id will be hidden but would also need to be added, so perhaps another option could be added, that is something like alwaysIncludeRecordId -- default true for backward compatibility?

    If you think my use case is quite rare then am happy to stick with the filter suggestion. (I can imagine that in the export scenario if someone wants visible fields only and id is hidden then it should remain hidden. I just can't tell whether the export scenario is a common use case for the grid...)

    Thanks!
  4. #4
    Hi,

    'excludeId' option is added to the 'getRowsValues' method
    Please update from SVN
  5. #5
    Hi Vladimir,

    Just tried it. Unfortunately it did not work.

    Using the example in my first post, I updated the click handlers to include the excludeId:true bit, as per this example:
    <Click  Handler="console.log(#{Store1}.getRecordsValues({visibleOnly:true,  excludeId:true, grid:#{GridPanel1}}));" />
    Upon closer inspection it looks like getRowsValues and getRecordsValues work with your change, but they both pass to prepareRecord.

    From what I can tell, the problem could be inside prepareRecord(), towards the end of that function:

            if (options.mappings !== false && this.saveMappings !== false) {
                var m,
                    map = record.fields.map, 
                    mappings = {};
                
                Ext.iterate(data, function (prop, value) {            
                    m = map[prop];
    
                    if (m) {
                        mappings[m.mapping ? m.mapping : m.name] = value;
                    }
                }); 
                mappings[this.metaId()] = record.id; 
                data = mappings;
            }
    I have not explicitly set the options.mapping or options.saveMappings to true or false, so it falls into this block of code. Then eventually it sets the Id.

    If I update the click handler to set saveMappings to false in the store, and set the options.mapping to false, then it does work:

    <Click Handler="#{Store1}.saveMappings = false;  console.log(#{Store1}.getRecordsValues({visibleOnly:true,  excludeId:true, mapping:false, grid:#{GridPanel1}}));" />
    But I could not find "saveMappings" in your extension to Store (I searched the whole solution - it was only used here) or the ExtJs documentation, so I wasn't sure what else it does or what other implication it has if I set it. (Also, what does option.mapping do? I couldn't see that in the list of options you mentioned earlier.)

    Maybe the excludeId option you added also has to be applied to the prepareRecord() method in the line shown above where the metaId is set?
  6. #6
    Hi,

    Yes, I forgot about mappings. I changed prepareRecord method, please update again
  7. #7
    Vladimir. Thanks for the update. That is working fine now. You can mark this as solved or fixed...!

Similar Threads

  1. Replies: 4
    Last Post: Jul 25, 2012, 5:45 AM
  2. [CLOSED] Checkbox return true/false
    By Jurke in forum 1.x Legacy Premium Help
    Replies: 3
    Last Post: Oct 04, 2011, 5:42 AM
  3. [CLOSED] getRecordsValues now uses Mapping instead of Name
    By wazige in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Mar 07, 2011, 1:54 PM
  4. Replies: 3
    Last Post: Aug 15, 2009, 2:55 PM

Tags for this Thread

Posting Permissions