Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Form Validation
Form Validation [message #1011785] Wed, 20 February 2013 03:58 Go to next message
Stathis Alexopoulos is currently offline Stathis Alexopoulos
Messages: 42
Registered: September 2010
Member
I want to have the following behavior from UI regarding the validation of fields.

Quote:
If there is at least one field having errorStatus with severity equals to ERROR, then the Button OK will be disabled.


In order to fullfill that expectation, i am calling the method setErrorStatus() inside execValidateValue() and execParseValue() methods and i have a decoration of field with the proper error or warning indicator.

Furthermore in my code any call to setErrorStatus() followed by a statement like
getOkButton().setEnabled( false);


In forms with many fields, or for a more reusable coding, i am implementing a setFieldErorStatus( IFormField, IProcessingStatus)) in any such form and inside that method i am implementing the expected behavior of the form.

But it seems to me that this expectation is quite common and involves more general validation expectations like updating statusbar, form subtitle, etc. and i was wondering if there is any mechanism implemented by Scout for such purposes.

For example, the setErrorStatus() method affecting the PROP_ERROR_STATUS property. Does form registers a listener on fields, and if yes, do you know a proper hook for that mechanism?

Re: Form Validation [message #1013871 is a reply to message #1011785] Sun, 24 February 2013 10:02 Go to previous messageGo to next message
Beat Schwarzentrub is currently offline Beat Schwarzentrub
Messages: 43
Registered: November 2010
Member
Stathis,

A form usually is not interessted in it's fields until some form event like "commit" or "cancel" occurs. But you can easily add your own listener to alle fields:

In your form, override execInitForm() and add something like this:

    ...
    // use the same listener for all fields
    PropertyChangeListener listener = new PropertyChangeListener() {
      @Override
      public void propertyChange(PropertyChangeEvent arg0) {
        // TODO Do something
      }
    };
    for (IFormField field : getAllFields()) {
      field.addPropertyChangeListener(IFormField.PROP_ERROR_STATUS, listener);
    }

Scout does not provide a mechanism like you described it. The "Scout way" is to leave the OK button enabled all the time and rather present a error message to the user when he clicks it.

Please think twice if it's really a good idea to disable the OK button. If you have a field with an error status and correct that error, you cannot press the OK button using the mouse because it is disabled. It won't be enabled until the field is validated, which is usually the case when the focus leaves the field - and that won't happen when you click on a disabled button.

Beat

Edit: added "code" markup

[Updated on: Sun, 24 February 2013 10:03]

Report message to a moderator

Re: Form Validation [message #1013906 is a reply to message #1013871] Sun, 24 February 2013 12:06 Go to previous messageGo to next message
Stathis Alexopoulos is currently offline Stathis Alexopoulos
Messages: 42
Registered: September 2010
Member
Thanks Beat for your answer,

Quote:
A form usually is not interessted in it's fields until some form event like "commit" or "cancel" occurs.

I think this is the answer in my question. Scout forms they dont want to interfere with fields until a "commit" Exclamation event happen. I still believe that it worths to implement a mechanism capable to handle GUI validation events, such as in FormData already implemented, but i suppose that i have to create a new topic for that.

As far as it concerns the rest of your answer,

Quote:
Please think twice if it's really a good idea to disable the OK button.

I forgot to mention that these forms must also have a Cancel Button. The user always has the option to cancel the edit procedure if she cannot provide valid data for every field. But i can think at least two more examples to have a validation mechanism for GUI


  • To simplify and promote an interactive GUI validation
  • To have dialogs or forms similar capable to provide messages as the attached screenshot.

index.php/fa/13532/0/

And finally, yes indeed i know that every form related class, in fact extends the AbstractPropertyObserver, so it is very easy to listen for every field or form change, that's why i asked if there is already implemented such kind of mechanism.

Quote:
For example, the setErrorStatus() method affecting the PROP_ERROR_STATUS property. Does form registers a listener on fields, and if yes, do you know a proper hook for that mechanism?

Just i thought to ask if there is already implemented something similar to FormData validation for the GUI, before i start the implementation of my own framewrok. I have already started implementing a validation framework using the hamcrest library, and if hopefully have any interesting result, i will share it with you.

Once more thanks for your answer.
Re: Form Validation [message #1015825 is a reply to message #1013906] Sun, 03 March 2013 04:50 Go to previous messageGo to next message
Lukas Huser is currently offline Lukas Huser
Messages: 40
Registered: March 2010
Member
Hi Stathis

Before you roll your own form validation framework, I would recommend to re-consider sticking with the default behavior of Scout. (Its simply much less work to do Smile)

With the Scout default behavior, you won't get a disabled Ok button, though. But maybe this is not too bad after all?

By default, when hitting the Ok button, Scout validates the form in various steps:
- Validation of form fields: Fields with error status, or empty mandatory fields are listed in the error message with a speaking description of the validation error. When confirming the error message, keyboard focus is automatically set on the first invalid field.
- Validation of the form itself (calling execValidate() on the form)
- Validation of the form handler (calling execValidate() on the current form handler)

If you want to disable the Ok button whenever a form is not valid, you probably need to handle all of the above cases for consistency. Simple value fields have the error status icon, which shows the error message as a tooltip, but it might not be so clear where you want to show the error message e.g. for table fields.

Quote:
To have dialogs or forms similar capable to provide messages as the attached screenshot.


You can achieve a similar effect with a separate label field which displays the error message combined with a string field in "validate on any key" mode.

index.php/fa/13648/0/

Code sample:

  @Order(10.0)
  public class MainBox extends AbstractGroupBox {

    @Order(10.0)
    public class GroupBox extends AbstractGroupBox {

      @Order(10.0)
      public class StatusField extends AbstractLabelField {

        @Override
        protected int getConfiguredGridW() {
          return 2;
        }
      }

      @Order(20.0)
      public class InputField extends AbstractStringField {

        @Override
        protected String getConfiguredLabel() {
          return TEXTS.get("Input");
        }

        @Override
        protected int getConfiguredGridW() {
          return 2;
        }

        @Override
        protected boolean getConfiguredValidateOnAnyKey() {
          return true;
        }

        @Override
        protected String execValidateValue(String rawValue) throws ProcessingException {
          if (StringUtility.hasText(rawValue) && rawValue.contains("foo")) {
            String errorText = TEXTS.get("InvalidValueMessageX", rawValue);
            getStatusField().setValue(errorText);
            getStatusField().setErrorStatus(errorText);
          }
          else {
            getStatusField().setValue(null);
            getStatusField().clearErrorStatus();
          }
          return rawValue;
        }
      }
    }
Re: Form Validation [message #1015854 is a reply to message #1015825] Sun, 03 March 2013 15:02 Go to previous messageGo to next message
Claudio Guglielmo is currently offline Claudio Guglielmo
Messages: 126
Registered: March 2010
Senior Member
Hi there

If you use the swt ui, you could use the eclipse forms IMessageManager instead of a label.
The advantage is: It looks good, it automatically handles stacking of multiple validation errors and you don't have to put it on every form by yourself.

index.php/fa/13649/0/

To make this work you need to implement some gui specific code. See the following code as example.

public class ValidationSwtScoutDialog extends SwtScoutDialog {
  private P_FieldValidationPropertyChangeListener m_validationListener;

  public ValidationSwtScoutDialog(Shell parentShell, ISwtEnvironment environment, int style) {
    super(parentShell, environment, style);
  }

  @Override
  protected void attachScout(IForm form) {
    super.attachScout(form);

    if (m_validationListener == null) {
      m_validationListener = new P_FieldValidationPropertyChangeListener();
    }
    for (IFormField f : form.getAllFields()) {
      f.addPropertyChangeListener(IFormField.PROP_ERROR_STATUS, m_validationListener);
    }
  }

  @Override
  protected void detachScout(IForm form) {
    super.detachScout(form);

    for (IFormField f : form.getAllFields()) {
      f.removePropertyChangeListener(IFormField.PROP_ERROR_STATUS, m_validationListener);
    }
  }

  private void handleFieldErrorStatusChanged(IFormField formField, IProcessingStatus errorStatus) {
    if (errorStatus == null) {
      getSwtForm().getMessageManager().removeMessage(formField);
    }
    else {
      getSwtForm().getMessageManager().addMessage(formField, errorStatus.getMessage(), null, IMessage.ERROR);
    }
  }

  private class P_FieldValidationPropertyChangeListener implements PropertyChangeListener {
    @Override
    public void propertyChange(final PropertyChangeEvent e) {
      Runnable t = new Runnable() {

        @Override
        public void run() {
          if (IFormField.PROP_ERROR_STATUS.equals(e.getPropertyName())) {
            handleFieldErrorStatusChanged((IFormField) e.getSource(), (IProcessingStatus) e.getNewValue());
          }

        }
      };
      getEnvironment().invokeSwtLater(t);
    }
  }// end private class
}


To make the header visible, you need to set a text on the eclipse form which can be done by setting a subtitle ond the model form (see SwtScoutForm#setTitleFromScout()).

public class ValidationTestForm extends AbstractForm {

  public ValidationTestForm() throws ProcessingException {
    super();
  }

  @Override
  protected String getConfiguredSubTitle() {
    return TEXTS.get("ValidationTest");
  }

  @Override
  protected String getConfiguredTitle() {
    return TEXTS.get("ValidationTest");
  }

  @Order(10.0)
  public class MainBox extends AbstractGroupBox {

    @Order(10.0)
    public class TextField extends AbstractTextField {

      @Override
      protected String getConfiguredLabel() {
        return TEXTS.get("Text");
      }

      @Override
      protected String execValidateValue(String rawValue) throws ProcessingException {
        if ("error".equals(rawValue)) {
          throw new VetoException("Field must not contain value error");
        }
        return null;
      }
    }
  // ....
  }
}


Have fun Smile
Re: Form Validation [message #1015932 is a reply to message #1015854] Mon, 04 March 2013 05:00 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 318
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Thanks for this interesting piece of code. Just two comments:

1. you need to overwrite SwtEnvironment.createSwtScoutDialog() to make it work
  @Override
  protected SwtScoutDialog createSwtScoutDialog(Shell shell, int dialogStyle) {
    return new ValidationSwtScoutDialog(shell, this, dialogStyle);
  }


2. it will only work with forms that are opened as dialogs but not with forms that are shown on a page

Still, it's an elegant way to show validation results!
Re: Form Validation [message #1015957 is a reply to message #1011785] Mon, 04 March 2013 07:14 Go to previous messageGo to next message
Claudio Guglielmo is currently offline Claudio Guglielmo
Messages: 126
Registered: March 2010
Senior Member
You're right, I forgot to mention that.

To make it work for views and editors too (which are used to display a form on a page), you just need to extend AbstractScoutView and AbstractScoutEditorPart. The code to insert should be more or less the same as for the dialog.
Re: Form Validation [message #1015980 is a reply to message #1015957] Mon, 04 March 2013 08:20 Go to previous messageGo to next message
Stathis Alexopoulos is currently offline Stathis Alexopoulos
Messages: 42
Registered: September 2010
Member
Thank you all,

I feel that i have to answer separately to each one of you.

@Loukas
Quote:

Before you roll your own form validation framework, I would recommend to re-consider sticking with the default behavior of Scout. (Its simply much less work to do )

I totally agree with you, and this is the reason that originally started this topic. I had already implemented a solution similar to yours, but when i realized that i had to repeated on every such field, i asked myself if there is already implemented and i missed it. And indeed i missed something. According to your explanation for field-by-field error correction, there is an alternate practice to "Hidden OK".

@Claudio
Yes, i am not using Swing. I am using just SWT and there are plans for some selected simple forms to deployed also in RAP. So, your solution it seems that fits perfectly for me, except that in my application there is no clear separation between dialogs and forms. Any form can also be used as a dialog, depending the action that initiated it.

For example i am implementing the CompanyDataEntryForm which normally appears in a TablePage responding to execRowsSelected(), but there is also an option for user to open it as a dialog from a link in the PersonDataEntryForm, which normally ...

@Urs
Thanks for the hint.

@Beat
Quote:
field.addPropertyChangeListener(IFormField.PROP_ERROR_STATUS, listener);

Last but not least. I think that in my first reply i overlooked the meaning of that line because finally came up with something similar.


Re: Form Validation [message #1016125 is a reply to message #1015957] Tue, 05 March 2013 02:33 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 318
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Claudio Guglielmo wrote on Mon, 04 March 2013 13:14
To make it work for views and editors too (which are used to display a form on a page), you just need to extend AbstractScoutView and AbstractScoutEditorPart. The code to insert should be more or less the same as for the dialog.


I assumed this would be possible but didn't have time to try to find out which classes to extend. Thanks a lot for providing them, I've extended them and it works perfectly.
Re: Form Validation [message #1016139 is a reply to message #1015980] Tue, 05 March 2013 03:16 Go to previous message
Claudio Guglielmo is currently offline Claudio Guglielmo
Messages: 126
Registered: March 2010
Senior Member
@Stathis
Quote:
Yes, i am not using Swing. I am using just SWT and there are plans for some selected simple forms to deployed also in RAP. So, your solution it seems that fits perfectly for me, except that in my application there is no clear separation between dialogs and forms. Any form can also be used as a dialog, depending the action that initiated it.

Just for clarification: It doesn't matter whether you use forms dispayed as dialogs or not. If the form should be opened as dialog, SwtScoutDialog is used to display it. If it should be opened as view, AbstractScoutView takes care about that. So just implement it on both and you're fine.
Previous Topic:Layout Management
Next Topic:Change order of traversal
Goto Forum:
  


Current Time: Fri Jul 25 21:05:34 EDT 2014

Powered by FUDForum. Page generated in 0.03891 seconds