Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Exporting wrong values

    Hi Isomorphic,

    in this case, "ListGrid.exportClientData" is not working properly.
    The values for the "Manager" field are incorrect.

    SmartClient Version: v12.0p_2019-12-14/PowerEdition Deployment (built 2019-12-14)

    BuiltInDS.java
    Code:
    package com.smartgwt.sample.client;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.Version;
    import com.smartgwt.client.core.KeyIdentifier;
    import com.smartgwt.client.data.DSRequest;
    import com.smartgwt.client.data.SortSpecifier;
    import com.smartgwt.client.rpc.RPCCallback;
    import com.smartgwt.client.rpc.RPCRequest;
    import com.smartgwt.client.rpc.RPCResponse;
    import com.smartgwt.client.types.ExportFormat;
    import com.smartgwt.client.types.SortDirection;
    import com.smartgwt.client.util.Page;
    import com.smartgwt.client.util.PageKeyHandler;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.Button;
    import com.smartgwt.client.widgets.IButton;
    import com.smartgwt.client.widgets.Window;
    import com.smartgwt.client.widgets.events.ClickEvent;
    import com.smartgwt.client.widgets.events.ClickHandler;
    import com.smartgwt.client.widgets.grid.ListGrid;
    import com.smartgwt.client.widgets.grid.ListGridField;
    import com.smartgwt.client.widgets.layout.VLayout;
    
    public class BuiltInDS extends VLayout implements EntryPoint {
        private IButton recreateBtn;
    
        public void onModuleLoad() {
            KeyIdentifier debugKey = new KeyIdentifier();
            debugKey.setCtrlKey(true);
            debugKey.setKeyName("D");
    
            Page.registerKey(debugKey, new PageKeyHandler() {
                public void execute(String keyName) {
                    SC.showConsole();
                }
            });
    
            setWidth100();
            setHeight100();
    
            recreateBtn = new IButton("Recreate");
            recreateBtn.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    new MyWindow().show();
                }
            });
            addMember(recreateBtn);
            new MyWindow().show();
            draw();
        }
    
        private class MyWindow extends Window {
            public MyWindow() {
                setWidth(400);
                setHeight(300);
                setMembersMargin(0);
                setModalMaskOpacity(70);
                setTitle(" (" + Version.getVersion() + "/" + Version.getSCVersionNumber() + ")");
                setTitle("img- vs object-tag issue" + getTitle());
                setShowMinimizeButton(false);
                setIsModal(true);
                setShowModalMask(true);
                centerInPage();
    
                ListGrid lg = new ListGrid();
                lg.setDataSource("employees");
    
                ListGridField userOrderLGF = new ListGridField("userOrder");
                ListGridField reportsToLGF = new ListGridField("ReportsTo");
                ListGridField emailLGF = new ListGridField("Email");
    
                lg.setFields(userOrderLGF, reportsToLGF, emailLGF);
                lg.setSort(new SortSpecifier("Email", SortDirection.ASCENDING));
                lg.fetchData();
    
                Button exportButton = new Button("Export data");
                exportButton.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        final DSRequest exportRequest = new DSRequest() {
                            {
                                setExportAs(ExportFormat.OOXML);
                                setExportFilename("Test");
                            }
                        };
    
                        SC.showPrompt("Test", "Test");
                        lg.exportClientData(exportRequest, new RPCCallback() {
                            @Override
                            public void execute(RPCResponse response, Object rawData, RPCRequest request) {
                                SC.clearPrompt();
                            }
                        });
                    }
                });
    
                addItem(lg);
                addItem(exportButton);
            }
        }
    }
    employees.ds.xml
    Code:
    <DataSource
        ID="employees"
        serverType="sql"
        tableName="employeeTable"
        recordName="employee"
        testFileName="/examples/shared/ds/test_data/employees.data.xml"
        titleField="Name"
    >
        <fields>
            <field name="userOrder"       title="userOrder"       type="integer"  canEdit="false"    hidden="true"/>
            <field name="Name"            title="Name"            type="text"     length="128"/>
            <field name="EmployeeId"      title="Employee ID"     type="integer"  primaryKey="true"  required="true"/>
            <field name="ReportsTo"       title="Manager"         type="integer"  required="true" 
                   foreignKey="employees.EmployeeId"  rootValue="1" displayField="EmployeeId" sortByField="Email"/>
            <field name="Job"             title="Title"           type="text"     length="128"/> 
            <field name="Email"           title="Email"           type="text"     length="128"/>
            <field name="EmployeeType"    title="Employee Type"   type="text"     length="40"/>
            <field name="EmployeeStatus"  title="Status"          type="text"     length="40"/>
            <field name="Salary"          title="Salary"          type="float"/>
            <field name="OrgUnit"         title="Org Unit"        type="text"     length="128"/>
            <field name="Gender"          title="Gender"          type="text"     length="7">
                <valueMap>
                    <value>male</value>
                    <value>female</value>
                </valueMap>
            </field>
            <field name="MaritalStatus"   title="Marital Status"  type="text"     length="10">
                <valueMap>
                    <value>married</value>
                    <value>single</value>
                </valueMap>
            </field>
        </fields>
    </DataSource>
    Best regards
    Pavo

    #2
    In what way are the values "incorrect"? Please be sure to explain your expectation when saying something is incorrect.

    In this case, you seem to have set things up so that raw IDs will be displayed for this field. Is that also what you wanted to see in your export?

    Comment


      #3
      I want to see in the export the same data I see in GUI.

      Click image for larger version

Name:	ListGrid.PNG
Views:	17
Size:	21.6 KB
ID:	261071

      For email "aandrews@server.com" value of the field "userOrder" is 31 and value of the field "Manager" is 269.

      If I export data from this ListGrid
      Click image for larger version

Name:	Export.PNG
Views:	15
Size:	3.7 KB
ID:	261072
      for email "aandrews@server.com" value of the field "Manager" is 190.

      I expect the data I see in ListGrid to be the same as the one I see when exporting the data.

      Best
      Pavo

      Comment


        #4
        Please take a look at the Export Formatting overview. You have options as to whether the displayField values are used or not; the defaults differ by export type.

        Comment


          #5
          Hi Isomorphic,

          I've missed that one. That's why my test case doesn't show the bug. INHO it should be by default that the exported data are the same as the one we see in ListGrid, but okay.

          Here is a new test case.

          BuiltInDS.java
          Code:
          package com.smartgwt.sample.client;
          
          import com.google.gwt.core.client.EntryPoint;
          import com.smartgwt.client.Version;
          import com.smartgwt.client.core.KeyIdentifier;
          import com.smartgwt.client.data.DSRequest;
          import com.smartgwt.client.data.SortSpecifier;
          import com.smartgwt.client.rpc.RPCCallback;
          import com.smartgwt.client.rpc.RPCRequest;
          import com.smartgwt.client.rpc.RPCResponse;
          import com.smartgwt.client.types.ExportFormat;
          import com.smartgwt.client.types.SortDirection;
          import com.smartgwt.client.util.Page;
          import com.smartgwt.client.util.PageKeyHandler;
          import com.smartgwt.client.util.SC;
          import com.smartgwt.client.widgets.Button;
          import com.smartgwt.client.widgets.IButton;
          import com.smartgwt.client.widgets.Window;
          import com.smartgwt.client.widgets.events.ClickEvent;
          import com.smartgwt.client.widgets.events.ClickHandler;
          import com.smartgwt.client.widgets.grid.ListGrid;
          import com.smartgwt.client.widgets.grid.ListGridField;
          import com.smartgwt.client.widgets.layout.VLayout;
          
          public class BuiltInDS extends VLayout implements EntryPoint {
              private IButton recreateBtn;
          
              public void onModuleLoad() {
                  KeyIdentifier debugKey = new KeyIdentifier();
                  debugKey.setCtrlKey(true);
                  debugKey.setKeyName("D");
          
                  Page.registerKey(debugKey, new PageKeyHandler() {
                      public void execute(String keyName) {
                          SC.showConsole();
                      }
                  });
          
                  setWidth100();
                  setHeight100();
          
                  recreateBtn = new IButton("Recreate");
                  recreateBtn.addClickHandler(new ClickHandler() {
                      @Override
                      public void onClick(ClickEvent event) {
                          new MyWindow().show();
                      }
                  });
                  addMember(recreateBtn);
                  new MyWindow().show();
                  draw();
              }
          
              private class MyWindow extends Window {
                  public MyWindow() {
                      setWidth(600);
                      setHeight(300);
                      setMembersMargin(0);
                      setModalMaskOpacity(70);
                      setTitle(" (" + Version.getVersion() + "/" + Version.getSCVersionNumber() + ")");
                      setTitle("img- vs object-tag issue" + getTitle());
                      setShowMinimizeButton(false);
                      setIsModal(true);
                      setShowModalMask(true);
                      centerInPage();
          
                      ListGrid lg = new ListGrid();
                      lg.setDataSource("employees");
          
                      ListGridField nameLGF = new ListGridField("Name");
                      ListGridField employeeIdLGF = new ListGridField("EmployeeId");
                      ListGridField reportsToLGF = new ListGridField("ReportsTo");
                      ListGridField emailLGF = new ListGridField("Email");
          
                      lg.setFields(nameLGF, employeeIdLGF, reportsToLGF, emailLGF);
                      lg.setSort(new SortSpecifier("Email", SortDirection.ASCENDING));
                      lg.fetchData();
          
                      Button exportButton = new Button("Export data");
                      exportButton.addClickHandler(new ClickHandler() {
                          @Override
                          public void onClick(ClickEvent event) {
                              final DSRequest exportRequest = new DSRequest() {
                                  {
                                      setExportAs(ExportFormat.OOXML);
                                      setExportFilename("Test");
                                      setExportValueFields(false);
                                  }
                              };
          
                              SC.showPrompt("Test", "Test");
                              lg.exportClientData(exportRequest, new RPCCallback() {
                                  @Override
                                  public void execute(RPCResponse response, Object rawData, RPCRequest request) {
                                      SC.clearPrompt();
                                  }
                              });
                          }
                      });
          
                      addItem(lg);
                      addItem(exportButton);
                  }
              }
          }
          employees.ds.xml
          Code:
          <DataSource
              ID="employees"
              serverType="sql"
              tableName="employeeTable"
              recordName="employee"
              testFileName="/examples/shared/ds/test_data/employees.data.xml"
              titleField="Name"
          >
              <fields>
                  <field name="userOrder"       title="userOrder"       type="integer"  canEdit="false"    hidden="true"/>
                  <field name="Name"            title="Name"            type="text"     length="128"/>
                  <field name="EmployeeId"      title="Employee ID"     type="integer"  primaryKey="true"  required="true"/>
                  <field name="ReportsTo"       title="Manager"         type="integer"  required="true"
                         foreignKey="employees.EmployeeId"  rootValue="1" displayField="ManagerEmail" />
                  <field name="ManagerEmail" includeFrom="employees.Email"/>              
                  <field name="Job"             title="Title"           type="text"     length="128"/>
                  <field name="Email"           title="Email"           type="text"     length="128"/>
                  <field name="EmployeeType"    title="Employee Type"   type="text"     length="40"/>
                  <field name="EmployeeStatus"  title="Status"          type="text"     length="40"/>
                  <field name="Salary"          title="Salary"          type="float"/>
                  <field name="OrgUnit"         title="Org Unit"        type="text"     length="128"/>
                  <field name="Gender"          title="Gender"          type="text"     length="7">
                      <valueMap>
                          <value>male</value>
                          <value>female</value>
                      </valueMap>
                  </field>
                  <field name="MaritalStatus"   title="Marital Status"  type="text"     length="10">
                      <valueMap>
                          <value>married</value>
                          <value>single</value>
                      </valueMap>
                  </field>
              </fields>
          </DataSource>
          Change "Email" of "Employeed ID: 190" to 1.
          Click image for larger version  Name:	Change data.PNG Views:	0 Size:	76.2 KB ID:	261086

          After you export data, field "Manager" of "Employee ID:269" is wrong. It's 190 and it should be 1.

          Click image for larger version  Name:	Wrong export data.PNG Views:	0 Size:	4.6 KB ID:	261087

          Very strange behavior:
          If the value of the field "Email" is number, a bug appears.
          If the value of the field "Email" is text, the bug does not appear.

          Best
          Pavo
          Last edited by pavo123; 12th Feb 2020, 04:35.

          Comment


            #6
            Just to clarify, you locally hacked the data so that someone's email address has been changed to the number 1 - which is invalid data since the field is type text - and that produces an export in which the numeric value is ignored.

            If so, that's not a bug. You changed the data to a number, which is the wrong type. You would not have been able to store that to the DataSource, it would have been turned into a string instead.

            Comment


              #7
              Hi Isomorphic,

              in our application this is the named level of a category and not a email-address.
              Entries in the category table have an sequence ID (much like employees), which never should be displayed, and a user chosen category value.
              Normally the chosen values are stuff like
              • id 100: cold, id 101: warm, id 101: hot
              • id 102: bronze, id 103: silber, id 104: gold
              • but here it is: id 105: 1, id 106: 2, id 107: 3
              In general it is a very valid use case to eventually have number data in string form - think of your SKUs in supplyItem. It should be obvious that the design of the test case was chosen to display the general problem, which is "client side exports of includeFrom fields display the ID instead, if the includeFrom-field data happens to be interpretable as a number".

              Best regards
              Blama

              Comment


                #8
                Having a number in String form is fine. But what would cause a problem here is putting a true Number in a field that is declared as type "text".

                That appears to be what you did, as far as we can tell.

                Comment


                  #9
                  Hi Isomorphic,

                  in the sample the field is
                  Code:
                  <field name="ManagerEmail" includeFrom="employees.Email"/>
                  The type-attribute comes via include from the Email field, so it is text.
                  The number 1 was edited with the GUI, so it should be text as well, but this shouldn't even matter - as soon as it is in the DB, is will be retrieved with the next fetch as text, as the type is text and as you can see all the other rows include text.

                  Best regards
                  Blama

                  Comment


                    #10
                    What's happening here is that during the export, we have a policy called "exportRawNumbers" that defaults to true for XLS and OOXML formats. Under this policy, if we see that the displayField value can be parsed as a double (which integers can), then instead of showing the displayField value, we use the underlying field's value instead. To avoid this, you can set the policy false by adding the starred line to your sample code above:
                    Code:
                    ListGridField nameLGF = new ListGridField("Name");
                    ListGridField employeeIdLGF = new ListGridField("EmployeeId");
                    ListGridField reportsToLGF = new ListGridField("ReportsTo");
                    ListGridField emailLGF = new ListGridField("Email");
                    reportsToLGF.setExportRawNumbers(false); // *** exportRawNumbers: false ***
                    For details see the docs here. You can also set it at the ListGrid level if that's easier.

                    Comment

                    Working...
                    X