Announcement

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

    ValuesManager disable validation

    I can't seem to get ValuesManager or DynamicForm to disable validation.

    My user story it to save a draft version of a record. On non-draft saves, all required fields must have values. For draft-save, the required fields are OK if empty but if they have values their format should pass other validators such as the regular expression for email addresses. So, Ideally I just want to disable the checks for 'required' but still run the other validations. But I can also get by with no validation at all for draft-saves.

    As I understand it from the docs, to disable all validation just takes a call to setDisableValidation(true) on the ValuesManager. But when I step through with a debugger, it gets to the saveData call and does not call the server-side code due to validation errors.

    (I'm using SmartGWT EE 2.5 nightly build, October 20. There are no errors / stack traces to report.)

    From constructor...
    Code:
    leftForm = makeLeftColumn();
    rightForm = makeRightColumn();
    
    valuesManager = new ValuesManager();
    valuesManager.setDataSource(DataSource.get(DATA_SOURCE));
    valuesManager.addMember(leftForm);
    valuesManager.addMember(rightForm);
    
    valuesManager.setDisableValidation(true);
    Save Draft button...
    Code:
    private Button makeSaveDraftButton() {
        final Button draft = new Button("Save Draft");
        draft.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                valuesManager.saveData(new DSCallback() {
                    @Override
                    public void execute(DSResponse dsResponse, Object o, DSRequest dsRequest) {
                        valuesManager.editRecord(dsResponse.getData()[0]);
                        SC.say("Draft saved.");
                    }
                });
            }
        });
        return draft;
    }
    Thanks in advance
    ,chris

    #2
    Since it's a nightly build, I upgraded to the latest smartgwt ee 2.5 eval nightly (November 1, 2011). Still get the same result. Validation continues to happen client-side.

    ,chris

    Comment


      #3
      Digging in the docs some more. I think I just need a custom DataSource.

      Comment


        #4
        So far no luck. I created a custom datasource that extends SQLDataSource (because all I want different is to ignore required field validation).
        What method should I override?

        The comments in the code sum up what I've found so far.

        DataSource config...
        Code:
        <DataSource
            ID="Thingy"
            tableName="thingy"
            dbName="Mysql"
            serverType="sql"
            serverConstructor="my.stuff.MyCustomDataSource"
            >
            ...
        MyCustomDataSource...
        Code:
        public class MyCustomDataSource extends SQLDataSource {
        
            @Override
            protected Object validateFieldValue(Map record, DSField field, Object value, ValidationContext context) throws Exception {
                // This is called for each field that has a value.
                return super.validateFieldValue(record, field, value, context);
            }
        
            @Override
            protected Object validateFieldValue(Map record, String fieldName, IType declaredType, Object value, ValidationContext context) throws Exception {
                // This is called for each field that has a value.
                return super.validateFieldValue(record, fieldName, declaredType, value, context);
            }
        
            @Override
            public ErrorReport validate(Map data, boolean reportMissingRequiredFields) throws Exception {
                // This is never called, but can we use "reportMissingRequiredFields" ???
                return super.validate(data, reportMissingRequiredFields);
            }
        
            @Override
            public DSResponse validateDSRequest(DSRequest dsRequest) throws Exception {
                // "partial" has no apparent affect.
                dsRequest.setValidationMode(ValidationMode.PARTIAL.getValue()); 
                
                // super.validateDSRequest(dsRequest) returns null DSResponse
                DSResponse dsResponse = super.validateDSRequest(dsRequest); 
                
                return dsResponse;
            }
        
            @Override
            public DSResponse executeUpdate(DSRequest req) throws Exception {
                // Never called if there are missing required fields.
                return super.executeUpdate(req);
            }
        
            @Override
            public DSResponse executeAdd(DSRequest req) throws Exception {
                // Never called if there are missing required fields.
                return super.executeAdd(req);
            }
        }

        Comment


          #5
          There's no way to selectively disable just required validation. Instead, don't mark the field as required in the .ds.xml, and handle the fact that they are conditionally required with business logic in a DMI or custom DataSource.

          Comment


            #6
            Thanks,

            I made the fields required="false" in the ds.xml file and changed my DMI as shown below.
            This works but causes a two-stage validation effect for the user. That is, my name & email fields are required. The email field also has regexp validation defined in the ds.xml file. So if name is blank and email is not blank but is invalid, then the user only sees the email validation error until it is fixed. After email is fixed, submitting shows the required validation on name.

            Is there any way to have validation ignored by smartgwt and then called in the DMI? That would allow me to control when the email validation happens and package all the errors in one response.

            Code:
            public DSResponse add(DSRequest dsRequest) throws Exception {
                if (!"DRAFT".equals(dsRequest.getAttribute("my_state"))) {
                    DSResponse dsResponse = checkRequiredFields(dsRequest, "name", "email");
                    if (!dsResponse.getErrors().isEmpty()) return dsResponse;
                }
                return dsRequest.execute();
            }
            
            private DSResponse checkRequiredFields(DSRequest dsRequest, String... attrNames) {
                DSResponse dsResponse = new DSResponse();
                for (String aName : attrNames) {
                    if (!satisfiesRequired(dsRequest, aName)) dsResponse.addError(aName, "Field is required.");
                }
                return dsResponse;
            }
            
            private boolean satisfiesRequired(DSRequest dsRequest, String attrName) {
                Map vals = dsRequest.getValues();
                if (!vals.containsKey(attrName)) return false;
                Object val = vals.get(attrName);
                return val != null && !"".equals(val);
            }
            ,chris

            Comment

            Working...
            X