Giter Club home page Giter Club logo

Comments (33)

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024 2

@Lesilva this can be done using Mode.BURST itself. The failure callback returns you the list of ValidationError objects. Instead of calling the validationError.getErrorMessage(Context) message, call the validationError.getFailedRules() method. From the list of failed Rules, get the message for the first failed rule by calling the rule.getMessage(Context) and display that message only.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@tomber71 You can use the Validator.setValidationMode(Mode.IMMEDIATE) to achieve that. Let me know if this helps. Thanks.

from android-saripaar.

 avatar commented on August 14, 2024

Thanks for your reply. Mode.IMMEDIATE does not actually solve my problem. This mode processes all rules of an failing view and does not stop after the first failed verification.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@tomber71 Just as I anticipated, this was a nightmare waiting to happen 😈

Mode.IMMEDIATE does what you want, but you aren't getting the expected result because the annotations themselves don't have a definite order.

In Saripaar, the rules were ordered using the order attribute in the rule annotation itself, so if the first rule fails it would stop. However, in Saripaar v2, I decided to order fields instead using the @Order annotation. This is causing problems now. The idea is to balance between a cleaner API and functionality.

This is how you'd do it in Saripaar,

    @Required(order = 1)
    @TextRule(order = 2, minLength = 3)
    private EditText mNameEditText;

    @Email(order = 3)
    private EditText mEmailEditText;

In Saripaar v2, in order to implement this feature we have to do something like this.

    @NotEmpty(sequence = 1)        // This is redundant, but just for illustration
    @Size(sequence = 2, min = 3)
    @Order(1)
    private EditText mNameEditText;

    @Email
    @Order(2)
    private EditText mEmailEditText;

Here the sequence attribute specifies the sequence in which the rules must be validated for the mNameEditText and is optional. It's helpful when using along with QuickRules and having a definite order while validation. However, it makes the API clunky.

What do you have in mind?

from android-saripaar.

 avatar commented on August 14, 2024

It has never been my intention to cause any nightmares 😉. I was only wondering if there is a way of covering my use case with Saripaar v2. But actually I can solve it quite easily by creating separate background tasks for long running verification (e.g. some backend checks) and start them after a successful (now strictly synchronous) Saripaar verification.

IMHO you should definitely avoid a multiple level ordering (view and rule based) as suggested with the sequence attribute. But I don't understand the advantage of a view based ordering as I suppose you can derive the same necessary information from a rule sequence (e.g. if you want to execute the verification until a certain view element). But I know that my view is rather limited and you will have had your reasons to do this switch.

Anyway, if you agree we can close the issue as I can very well use v2 by separating the long running verification tasks from the synchronous ones. Thank you very much for your support!

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@tomber71 This is was something that I anticipated earlier and wanted to check if developers still needed this feature. Definitely not your fault and you have a valid use case 😉

Also, you are right about multiple level ordering, that's kind of redundant and makes the API clunky. The move to @Order annotation doesn't seem to serve it's purpose. I was keen to get feedback about the current API and it's a good thing that we haven't gone mainstream with the release builds yet.

The logical thing to do would be to use the order attribute, just as we did it with Saripaar v1 and to order fields using those values instead. I don't know if this is still the right way to go. There are a few more ways of doing this. Will work them out and share some of the alternative API designs on this thread. Will leave this issue open till it's addressed. Thank you for your contribution.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@tomber71 Quick thought, what if I write a companion plugin for Android Studio. Would that make life easier with multiple ordering? (I'll come up with a few reasons in another comment)

from android-saripaar.

 avatar commented on August 14, 2024

Not sure, but I think I need to read and understand your above mentioned reasons first. I still see an issue that the @Order annotation is obsolete with a sequence attribute on rule level. This will remain with whatever solution you want to tackle it. And personally I find annotations quite handy. But as I said I need to understand more what kind of idea you have in mind and I am looking forward to getting more information.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@tomber71 here are my reasons.

1. Google's way of doing things
I consider them as best practices. Google applications validate all the fields at the same time and display errors in one go. I've seen this on credit card forms in Google Play Applications and a few apps that ask for email and password.

That is why Saripaar v2 has Mode.BURST as default. This mode validates all fields at the same time.

2. Use Case I - Simple forms

// Example 2.1
@Email
private EditText mEmailEditText;

@Password
private EditText mPassword;

@ConfirmPassword
private EditText mConfirmPassword;

In this case, combining 1, the user could get started with no additional configurations.

3. Use Case II - Sequencing

// Example 3.1
@NotEmpty(sequence = 1)
@Email(sequence = 2)
private EditText mEmailEditText;

@Password
private EditText mPassword;

@ConfirmPassword
private EditText mConfirmPassword;

When a developer is using more than one annotation on a field, he needs to specify the sequence in which the rules should be validated. This is similar to the order attribute in Saripaar v2. But even better, considering the following:

  • Unlike the order attribute in v1, the sequence attribute is optional and is local to the given field.
  • Is required only when there is more than one annotation (considering the fact that you care about the sequence in which the rules are validated, optional otherwise).
  • Keeping the sequence number local to the field has the advantage of not having to keep track of the previous order value. Every time you start adding a sequence to a field, you start with 1 instead.
  • Reordering, in v1, if you want include a new annotation or reorder existing annotations, all the order attributes should be re-ordered. Changing one order value affects the value of all annotations that follow the modified order number.
  • Adding a QuickRule could make the matters worse if we use the methodology used in v1, because you have to jump between order numbers as shown in the following example (if we used the same technique as in v1).
// Example 3.2
@Required(order = 1)
@Email(order = 2)
// We add a QuickRule for a specific domain name with order 3
private EditText mEmailEditText;

@Password(order = 4) // We skipped 3, because of the QuickRule
private EditText mPassword;

@ConfirmPassword(order = 5)
private EditText mConfirmPassword;

Example 3.1 is elegant, more concise, amicable to refactoring and re-ordering than Example 3.2 considering Google's methodology discussed in 1.

4. Use Case III - Ordering
If we take the other way and want to validate fields one by one, then in order to find the order of the declared fields we have to use the @Order annotation. So, our example would look something like this while using Mode.IMMEDIATE / Validator.validateTill(View) / Validator.validateBefore(View).

// Example 4.1
@NotEmpty(sequence = 1)
@Email(sequence = 2)
@Order(1)
private EditText mEmailEditText;

@Password
@Order(2)
private EditText mPassword;

@ConfirmPassword
@Order(3)
private EditText mConfirmPassword;

This (i.e. @Order annotation) indeed makes the API clunky, but handles the situation. The ideology behind this API design decision is this:

  1. For developers who are willing to adopt the best practices, and want less - there's less work to do.
  2. For developers who are looking for more features, there's a bit more work.

Finally, I want to make sure that the API looks clean and involves lesser refactoring when changes are expected. And I think taking this longer stride with the @Order annotation and sequence attribute seem to accomplish that.

Let me know your thoughts 😉

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@tomber71 Any thoughts? If you agree, we could close this issue. Thanks.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@tomber71 I'm closing this for the moment. Do let me know if you have a different opinion before we freeze the APIs.

from android-saripaar.

 avatar commented on August 14, 2024

I am very sorry for my late reply. I have been very busy lately and I
simply didn't find the time.

I like your approach very much. I do agree that it is best to validate
all fields at once and show all the possible errors to the user. And
with the additional sequence attribute and the order annotation you
still can add all the flexiblity.

IMHO it is a very clean and consistent API!

Thanks a lot for this exchange and please apologize once again my later
reply!

Best regards,
Thomas

Am 26.01.2015 um 09:40 schrieb Ragunath Jawahar:

@tomber71 https://github.com/tomber71 here are my reasons.

1. Google's way of doing things
I consider them as best practices. Google applications validate all
the fields at the same time and display errors in one go. I've seen
this on credit card forms in Google Play Applications and a few apps
that ask for email and password.

That is why Saripaar v2 has |Mode.BURST| as default. This mode
validates all fields at the same time.

2. Use Case I - Simple forms

// Example 2.1
@Email
private EditText mEmailEditText;

@password
private EditText mPassword;

@ConfirmPassword
private EditText mConfirmPassword;

In this case, combining 1, the user could get started with no
additional configurations.

3. Use Case II - Sequencing

// Example 3.1
@notempty(sequence= 1)
@Email(sequence= 2)
private EditText mEmailEditText;

@password
private EditText mPassword;

@ConfirmPassword
private EditText mConfirmPassword;

When a developer is using more than one annotation on a field, he
needs to specify the |sequence| in which the rules should be
validated. This is similar to the |order| attribute in Saripaar v2.
But even better, considering the following:

  • Unlike the |order| attribute in v1, the |sequence| attribute is
    optional and is local to the given field.
  • Is required only when there is more than one annotation
    (considering the fact that you care about the sequence in which
    the rules are validated, optional otherwise).
  • Keeping the sequence number local to the field has the advantage
    of not having to keep track of the previous |order| value. Every
    time you start adding a sequence to a field, you start with |1|
    instead.
  • Reordering, in v1, if you want include a new annotation or reorder
    existing annotations, all the |order| attributes should be
    re-ordered. Changing one |order| value affects the value of all
    annotations that follow the modified |order| number.
  • Adding a |QuickRule| could make the matters worse if we use the
    methodology used in v1, because you have to jump between order
    numbers as shown in the following example (if we used the same
    technique as in v1).

// Example 3.2
@required(order= 1)
@Email(order= 2)
// We add a QuickRule for a specific domain name with order 3
private EditText mEmailEditText;

@password(order= 4)// We skipped 3, because of the QuickRule
private EditText mPassword;

@ConfirmPassword(order= 5)
private EditText mConfirmPassword;

|Example 3.1| is elegant, more concise, amicable to refactoring and
re-ordering than |Example 3.2| considering Google's methodology
discussed in 1.

4. Use Case III - Ordering
If we take the other way and want to validate fields one by one, then
in order to find the order of the declared fields we have to use the
|@order| annotation. So, our example would look something like this
while using |Mode.IMMEDIATE| / |Validator.validateTill(View)| /
|Validator.validateBefore(View)|.

// Example 4.1
@notempty(sequence= 1)
@Email(sequence= 2)
@order(1)
private EditText mEmailEditText;

@password
@order(2)
private EditText mPassword;

@ConfirmPassword
@order(3)
private EditText mConfirmPassword;

This (i.e. |@order| annotation) indeed makes the API clunky, but
handles the situation. The ideology behind this API design decision is
this:

  1. For developers who are willing to adopt the best practices, and
    want less - there's less work to do.
  2. For developers who are looking for more features, there's a bit
    more work.

Finally, I want to make sure that the API looks clean and involves
lesser refactoring when changes are expected. And I think taking this
longer stride with the |@order| annotation and |sequence| attribute
seem to accomplish that.

Let me know your thoughts 😉


Reply to this email directly or view it on GitHub
#57 (comment).

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@tomber71 No worries and thank you for your feedback on this.

from android-saripaar.

Lesilva avatar Lesilva commented on August 14, 2024

@ragunathjawahar I'm also trying to validate multiple rules for one view. I tried to use sequences to do that but I'm still getting back all errors for all rules. I was wondering if I did something wrong.

    @Override
    public void onValidationFailed(List<ValidationError> errors) {
        for (ValidationError error : errors) {
            TextView view = (TextView) error.getView();
            view.requestFocus();
            view.setError(error.getCollatedErrorMessage(getActivity()));
        }
    }

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@Lesilva Did you try switching to Mode.IMMEDIATE in your Validator?

from android-saripaar.

Lesilva avatar Lesilva commented on August 14, 2024

@ragunathjawahar I did not. I don't need validation orders for views, just for local rules in each view. Do I need Mode.IMMEDIATE to make sequences work as well?

Just tried Mode.IMMEDIATE, it still giving me all error messages for each rule. How can I just show error message by sequence. Something like, if sequence 1 rule failed, just show the error message for sequence 1 rule.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

If you need to validate rules one by one, you need the @Order annotation as well as the sequence attributes for all your rule annotations and QuickRules.

from android-saripaar.

Lesilva avatar Lesilva commented on August 14, 2024

@ragunathjawahar Thanks for your reply. Here's what I have:

    @NotEmpty(sequence = 1)
    @Size(sequence = 3, max = 30)
    @Pattern(sequence = 2, regex = "[a-zA-Z][a-zA-Z ]+")
    @Order(1)
    @InjectView(R.id.first_name)
    EditText firstName;

    @NotEmpty(sequence = 1)
    @Size(max = 1, sequence = 2)
    @Pattern(regex = "[a-zA-Z]", sequence = 3)
    @Order(2)
    @InjectView(R.id.middle_initial)
    EditText middleInitial;

    @NotEmpty(sequence = 1)
    @Size(max = 30, sequence = 2)
    @Pattern(regex = "[a-zA-Z][a-zA-Z ]+", sequence = 3)
    @Order(3)
    @InjectView(R.id.last_name)
    EditText lastName;

and validator.setValidationMode(Validator.Mode.IMMEDIATE)

When I'm trying to validate all empty fields, what I'm getting now is, the first two fields shows ALL error messages, the last one did not show anything.

According to my understanding, now it suppose to only show sequence 1 rule's error for the first field?

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

😕 could be a possible bug. I should investigate. Thanks for posting this.

from android-saripaar.

Lesilva avatar Lesilva commented on August 14, 2024

@ragunathjawahar Thanks! Let me know how it goes.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@Lesilva Will do :) I'll keep you posted on this.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@Lesilva please keep track of #73

from android-saripaar.

Lesilva avatar Lesilva commented on August 14, 2024

@ragunathjawahar Will do, thanks.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@Lesilva, I did take a look at your issue again. The sequence attribute is local to a given field. You can't validate all rules by sequence.

from android-saripaar.

Lesilva avatar Lesilva commented on August 14, 2024

@ragunathjawahar , I'm kinda confused now, I'm trying to validate rules in order for each view, so when ever a rule failed, it will only show error message for that rule and stop validating other rules. So it will only show one error message for each view. How do i do that? Thanks.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@Lesilva so consider this example,

@NotEmpty(sequence = 1)
@Size(sequence = 3, max = 30)
@Pattern(sequence = 2, regex = "[a-zA-Z][a-zA-Z ]+")
@Order(1)
@InjectView(R.id.first_name)
EditText firstName;

In the above example, if the @NotEmpty rule fails, then you want to show the respective error message. And again if the @Size rule fails (@NotEmpty passes), display the error message for @Size and so on. Is that what you are trying to do?

from android-saripaar.

Lesilva avatar Lesilva commented on August 14, 2024

@ragunathjawahar What I'm trying to do is, when @NotEmpty rule fails, display the error message, and stop validate this field(view) and go to next field(view).

from android-saripaar.

Lesilva avatar Lesilva commented on August 14, 2024

@ragunathjawahar Thanks for the tip. I'll try it that way.

from android-saripaar.

ragunathjawahar avatar ragunathjawahar commented on August 14, 2024

@Lesilva ok great.

from android-saripaar.

eternalBlast avatar eternalBlast commented on August 14, 2024

Hello @ragunathjawahar I tested with sequencing use case but the error messages displayed all errors on one field. I have tried like you said above. This is my code:

@Order(1)
@NotEmpty(sequence = 1, messageResId = R.string.must_filled)
@Length(sequence = 2, min = 4, messageResId = R.string.min_char)
@Bind(R.id.name)
protected EditText mFullnameText;

I have set validator.setValidationMode(Validation.IMMEDIATE)
I want when not empty is denied, it displays the error message i put on messageResId. When the user input the value the error gone. And if the user deny the Length rule, it display the Length error. I'm using saripaar 2.0.0 message. How do i achieve that?.Did i missing something?

from android-saripaar.

TuxApple avatar TuxApple commented on August 14, 2024

@eternalBlast

@NotEmpty(sequence = 1, messageResId = R.string.must_filled)
@Length(sequence = 2, min = 4, messageResId = R.string.min_char)
@Bind(R.id.name)
protected EditText mFullnameText;

and in method onValidationFailure using

@Override
public void onValidationFailed(List<ValidationError> errors) {
        for (ValidationError error : errors) {
            View view = error.getView();
            String[] listmessage = error.getCollatedErrorMessage(this).split("\n");
            String message = listmessage[0];

            // Display error messages ;)
            if (view instanceof EditText) {
                ((EditText) view).setError(message);
                view.requestFocus();
            } else {
                Dialogs.showAlertDialog(this, message);
            }
        }
    }

from android-saripaar.

nikitajain2 avatar nikitajain2 commented on August 14, 2024

in A Quick rule more time press button to check validation before resolv e the error it show error msg multipal time how to resolve it .
exp :- This field is required
This field is required
This field is required

from android-saripaar.

nikitajain2 avatar nikitajain2 commented on August 14, 2024

assign a quick rule to a view user click on view to resolve error but click on view error are not remove

from android-saripaar.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.