Announcement

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

    ValuesManager.validate() inconsistent behavior with nested data

    SmartClient Version: v11.0p_2018-01-07/LGPL Development Only (built 2018-01-07)
    Chrome Version 64.0.3282.140 (Official Build) (64-bit)
    Ubuntu 16.4

    I found what appears to be inconsistent behavior in ValuesManager.validate() when there's nested data using DataSourceField.setTypeAsDataSource(). Consider this json:

    Code:
    {"gridRecords":[], "subFormData":{}}
    In the example below, I define a ListGrid with a required field and a form for editing the contents of subFormData via setDataPath. The problem comes when I try to validate. If there are no records under gridRecords, The valuesmanager incorrectly throws an error for gridField. This only happens when I include the form in the layout. If I comment out "addMember(subForm);" then the grid data isn't validated at all. After reviewing valuesManager.validate source code located on line 71810 in ISC_Forms.js, it appears that including the DynamicForm causes isDataPath to be set to true on line 71878, which triggers the inappropriate validation.

    Ideally, nested grid (IE setMultiple(true)) data should always be validated even when there's no form, and it should properly handle the array structure. If that's not possible, then it should at least handle the empty array condition correctly.

    Code:
    import com.google.gwt.core.shared.GWT;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.data.DataSourceField;
    import com.smartgwt.client.data.Record;
    import com.smartgwt.client.data.fields.DataSourceTextField;
    import com.smartgwt.client.util.JSON;
    import com.smartgwt.client.widgets.Button;
    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.form.DynamicForm;
    import com.smartgwt.client.widgets.form.ValuesManager;
    import com.smartgwt.client.widgets.form.fields.TextItem;
    import com.smartgwt.client.widgets.grid.ListGrid;
    import com.smartgwt.client.widgets.grid.ListGridField;
    
    public class TestWindow extends Window
    {
        private static class TopLevelDS extends DataSource
        {
            {
                final DataSourceField subFormData = new DataSourceField();
                subFormData.setName("subFormData");
                subFormData.setTypeAsDataSource(new DataSource());
    
                final DataSourceTextField gridField = new DataSourceTextField("gridField");
                gridField.setRequired(true);
                final DataSource gridDataSource = new DataSource();
                gridDataSource.setFields(gridField);
    
                final DataSourceField gridRecords = new DataSourceField();
                gridRecords.setName("gridRecords");
                gridRecords.setTypeAsDataSource(gridDataSource);
                gridRecords.setMultiple(true);
    
                setFields(subFormData, gridRecords);
            }
        }
    
        public TestWindow()
        {
            setWidth(300);
            setHeight(300);
    
            final ValuesManager vm = new ValuesManager();
            vm.setDataSource(new TopLevelDS());
    
            final DynamicForm subForm = new DynamicForm()
            {{
                setDataPath("subFormData");
                setValuesManager(vm);
                setFields(new TextItem("subFormField"));
            }};
    
            final ListGrid grid = new ListGrid()
            {{
                setDataPath("gridRecords");
                setValuesManager(vm);
                setFields(new ListGridField("gridField"));
                setCanEdit(true);
                setCanRemoveRecords(true);
            }};
    
            final Button validateButton = new Button("validate");
            validateButton.addClickHandler(new ClickHandler()
            {
                @Override
                public void onClick(ClickEvent clickEvent)
                {
                    GWT.log("vm.getValues(): " + JSON.encode(new Record(vm.getValues()).getJsObj()));
                    if (vm.validate())
                    {
                        GWT.log("NO ERRORS");
                    }
                    else
                    {
                        GWT.log("errors: " + vm.getErrors().toString());
                    }
                }
            });
    
            final Button addRowButton = new Button("add row");
            addRowButton.addClickHandler(new ClickHandler()
            {
                @Override
                public void onClick(ClickEvent clickEvent)
                {
                    grid.startEditingNew();
                }
            });
    
            setMembers(grid, validateButton, addRowButton);
            addMember(subForm); // this line changes the validation behavior
        }
    }
    Here's what the console looks like when I click the validate button:

    Code:
    vm.getValues(): {
        "gridRecords":[
        ],
        "subFormData":{
            "subFormField":null
        }
    }
    SuperDevModeLogger.java:71 errors: {gridRecords/gridField=Field is required}
    Thanks
    Last edited by jaysmith2020; 2 Mar 2018, 07:29.

    #2
    Just a note to say this is assigned to a developer to take a look. We'll follow up when we have any information for you

    Comment

    Working...
    X