Announcement

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

    Validation of DataSourceEnumFields with OptionDataSources

    Hallo,

    I'm having problems with the automatically generated isOneOf validator of a DataSourceEnumField.
    In my case, I have a ListGrid with an associated DynamicForm to enter the data. One field is a DataSourceEnumField with an OptionDataSource bound to it. The EnumField and the OptionDataSoruce create a SelectItem with the valid values for this field. Because the user can't enter an other (wrong) value there, I wouldn't need client side validation at all for this field. And because I'm using a REST DataSource, I must handle the server side validation my self.
    But so far, I couldn't find out, how to get rid of the automatically created isOneOf validator and get the following WARNs in the Developer Console:
    Code:
    16:49:11.194 [ERROR] [testcase.Showcase] 16:49:11.195:XRP3:WARN:validation:isOneOf validator specified with no specified list of options or valueMap - 
    validator will always fail. Field definition:{name: "employeeId", type: "enum", _typeDefaultsAdded: true, _simpleType: 
    Obj{name:enum}, validators: Array[1], title: "Employee Id", _titleAutoDerived: true}
    and
    Code:
    16:49:11.210 [ERROR] [testcase.Showcase] 16:49:11.196:XRP3:WARN:DataSource:isc_DataSource_0:isc_DataSource_0.employeeId: value: "4" failed on validator: 
    {type: "isOneOf", _generated: true, defaultErrorMessage: "Not a valid option"}
    So, is there a way to disable the isOneOf validator or let it take the valueMap from the OptionDataSource? Or is there maybe some other trick?

    The following sample code reproduces my problem using the datasources from the showcase.

    Code:
    package testcase.client;
    
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.data.fields.DataSourceEnumField;
    import com.smartgwt.client.data.fields.DataSourceIntegerField;
    import com.smartgwt.client.data.fields.DataSourceTextField;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.form.fields.FormItem;
    import com.smartgwt.client.widgets.grid.ListGrid;
    import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
    import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
    import com.smartgwt.client.widgets.layout.VLayout;
    
    
    
    public class FormGridValidation extends VLayout {
    	private DataSource mainDS;
    	private DataSource optionDS;
    	private DynamicForm form;
    	private ListGrid grid;
    
    	public FormGridValidation() {
    		mainDS = new DataSource();
    		mainDS.setRecordXPath("/List/teamMember");
    		DataSourceTextField dsfProjectCode = new DataSourceTextField("projectCode");
    		DataSourceEnumField dsfEmployee = new DataSourceEnumField("employeeId");
    		mainDS.setFields(dsfProjectCode, dsfEmployee);
    		mainDS.setDataURL("ds/test_data/teamMembers.data.xml");
    		
    		optionDS = new DataSource();
    		optionDS.setRecordXPath("/List/employee");
    		optionDS.setDataURL("ds/test_data/employees.data.xml");
    		DataSourceIntegerField dsfOptionEmployeeId = new DataSourceIntegerField(
    				"EmployeeId");
    		dsfOptionEmployeeId.setPrimaryKey(true);
    		DataSourceTextField dsfOptionEmployeeName = new DataSourceTextField(
    				"Name");
    		optionDS.setFields(dsfOptionEmployeeId, dsfOptionEmployeeName);
    		
    
    		form = new DynamicForm();
    		form.setDataSource(mainDS);
    		
    		FormItem item = form.getItem("employeeId");
    		item.setOptionDataSource(optionDS);
    		item.setValueField("EmployeeId");
    		item.setDisplayField("Name");
    		
    		grid = new ListGrid();
    		grid.setWidth(800);
    		grid.setHeight(400);
    		grid.setDataSource(mainDS);
    		grid.setAutoFetchData(true);
    		grid.addRecordClickHandler(new RecordClickHandler() {
    			public void onRecordClick(RecordClickEvent event) {
    				form.clearErrors(true);
    				form.editRecord(event.getRecord());
    				form.enable();
    			}
    		});
    
    		this.setWidth(800);
    		this.addMember(grid);
    		this.addMember(form);
    	}
    
    	protected void onInit() {
    	}
    }
    Thanks in advance
    Christian

    PS: I'm using SmartGWT 4.0.

    #2
    type="enum" is for use with valueMaps, not optionDataSource. For optionDataSource, simply declare the field's actual type (e.g. "text" or "int").

    See also the hasRelatedRecord validator if you want explicit validation, although as the docs for that validator explain, this is normally not needed.

    Comment


      #3
      Thanks for your reply.
      But, if I define my field as standard DataSourceTextField oder -IntField, how can I show the field as a SelectField in the form? So that the user can choose from the values of the optionDataSource?
      Christian

      Comment


        #4
        This is automatic if you have defined an optionDataSource or foreignKey. If it needs to be specified manually, use setEditorType().

        Comment


          #5
          Hallo,

          because the option datasource didn't automatically create a SelectField, I tried your two suggestions by adding the following lines to the code:
          1. Add a foreign key constraint
          Code:
          ...
          optionDS.setID("OptionDS");
          DataSourceIntegerField dsfEmployee = new DataSourceIntegerField("employeeId");
          dsfEmployee.setForeignKey("OptionDS.EmployeeId");
          ...
          2. Manually call setEditorType()
          Code:
          GWT.create(BeanFactory.FormItemMetaFactory.class);
          item.setEditorType(SelectItem.class);
          But I still have a standard TextField instead of a SelectField in the form. Where is my mistake?

          The full code again, now would be:
          Code:
          package testcase.client;
          
          import com.google.gwt.core.client.GWT;
          import com.smartgwt.client.bean.BeanFactory;
          import com.smartgwt.client.data.DataSource;
          import com.smartgwt.client.data.fields.DataSourceIntegerField;
          import com.smartgwt.client.data.fields.DataSourceTextField;
          import com.smartgwt.client.widgets.form.DynamicForm;
          import com.smartgwt.client.widgets.form.fields.FormItem;
          import com.smartgwt.client.widgets.form.fields.SelectItem;
          import com.smartgwt.client.widgets.grid.ListGrid;
          import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
          import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
          import com.smartgwt.client.widgets.layout.VLayout;
          
          
          
          public class FormGridValidation extends VLayout {
          	private DataSource mainDS;
          	private DataSource optionDS;
          	private DynamicForm form;
          	private ListGrid grid;
          
          	public FormGridValidation() {
          		GWT.create(BeanFactory.FormItemMetaFactory.class);
          		optionDS = new DataSource();
          		optionDS.setRecordXPath("/List/employee");
          		optionDS.setDataURL("ds/test_data/employees.data.xml");
          		DataSourceTextField dsfOptionEmployeeId = new DataSourceTextField(
          				"EmployeeId");
          		dsfOptionEmployeeId.setPrimaryKey(true);
          		DataSourceTextField dsfOptionEmployeeName = new DataSourceTextField(
          				"Name");
          		optionDS.setFields(dsfOptionEmployeeId, dsfOptionEmployeeName);
          		optionDS.setID("OptionDS");
          		
          		mainDS = new DataSource();
          		mainDS.setRecordXPath("/List/teamMember");
          		DataSourceTextField dsfProjectCode = new DataSourceTextField("projectCode");
          		DataSourceIntegerField dsfEmployee = new DataSourceIntegerField("employeeId");
          		dsfEmployee.setForeignKey("OptionDS.EmployeeId");
          		mainDS.setFields(dsfProjectCode, dsfEmployee);
          		mainDS.setDataURL("ds/test_data/teamMembers.data.xml");
          
          		form = new DynamicForm();
          		form.setDataSource(mainDS);
          		
          		FormItem item = form.getItem("employeeId");
          		item.setOptionDataSource(optionDS);
          		item.setValueField("EmployeeId");
          		item.setDisplayField("Name");
          		item.setEditorType(SelectItem.class);
          		
          		grid = new ListGrid();
          		grid.setWidth(800);
          		grid.setHeight(400);
          		grid.setDataSource(mainDS);
          		grid.setAutoFetchData(true);
          		grid.addRecordClickHandler(new RecordClickHandler() {
          			public void onRecordClick(RecordClickEvent event) {
          				form.clearErrors(true);
          				form.editRecord(event.getRecord());
          				form.enable();
          			}
          		});
          
          		this.setWidth(800);
          		this.addMember(grid);
          		this.addMember(form);
          	}
          
          	protected void onInit() {
          	}
          }
          Thanks
          Chris

          Comment


            #6
            See the QuickStart Guide, DataBinding chapter: do not attempt to modify items generates by the form after calling setDataSource(), provide your own items in addition to the DataSource instead.

            Comment


              #7
              Thanks for your help, it seems to work now.
              To summarize: If I want to have a SelectItem in my Form for a field with an associated option datasource, I must not try to redefine the automatically created field, but I must create a new one and assign the corresponding name attribute to it, so it will overwrite the automatically created one.
              I hope that this will also work for my real world problem and not just only the test case.
              My final code now is:
              Code:
              package testcase.client;
              
              import com.smartgwt.client.data.DataSource;
              import com.smartgwt.client.data.fields.DataSourceIntegerField;
              import com.smartgwt.client.data.fields.DataSourceTextField;
              import com.smartgwt.client.widgets.form.DynamicForm;
              import com.smartgwt.client.widgets.form.fields.SelectItem;
              import com.smartgwt.client.widgets.grid.ListGrid;
              import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
              import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
              import com.smartgwt.client.widgets.layout.VLayout;
              
              
              
              public class FormGridValidation extends VLayout {
              	private DataSource mainDS;
              	private DataSource optionDS;
              	private DynamicForm form;
              	private ListGrid grid;
              
              	public FormGridValidation() {
              		optionDS = new DataSource();
              		optionDS.setRecordXPath("/List/employee");
              		optionDS.setDataURL("ds/test_data/employees.data.xml");
              		DataSourceTextField dsfOptionEmployeeId = new DataSourceTextField(
              				"EmployeeId");
              		dsfOptionEmployeeId.setPrimaryKey(true);
              		DataSourceTextField dsfOptionEmployeeName = new DataSourceTextField(
              				"Name");
              		optionDS.setFields(dsfOptionEmployeeId, dsfOptionEmployeeName);
              		optionDS.setID("OptionDS");
              		
              		mainDS = new DataSource();
              		mainDS.setRecordXPath("/List/teamMember");
              		DataSourceTextField dsfProjectCode = new DataSourceTextField("projectCode");
              		DataSourceIntegerField dsfEmployee = new DataSourceIntegerField("employeeId");
              		dsfEmployee.setForeignKey("OptionDS.EmployeeId");
              		mainDS.setFields(dsfProjectCode, dsfEmployee);
              		mainDS.setDataURL("ds/test_data/teamMembers.data.xml");
              
              		form = new DynamicForm();
              		form.setDataSource(mainDS);
              		form.setUseAllDataSourceFields(true);
              		
              		SelectItem item = new SelectItem("employeeId", "mein Empoyee");
              		item.setOptionDataSource(optionDS);
              		item.setValueField("EmployeeId");
              		item.setDisplayField("Name");
              		form.setItems(item);
              		
              		grid = new ListGrid();
              		grid.setWidth(800);
              		grid.setHeight(400);
              		grid.setDataSource(mainDS);
              		grid.setAutoFetchData(true);
              		grid.addRecordClickHandler(new RecordClickHandler() {
              			public void onRecordClick(RecordClickEvent event) {
              				form.clearErrors(true);
              				form.editRecord(event.getRecord());
              				form.enable();
              			}
              		});
              
              		this.setWidth(800);
              		this.addMember(grid);
              		this.addMember(form);
              	}
              
              	protected void onInit() {
              	}
              }

              Comment

              Working...
              X