├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── exampleproject ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── AndroidManifest.xml ├── build.gradle ├── proguard-project.txt ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-ldpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── layout │ │ ├── example_allowempty.xml │ │ ├── example_alpha.xml │ │ ├── example_alpha_textinputlayout.xml │ │ ├── example_creditcard.xml │ │ ├── example_custom.xml │ │ ├── example_date.xml │ │ ├── example_date_custom.xml │ │ ├── example_domainname.xml │ │ ├── example_email.xml │ │ ├── example_email_or_creditcard.xml │ │ ├── example_floatnumericrange.xml │ │ ├── example_ipaddress.xml │ │ ├── example_nocheck.xml │ │ ├── example_numeric.xml │ │ ├── example_personfullname.xml │ │ ├── example_personname.xml │ │ ├── example_phone.xml │ │ ├── example_phone_custommessages.xml │ │ ├── example_regexp.xml │ │ ├── example_weburl.xml │ │ └── layout_examplegeneric.xml │ ├── menu │ │ └── menu.xml │ ├── values-v11 │ │ └── themes.xml │ ├── values │ │ ├── strings.xml │ │ └── themes.xml │ └── xml │ │ └── pref_contact.xml └── src │ └── com │ └── andreabaccega │ └── edittextformexample │ ├── CiaoValidator.java │ ├── EditTextFormExampleActivity.java │ ├── EmailOrCreditCard.java │ ├── LayoutExampleActivity.java │ ├── SettingsActivity.java │ └── utils │ ├── LayoutListItem.java │ ├── ListItem.java │ └── SimpleListItem.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── library ├── .classpath ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.jdt.ui.prefs ├── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── proguard-project.txt ├── project.properties ├── res │ ├── values-ar │ │ └── strings.xml │ ├── values-ca │ │ └── strings.xml │ ├── values-de │ │ └── strings.xml │ ├── values-es │ │ └── strings.xml │ ├── values-fr │ │ └── strings.xml │ ├── values-it │ │ └── strings.xml │ ├── values-ja │ │ └── strings.xml │ ├── values-ko │ │ └── strings.xml │ ├── values-pt-rBR │ │ └── strings.xml │ ├── values-ru │ │ └── strings.xml │ ├── values-tr │ │ └── strings.xml │ ├── values-zh-rCN │ │ └── strings.xml │ ├── values-zh-rTW │ │ └── strings.xml │ └── values │ │ ├── fet_attrs.xml │ │ └── strings.xml └── src │ └── com │ └── andreabaccega │ ├── formedittextvalidator │ ├── AlphaNumericValidator.java │ ├── AlphaValidator.java │ ├── AndValidator.java │ ├── CreditCardValidator.java │ ├── DateValidator.java │ ├── DigitLengthRangeValidator.java │ ├── DomainValidator.java │ ├── DummyValidator.java │ ├── EmailValidator.java │ ├── EmptyValidator.java │ ├── FloatNumericRangeValidator.java │ ├── IpAddressValidator.java │ ├── MultiValidator.java │ ├── NotValidator.java │ ├── NumericRangeValidator.java │ ├── NumericValidator.java │ ├── OrValidator.java │ ├── PatternValidator.java │ ├── PersonFullNameValidator.java │ ├── PersonNameValidator.java │ ├── PhoneValidator.java │ ├── RegexpValidator.java │ ├── SameValueValidator.java │ ├── Validator.java │ └── WebUrlValidator.java │ └── widget │ ├── DefaultEditTextValidator.java │ ├── EditTextValidator.java │ ├── FormAutoCompleteTextView.java │ ├── FormEditText.java │ └── ValidatingEditTextPreference.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | build/ 15 | 16 | # intellij iml files 17 | *.iml 18 | 19 | # gradle and idea files and cache 20 | .gradle 21 | .idea 22 | 23 | #random stuff that dropped in my project probably cause of android studio 24 | library/build.xml 25 | 26 | # Local configuration file (sdk path, etc) 27 | local.properties 28 | gradle/ 29 | gradlew 30 | gradlew.bat 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2012 Andrea Baccega 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Form EditText 2 | [![Release](https://jitpack.io/v/com.andreabaccega/android-edittext-validator.svg)](https://jitpack.io/#com.andreabaccega/android-edittext-validator) 3 | 4 | 5 | Android form edit text is an extension of EditText that brings data validation facilities to the edittext. 6 | 7 | # Example App 8 | I built an example app that showcase some of the possibilities of the library. 9 | 10 | You'll be able to find the app in the [Play Store](https://play.google.com/store/apps/details?id=com.andreabaccega.edittextformexample) 11 | Here some screenshot of the Example app ( and the library ) 12 | 13 | ![Examples list](http://lh6.ggpht.com/mYceoyXym2U4-6tRJWsudY4-6-V1TyFlqDfzL9P2R4Z059WZQLTZ3C9Gqcwr-hRrDQ) - ![Email validation](http://lh6.ggpht.com/yTzsI6-9VTtJVH331EA6gKc4GRBMv_DXxjAqPPlV9Yj5g-VGzcWtJ77T_m2JcbmbOoQ) 14 | 15 | The app source code is located under this repo! 16 | 17 | # How to include it 18 | 19 | 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 20 | #### Gradle: 21 | ```groovy 22 | allprojects { 23 | repositories { 24 | ... 25 | maven { url "https://jitpack.io" } 26 | } 27 | } 28 | dependencies { 29 | // ... 30 | compile 'com.andreabaccega:android-edittext-validator:1.3.5' 31 | // ... 32 | } 33 | ``` 34 | #### Maven 35 | ```xml 36 | 37 | 38 | jitpack.io 39 | https://jitpack.io 40 | 41 | 42 | 43 | com.andreabaccega 44 | android-edittext-validator 45 | ${...} 46 | aar 47 | provided 48 | 49 | ``` 50 | 51 | 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. 52 | 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: 53 | 54 | ```groovy 55 | dependencies { 56 | // .. 57 | implementation 'com.andreabaccega:android-form-edittext:1.3.5' 58 | // .. 59 | } 60 | ``` 61 | 62 | # How to use 63 | 64 | 65 | In your xml import an extra namespace on the root of your layout 66 | 67 | ```xml 68 | 69 | 74 | .... 75 | 76 | .... 77 | 78 | ``` 79 | 80 | **Note:** It's not mandatory to use it on the root element. Also remember to change the xmlns value with your package name 81 | 82 | Whenever you need to use the FormEditText just do the following in your xml. 83 | 84 | ```xml 85 | 86 | 91 | 92 | 93 | 94 | 100 | 101 | 102 | 103 | 104 | ``` 105 | 106 | As you noticed there is a *whatever:test* attribute setted to *alpha*. This let the FormEditText know that the data inside it should be only Alpha characters. 107 | 108 | There are several values you can set to the test attribute: 109 | - **regexp**: for custom regexp 110 | - **numeric**: for an only numeric field 111 | - **alpha**: for an alpha only field 112 | - **alphaNumeric**: guess what? 113 | - **email**: checks that the field is a valid email 114 | - **creditCard**: checks that the field contains a valid credit card using [Luhn Algorithm](http://en.wikipedia.org/wiki/Luhn_algorithm) 115 | - **phone**: checks that the field contains a valid phone number 116 | - **domainName**: checks that field contains a valid domain name 117 | - **ipAddress**: checks that the field contains a valid ip address 118 | - **webUrl**: checks that the field contains a valid url 119 | - **personName**: checks if the entered text is a person first or last name. 120 | - **personFullName**: checks if the entered value is a complete full name. 121 | - **date**: checks that the field is a valid date/datetime format ( if customFormat is set, checks with customFormat ) 122 | - **numericRange**: checks that the field is a valid value between integers. (minNumber and maxNumber must be set) 123 | - **floatNumericRange**: checks that the field is a valid value between integers (but decimal values are allowed). (minNumber and maxNumber must be set) 124 | - **nocheck**: It does not check anything except the emptyness of the field. 125 | 126 | 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 127 | 128 | You can customize them using the attributes 129 | - **testErrorString** used when the field does not pass the test 130 | - **emptyErrorString** used when the field is empty 131 | 132 | ### Example: 133 | 134 | ```xml 135 | 136 | 141 | 142 | 143 | 144 | 152 | 153 | 154 | 155 | 156 | ``` 157 | 158 | 159 | Furthermore you can ask the FormEditText to allow the content to be *optional*. 160 | Just use the **emptyAllowed** attribute and set it to *true*. **Note:** If you don't specify the **emptyAllowed** attribute the default value is *false*. 161 | 162 | If you want to use **regexp** as **test** attribute value you'll need to also use the **customRegexp** attribute. Take a look in the following example: 163 | 164 | ### Example: (Email check) 165 | 166 | ```xml 167 | 168 | 172 | 173 | 174 | 175 | 185 | 186 | 187 | 188 | 189 | ``` 190 | **Note:** The library supports the email check natively using the **email** value as the **test** attribute. 191 | ```xml 192 | 193 | 198 | 199 | 200 | 201 | 209 | 210 | 211 | 212 | 213 | ``` 214 | 215 | In your Java code you'll need to call a method when you want to know if the field validates. 216 | 217 | ```java 218 | public void onClickNext(View v) { 219 | FormEditText[] allFields = { etFirstname, etLastname, etAddress, etZipcode, etCity }; 220 | 221 | 222 | boolean allValid = true; 223 | for (FormEditText field: allFields) { 224 | allValid = field.testValidity() && allValid; 225 | } 226 | 227 | if (allValid) { 228 | // YAY 229 | } else { 230 | // EditText are going to appear with an exclamation mark and an explicative message. 231 | } 232 | } 233 | ``` 234 | 235 | Calling *testValidity()* will cause the EditText to cycle through all the validators and call the isValid method. it will stop when one of them returns false or there are no validators left. 236 | 237 | Furthermore *testValidity()* will also place an exclamation mark on the right of the [EditText](http://developer.android.com/reference/android/widget/EditText.html) and will call the [setError](http://developer.android.com/reference/android/widget/TextView.html#setError) method. 238 | 239 | 240 | 241 | ## Add your custom validators 242 | You can add your custom validators runtime through the *addValidator* method. For example, let's suppouse we want to add a validator that checks that the text input is equal to the string "ciao": 243 | ```java 244 | public class CiaoValidator extends Validator { 245 | 246 | public CiaoValidator() { 247 | super("You should enter 'ciao' here"); 248 | } 249 | 250 | public boolean isValid(EditText et) { 251 | return TextUtils.equals(et.getText(), "ciao"); 252 | } 253 | 254 | } 255 | ``` 256 | 257 | As you can see in the constructor you'll be required to set an Error Message that will be handled ( in this simple scenario ) by the super class. That piece of code will set the error message to: *You should enter 'ciao' here*. 258 | 259 | This means that if the user will not enter "ciao" in the edit text it will get that error message in the popup. 260 | 261 | ## Binary operators 262 | You can use the following binary operators in order to perform checks on the field value: 263 | - **AND**: will return true if every enqueued validator returns true 264 | - **OR**: will return true if just one enqueued validator returns true 265 | - **NOT**: will return the inverse of the passed Validator 266 | 267 | With these binary operator validators you'll be able to perform as many different checks as you want. For example, lets say you want a field to be valid either if the user enters his email address or his credit card. Use 'nocheck' in the xml and programmatically do something like this: 268 | 269 | ```java 270 | protected void onCreate(Bundle savedInstanceState) { 271 | // Blabla 272 | 273 | FormEditText fdt = (FormEditText) findViewById(R.id.et); 274 | fdt.addValidator( 275 | new OrValidator( 276 | "This is neither a creditcard or an email", 277 | new CreditCardValidator(null), // we specify null as the message string cause the Or validator will use his own message 278 | new EmailValidator(null) // same here for null 279 | ) 280 | ); 281 | } 282 | ``` 283 | 284 | 285 | # Author 286 | 287 | * Andrea Baccega - _Author/Ideator of the library_ 288 | 289 | # Contributors 290 | 291 | * [ffrog8](https://github.com/ffrog8) - _Added the ability to use the library inside the preferences_ 292 | * [indication](https://github.com/indication) - _Added japanese translations_ 293 | * [renclav](https://github.com/renclav) - _Fixed weird bug affecting some 4.2+ devices that prevented the error icon to be shown_ 294 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | google() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.1.3' 9 | 10 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 11 | 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | google() 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /exampleproject/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /exampleproject/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | EditTextFormExample 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /exampleproject/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 3 | org.eclipse.jdt.core.compiler.compliance=1.5 4 | org.eclipse.jdt.core.compiler.source=1.5 5 | -------------------------------------------------------------------------------- /exampleproject/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /exampleproject/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | buildToolsVersion "27.0.3" 6 | defaultConfig { 7 | minSdkVersion 14 8 | targetSdkVersion 27 9 | } 10 | sourceSets.main { 11 | manifest.srcFile 'AndroidManifest.xml' 12 | java.srcDirs = ['src'] 13 | resources.srcDirs = ['src'] 14 | aidl.srcDirs = ['src'] 15 | renderscript.srcDirs = ['src'] 16 | res.srcDirs = ['res'] 17 | assets.srcDirs = ['assets'] 18 | } 19 | dependencies { 20 | compile project(':library') 21 | } 22 | 23 | } 24 | 25 | dependencies { 26 | compile 'com.android.support:appcompat-v7:27.1.1' 27 | } 28 | -------------------------------------------------------------------------------- /exampleproject/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /exampleproject/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vekexasia/android-edittext-validator/4a100e3d708b232133f4dd8ceb37ad7447fc7a1b/exampleproject/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /exampleproject/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vekexasia/android-edittext-validator/4a100e3d708b232133f4dd8ceb37ad7447fc7a1b/exampleproject/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /exampleproject/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vekexasia/android-edittext-validator/4a100e3d708b232133f4dd8ceb37ad7447fc7a1b/exampleproject/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /exampleproject/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vekexasia/android-edittext-validator/4a100e3d708b232133f4dd8ceb37ad7447fc7a1b/exampleproject/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /exampleproject/res/layout/example_allowempty.xml: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_alpha.xml: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_alpha_textinputlayout.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_creditcard.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_custom.xml: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_date.xml: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_date_custom.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_domainname.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_email.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_email_or_creditcard.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_floatnumericrange.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_ipaddress.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_nocheck.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_numeric.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_personfullname.xml: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_personname.xml: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_phone.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_phone_custommessages.xml: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_regexp.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /exampleproject/res/layout/example_weburl.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /exampleproject/res/layout/layout_examplegeneric.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 17 | 18 | 23 | 24 |