Skip to content

Commit

Permalink
Added FloatNumericRangeValidator, refactored some code
Browse files Browse the repository at this point in the history
  • Loading branch information
vekexasia committed Sep 15, 2016
1 parent 46f5ecc commit 7a8f577
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 153 deletions.
30 changes: 21 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ The app source code is located under this repo!
This library can be found in maven central repo. If you're using Android studio you can include it by writing the following in the corresponding _dependencies_ block
#### Gradle:
```groovy
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
dependencies {
// ...
compile 'com.andreabaccega:android-form-edittext:1.2.1@aar'
Expand All @@ -25,6 +31,12 @@ dependencies {
```
####Maven
```xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.andreabaccega</groupId>
<artifactId>android-form-edittext</artifactId>
Expand All @@ -34,15 +46,13 @@ dependencies {
</dependency>
```

Since 1.2.+ the library comes with a new optional dependency: [com.android.support.design](http://android-developers.blogspot.it/2015/05/android-design-support-library.html). This will enable the new [TextInputLayout](http://developer.android.com/reference/android/support/design/widget/TextInputLayout.html) features to be used with the validation engine.
Version 1.2.+ depends on com.android.support.design:2.2.0 but if you're not using the support design library you can safely exclude it while including this with gradle by doing so:
Since 1.3.+ the library comes with a new optional dependency: [com.android.support.design](http://android-developers.blogspot.it/2015/05/android-design-support-library.html). This will enable the new [TextInputLayout](http://developer.android.com/reference/android/support/design/widget/TextInputLayout.html) features to be used with the validation engine.
Version 1.3.+ depends on com.android.support.design:2.2.0 but if you're not using the support design library you can safely exclude it while including this with gradle by doing so:

```groovy
dependencies {
// ..
compile ('com.andreabaccega:android-form-edittext:1.2.1@aar'){
exclude module: 'design'
}
compile ('com.andreabaccega:android-form-edittext:1.3.+')
// ..
}
```
Expand Down Expand Up @@ -96,15 +106,17 @@ There are several values you can set to the test attribute:
- **numeric**: for an only numeric field
- **alpha**: for an alpha only field
- **alphaNumeric**: guess what?
- **personName**: checks if the entered text is a person first or last name.
- **personFullName**: checks if the entered value is a complete full name.
- **email**: checks that the field is a valid email
- **creditCard**: checks that the field contains a valid credit card using [Luhn Algorithm](http://en.wikipedia.org/wiki/Luhn_algorithm)
- **phone**: checks that the field contains a valid phone number
- **domainName**: checks that field contains a valid domain name ( always passes the test in API Level < 8 )
- **domainName**: checks that field contains a valid domain name
- **ipAddress**: checks that the field contains a valid ip address
- **webUrl**: checks that the field contains a valid url ( always passes the test in API Level < 8 )
- **webUrl**: checks that the field contains a valid url
- **personName**: checks if the entered text is a person first or last name.
- **personFullName**: checks if the entered value is a complete full name.
- **date**: checks that the field is a valid date/datetime format ( if customFormat is set, checks with customFormat )
- **numericRange**: checks that the field is a valid value between integers. (minNumber and maxNumber must be set)
- **floatNumericRange**: checks that the field is a valid value between integers (but decimal values are allowed). (minNumber and maxNumber must be set)
- **nocheck**: It does not check anything except the emptyness of the field.

For most of the test type values this library comes with a couple of default strings. This means that error strings ( english only ) are already available for the following test types: numeric, alpha, alphanumeric
Expand Down
33 changes: 0 additions & 33 deletions library/res/values-ar/fet_attrs.xml

This file was deleted.

1 change: 1 addition & 0 deletions library/res/values/fet_attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<enum name="personFullName" value="13" />
<enum name="date" value="14" />
<enum name="numericRange" value="15" />
<enum name="floatNumericRange" value="16" />
</attr>
<attr name="testErrorString" format="string" />
<attr name="emptyErrorString" format="string" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.andreabaccega.formedittextvalidator;

import android.widget.EditText;

/**
* A validator that returns true only if the input field contains only numbers
* and the number is within the given range.
*
* @author Said Tahsin Dane <tasomaniac@gmail.com>
*
*/
public class FloatNumericRangeValidator extends Validator{

private int min, max;

public FloatNumericRangeValidator(String _customErrorMessage, int min, int max) {
super(_customErrorMessage);
this.min = min;
this.max = max;
}

public boolean isValid(EditText et) {
try {
double value = Double.parseDouble(et.getText().toString());
return value >= min && value <= max;
} catch(NumberFormatException e) {
return false;
}
}
}
100 changes: 42 additions & 58 deletions library/src/com/andreabaccega/widget/DefaultEditTextValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,14 @@
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;

import com.andreabaccega.formedittext.R;
import com.andreabaccega.formedittextvalidator.AlphaNumericValidator;
import com.andreabaccega.formedittextvalidator.AlphaValidator;
import com.andreabaccega.formedittextvalidator.AndValidator;
import com.andreabaccega.formedittextvalidator.CreditCardValidator;
import com.andreabaccega.formedittextvalidator.DateValidator;
import com.andreabaccega.formedittextvalidator.DomainValidator;
import com.andreabaccega.formedittextvalidator.DummyValidator;
import com.andreabaccega.formedittextvalidator.EmailValidator;
import com.andreabaccega.formedittextvalidator.EmptyValidator;
import com.andreabaccega.formedittextvalidator.IpAddressValidator;
import com.andreabaccega.formedittextvalidator.MultiValidator;
import com.andreabaccega.formedittextvalidator.NotValidator;
import com.andreabaccega.formedittextvalidator.NumericRangeValidator;
import com.andreabaccega.formedittextvalidator.NumericValidator;
import com.andreabaccega.formedittextvalidator.OrValidator;
import com.andreabaccega.formedittextvalidator.PersonFullNameValidator;
import com.andreabaccega.formedittextvalidator.PersonNameValidator;
import com.andreabaccega.formedittextvalidator.PhoneValidator;
import com.andreabaccega.formedittextvalidator.RegexpValidator;
import com.andreabaccega.formedittextvalidator.Validator;
import com.andreabaccega.formedittextvalidator.WebUrlValidator;
import com.andreabaccega.formedittextvalidator.*;

/**
* Default implementation of an {@link EditTextValidator}
*/
public class DefaultEditTextValidator
implements EditTextValidator {
implements EditTextValidator {
/**
* The custom validators setted using
*/
Expand Down Expand Up @@ -76,7 +55,7 @@ public DefaultEditTextValidator(EditText editText, AttributeSet attrs, Context c
customRegexp = typedArray.getString(R.styleable.FormEditText_customRegexp);
emptyErrorString = typedArray.getString(R.styleable.FormEditText_emptyErrorString);
customFormat = typedArray.getString(R.styleable.FormEditText_customFormat);
if ( testType == TEST_NUMERIC_RANGE ) {
if (testType == TEST_NUMERIC_RANGE || testType == TEST_FLOAT_NUMERIC_RANGE) {
minNumber = typedArray.getInt(R.styleable.FormEditText_minNumber, Integer.MIN_VALUE);
maxNumber = typedArray.getInt(R.styleable.FormEditText_maxNumber, Integer.MAX_VALUE);
}
Expand All @@ -89,8 +68,8 @@ public DefaultEditTextValidator(EditText editText, AttributeSet attrs, Context c

@Override
public void addValidator(Validator theValidator)
throws IllegalArgumentException {
if ( theValidator == null ) {
throws IllegalArgumentException {
if (theValidator == null) {
throw new IllegalArgumentException("theValidator argument should not be null");
}
mValidator.enqueue(theValidator);
Expand All @@ -109,7 +88,7 @@ public EditText getEditText() {
}

public void setEditText(EditText editText) {
if ( this.editText != null ) {
if (this.editText != null) {
this.editText.removeTextChangedListener(getTextWatcher());
}
this.editText = editText;
Expand All @@ -126,7 +105,7 @@ public int getTestType() {

@Override
public TextWatcher getTextWatcher() {
if ( tw == null ) {
if (tw == null) {
tw = new TextWatcher() {

public void afterTextChanged(Editable s) {
Expand All @@ -137,7 +116,7 @@ public void beforeTextChanged(CharSequence s, int start, int count, int after) {

public void onTextChanged(CharSequence s, int start, int before, int count) {

if ( !TextUtils.isEmpty(s) && isErrorShown()) {
if (!TextUtils.isEmpty(s) && isErrorShown()) {
try {
TextInputLayout textInputLayout = (TextInputLayout) editText.getParent();
textInputLayout.setErrorEnabled(false);
Expand Down Expand Up @@ -173,81 +152,86 @@ public void resetValidators(Context context) {

case TEST_ALPHA:
toAdd =
new AlphaValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_only_standard_letters_are_allowed)
: testErrorString);
new AlphaValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_only_standard_letters_are_allowed)
: testErrorString);
break;
case TEST_ALPHANUMERIC:
toAdd =
new AlphaNumericValidator(
TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_this_field_cannot_contain_special_character)
: testErrorString);
new AlphaNumericValidator(
TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_this_field_cannot_contain_special_character)
: testErrorString);
break;

case TEST_NUMERIC:
toAdd =
new NumericValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_only_numeric_digits_allowed)
: testErrorString);
new NumericValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_only_numeric_digits_allowed)
: testErrorString);
break;
case TEST_NUMERIC_RANGE:
toAdd =
new NumericRangeValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_only_numeric_digits_range_allowed, minNumber, maxNumber)
: testErrorString, minNumber, maxNumber);
new NumericRangeValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_only_numeric_digits_range_allowed, minNumber, maxNumber)
: testErrorString, minNumber, maxNumber);
break;
case TEST_FLOAT_NUMERIC_RANGE:
toAdd =
new FloatNumericRangeValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_only_numeric_digits_range_allowed, minNumber, maxNumber)
: testErrorString, minNumber, maxNumber);
break;
case TEST_REGEXP:

toAdd = new RegexpValidator(testErrorString, customRegexp);
break;
case TEST_CREDITCARD:
toAdd =
new CreditCardValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_creditcard_number_not_valid)
: testErrorString);
new CreditCardValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_creditcard_number_not_valid)
: testErrorString);
break;
case TEST_EMAIL:
toAdd =
new EmailValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_email_address_not_valid)
: testErrorString);
new EmailValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_email_address_not_valid)
: testErrorString);
break;
case TEST_PHONE:
toAdd =
new PhoneValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_phone_not_valid) : testErrorString);
new PhoneValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_phone_not_valid) : testErrorString);
break;
case TEST_DOMAINNAME:
toAdd =
new DomainValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_domain_not_valid)
: testErrorString);
new DomainValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_domain_not_valid)
: testErrorString);
break;
case TEST_IPADDRESS:
toAdd =
new IpAddressValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_ip_not_valid) : testErrorString);
new IpAddressValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_ip_not_valid) : testErrorString);
break;
case TEST_WEBURL:
toAdd =
new WebUrlValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_url_not_valid) : testErrorString);
new WebUrlValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_url_not_valid) : testErrorString);
break;
case TEST_PERSONNAME:
toAdd =
new PersonNameValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_notvalid_personname) : testErrorString);
new PersonNameValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_notvalid_personname) : testErrorString);
break;
case TEST_PERSONFULLNAME:
toAdd =
new PersonFullNameValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_notvalid_personfullname) : testErrorString);
new PersonFullNameValidator(TextUtils.isEmpty(testErrorString) ? context.getString(R.string.error_notvalid_personfullname) : testErrorString);
break;

case TEST_CUSTOM:
// must specify the fully qualified class name & an error message

if ( classType == null ) {
if (classType == null) {
throw new RuntimeException("Trying to create a custom validator but no classType has been specified.");
}
if ( TextUtils.isEmpty(testErrorString) ) {
if (TextUtils.isEmpty(testErrorString)) {
throw new RuntimeException(String.format("Trying to create a custom validator (%s) but no error string specified.", classType));
}

Class<? extends Validator> customValidatorClass;
try {
Class<?> loadedClass = this.getClass().getClassLoader().loadClass(classType);

if ( ! Validator.class.isAssignableFrom(loadedClass) ) {
if (!Validator.class.isAssignableFrom(loadedClass)) {
throw new RuntimeException(String.format("Custom validator (%s) does not extend %s", classType, Validator.class.getName()));
}
customValidatorClass = (Class<? extends Validator>) loadedClass;
Expand All @@ -259,7 +243,7 @@ public void resetValidators(Context context) {
toAdd = customValidatorClass.getConstructor(String.class).newInstance(testErrorString);
} catch (Exception e) {
throw new RuntimeException(String.format("Unable to construct custom validator (%s) with argument: %s", classType,
testErrorString));
testErrorString));
}

break;
Expand All @@ -270,7 +254,7 @@ public void resetValidators(Context context) {
}

MultiValidator tmpValidator;
if ( ! emptyAllowed ) { // If the xml tells us that this is a required field, we will add the EmptyValidator.
if (!emptyAllowed) { // If the xml tells us that this is a required field, we will add the EmptyValidator.
tmpValidator = new AndValidator();
tmpValidator.enqueue(new EmptyValidator(emptyErrorStringActual));
tmpValidator.enqueue(toAdd);
Expand Down Expand Up @@ -300,7 +284,7 @@ public void setEmptyAllowed(boolean emptyAllowed, Context context) {
}

public void setEmptyErrorString(String emptyErrorString) {
if ( ! TextUtils.isEmpty(emptyErrorString) ) {
if (!TextUtils.isEmpty(emptyErrorString)) {
emptyErrorStringActual = emptyErrorString;
} else {
emptyErrorStringActual = defaultEmptyErrorString;
Expand All @@ -325,15 +309,15 @@ public boolean testValidity() {
@Override
public boolean testValidity(boolean showUIError) {
boolean isValid = mValidator.isValid(editText);
if ( ! isValid && showUIError ) {
if (!isValid && showUIError) {
showUIError();
}
return isValid;
}

@Override
public void showUIError() {
if ( mValidator.hasErrorMessage() ) {
if (mValidator.hasErrorMessage()) {
try {
TextInputLayout parent = (TextInputLayout) editText.getParent();
parent.setErrorEnabled(true);
Expand All @@ -349,7 +333,7 @@ public boolean isErrorShown() {
TextInputLayout parent = (TextInputLayout) editText.getParent();
return true; // might sound like a bug. but there's no way to know if the error is shown (not with public api)
} catch (Throwable e) {
return ! TextUtils.isEmpty(editText.getError());
return !TextUtils.isEmpty(editText.getError());
}
}

Expand Down

0 comments on commit 7a8f577

Please sign in to comment.